18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * its contributors may be used to endorse or promote products derived 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * from this software without specific prior written permission. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "BytecodeGenerator.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "BatchedTransitionOptimizer.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSFunction.h" 35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Interpreter.h" 3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "ScopeChain.h" 37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "UString.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project The layout of a register frame looks like this: 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project For 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function f(x, y) { 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project var v1; 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function g() { } 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project var v2; 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (x) * (y); 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project assuming (x) and (y) generated temporaries t1 and t2, you would have 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ------------------------------------ 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | x | y | g | v2 | v1 | t1 | t2 | <-- value held 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ------------------------------------ 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ------------------------------------ 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | params->|<-locals | temps-> 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Because temporary registers are allocated in a stack-like fashion, we 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project can reclaim them with a simple popping algorithm. The same goes for labels. 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (We never reclaim parameter or local registers, because parameters and 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project locals are DontDelete.) 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project The register layout before a function call looks like this: 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project For 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function f(x, y) 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project f(1); 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project > <------------------------------ 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project < > reserved: call frame | 1 | <-- value held 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project > >snip< <------------------------------ 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project < > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project > <------------------------------ 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | params->|<-locals | temps-> 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project The call instruction fills in the "call frame" registers. It also pads 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project missing arguments at the end of the call: 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project > <----------------------------------- 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project < > reserved: call frame | 1 | ? | <-- value held ("?" stands for "undefined") 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project > >snip< <----------------------------------- 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project < > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project > <----------------------------------- 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | params->|<-locals | temps-> 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project After filling in missing arguments, the call instruction sets up the new 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stack frame to overlap the end of the old stack frame: 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project |----------------------------------> < 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | reserved: call frame | 1 | ? < > <-- value held ("?" stands for "undefined") 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project |----------------------------------> >snip< < 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | -7 | -6 | -5 | -4 | -3 | -2 | -1 < > <-- register index 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project |----------------------------------> < 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project | | params->|<-locals | temps-> 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project That way, arguments are "copied" into the callee's stack frame for free. 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project If the caller supplies too many arguments, this trick doesn't work. The 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project extra arguments protrude into space reserved for locals and temporaries. 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project In that case, the call instruction makes a real copy of the call frame header, 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project along with just the arguments expected by the callee, leaving the original 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project call frame header and arguments behind. (The call instruction can't just discard 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project extra arguments, because the "arguments" object may access them later.) 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This copying strategy ensures that all named values will be at the indices 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project expected by the callee. 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/ 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool s_dumpsGeneratedCode = false; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode) 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project s_dumpsGeneratedCode = dumpsGeneratedCode; 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UNUSED_PARAM(dumpsGeneratedCode); 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::dumpsGeneratedCode() 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return s_dumpsGeneratedCode; 135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return false; 137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochJSObject* BytecodeGenerator::generate() 141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->setThisRegister(m_thisRegister.index()); 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_scopeNode->emitBytecode(*this); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG 147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->setInstructionCount(m_codeBlock->instructions().size()); 148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (s_dumpsGeneratedCode) 15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_codeBlock->dump(m_scopeChain->globalObject->globalExec()); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode) 154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project symbolTable().clear(); 155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->shrinkToFit(); 15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (m_expressionTooDeep) 15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return createOutOfMemoryError(m_scopeChain->globalObject.get()); 16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return 0; 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0) 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int index = m_calleeRegisters.size(); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0); 167f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry); 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result.second) { 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r0 = ®isterFor(result.first->second.getIndex()); 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 174e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block r0 = addVar(); 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0) 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int index = m_nextGlobalIndex; 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0); 182f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result.second) 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project index = result.first->second.getIndex(); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project --m_nextGlobalIndex; 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_globals.append(index + m_globalVarStorageOffset); 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r0 = ®isterFor(index); 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result.second; 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid BytecodeGenerator::preserveLastVar() 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0) 1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_lastVar = &m_calleeRegisters.last(); 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochBytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock) 20281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger()) 20381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling()) 20481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo()) 20581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_scopeChain(*scopeChain->globalData, scopeChain) 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_symbolTable(symbolTable) 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_scopeNode(programNode) 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_codeBlock(codeBlock) 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_thisRegister(RegisterFile::ProgramCodeThisRegister) 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_finallyDepth(0) 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_dynamicScopeDepth(0) 212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_baseScopeDepth(0) 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_codeType(GlobalCode) 214635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_nextGlobalIndex(-1) 2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_nextConstantOffset(0) 2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_globalConstantIndex(0) 217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_hasCreatedActivation(true) 218bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_firstLazyFunction(0) 219bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_lastLazyFunction(0) 22081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_globalData(scopeChain->globalData) 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_lastOpcodeID(op_end) 222dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#ifndef NDEBUG 223dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_lastOpcodePosition(0) 224dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif 225f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_stack(m_globalData->stack()) 22606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen , m_usesExceptions(false) 22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_expressionTooDeep(false) 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_shouldEmitDebugHooks) 230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->setNeedsFullScopeChain(true); 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_enter); 233635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->setGlobalData(m_globalData); 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // FIXME: Move code that modifies the global object to Interpreter::execute. 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->m_numParameters = 1; // Allocate space for "this" 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch JSGlobalObject* globalObject = scopeChain->globalObject.get(); 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ExecState* exec = globalObject->globalExec(); 241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RegisterFile* registerFile = &exec->globalData().interpreter->registerFile(); 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Shift register indexes in generated code to elide registers allocated by intermediate stack frames. 244635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters - registerFile->size(); 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add previously defined symbols to bookkeeping. 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_globals.grow(symbolTable->size()); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SymbolTable::iterator end = symbolTable->end(); 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it) 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project registerFor(it->second.getIndex()).setIndex(it->second.getIndex() + m_globalVarStorageOffset); 2512bde8e466a4451c7319e3a072d118917957d6554Steve Block 2522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BatchedTransitionOptimizer optimizer(*m_globalData, globalObject); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 254635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const VarStack& varStack = programNode->varStack(); 255635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const FunctionStack& functionStack = programNode->functionStack(); 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool canOptimizeNewGlobals = symbolTable->size() + functionStack.size() + varStack.size() < registerFile->maxGlobals(); 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (canOptimizeNewGlobals) { 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Shift new symbols so they get stored prior to existing symbols. 259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_nextGlobalIndex -= symbolTable->size(); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2612bde8e466a4451c7319e3a072d118917957d6554Steve Block HashSet<StringImpl*, IdentifierRepHash> newGlobals; 2622bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<std::pair<int, bool>, 16> functionInfo(functionStack.size()); 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < functionStack.size(); ++i) { 264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionBodyNode* function = functionStack[i]; 2652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch globalObject->removeDirect(*m_globalData, function->ident()); // Make sure our new function is not shadowed by an old property. 2662bde8e466a4451c7319e3a072d118917957d6554Steve Block SymbolTableEntry entry = symbolTable->inlineGet(function->ident().impl()); 2672bde8e466a4451c7319e3a072d118917957d6554Steve Block 2682bde8e466a4451c7319e3a072d118917957d6554Steve Block if (entry.isNull()) 2692bde8e466a4451c7319e3a072d118917957d6554Steve Block newGlobals.add(function->ident().impl()); 2702bde8e466a4451c7319e3a072d118917957d6554Steve Block functionInfo[i] = make_pair(entry.getIndex(), entry.isReadOnly()); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2722bde8e466a4451c7319e3a072d118917957d6554Steve Block 2732bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<bool, 16> shouldCreateVar(varStack.size()); 27481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch for (size_t i = 0; i < varStack.size(); ++i) { 2752bde8e466a4451c7319e3a072d118917957d6554Steve Block if (newGlobals.contains(varStack[i].first->impl()) || globalObject->hasProperty(exec, *varStack[i].first)) { 2762bde8e466a4451c7319e3a072d118917957d6554Steve Block shouldCreateVar[i] = false; 27781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch continue; 2782bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2792bde8e466a4451c7319e3a072d118917957d6554Steve Block shouldCreateVar[i] = true; 2802bde8e466a4451c7319e3a072d118917957d6554Steve Block newGlobals.add(varStack[i].first->impl()); 28181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 28281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 2832bde8e466a4451c7319e3a072d118917957d6554Steve Block int expectedSize = symbolTable->size() + newGlobals.size(); 2842bde8e466a4451c7319e3a072d118917957d6554Steve Block globalObject->resizeRegisters(symbolTable->size(), expectedSize); 2852bde8e466a4451c7319e3a072d118917957d6554Steve Block 2862bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t i = 0; i < functionStack.size(); ++i) { 2872bde8e466a4451c7319e3a072d118917957d6554Steve Block FunctionBodyNode* function = functionStack[i]; 2882bde8e466a4451c7319e3a072d118917957d6554Steve Block if (functionInfo[i].second) 2892bde8e466a4451c7319e3a072d118917957d6554Steve Block continue; 2902bde8e466a4451c7319e3a072d118917957d6554Steve Block RegisterID* dst = addGlobalVar(function->ident(), false); 2912bde8e466a4451c7319e3a072d118917957d6554Steve Block JSValue value = new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain); 2922bde8e466a4451c7319e3a072d118917957d6554Steve Block globalObject->registerAt(dst->index() - m_globalVarStorageOffset).set(*m_globalData, globalObject, value); 2932bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2952bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t i = 0; i < varStack.size(); ++i) { 2962bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!shouldCreateVar[i]) 2972bde8e466a4451c7319e3a072d118917957d6554Steve Block continue; 2982bde8e466a4451c7319e3a072d118917957d6554Steve Block addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant); 2992bde8e466a4451c7319e3a072d118917957d6554Steve Block } 3002bde8e466a4451c7319e3a072d118917957d6554Steve Block if (symbolTable->size() != expectedSize) 3012bde8e466a4451c7319e3a072d118917957d6554Steve Block CRASH(); 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3032bde8e466a4451c7319e3a072d118917957d6554Steve Block preserveLastVar(); 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < functionStack.size(); ++i) { 306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionBodyNode* function = functionStack[i]; 30781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain), DontDelete); 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < varStack.size(); ++i) { 31081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (globalObject->symbolTableHasProperty(*varStack[i].first) || globalObject->hasProperty(exec, *varStack[i].first)) 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project continue; 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int attributes = DontDelete; 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (varStack[i].second & DeclarationStacks::IsConstant) 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project attributes |= ReadOnly; 315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block globalObject->putWithAttributes(exec, *varStack[i].first, jsUndefined(), attributes); 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch preserveLastVar(); 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 320bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen codeBlock->m_numCapturedVars = codeBlock->m_numVars; 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochBytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainNode* scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock) 32481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger()) 32581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling()) 32681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo()) 32781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_scopeChain(*scopeChain->globalData, scopeChain) 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_symbolTable(symbolTable) 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_scopeNode(functionBody) 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_codeBlock(codeBlock) 331e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block , m_activationRegister(0) 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_finallyDepth(0) 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_dynamicScopeDepth(0) 334635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_baseScopeDepth(0) 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_codeType(FunctionCode) 3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_nextConstantOffset(0) 3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_globalConstantIndex(0) 338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_hasCreatedActivation(false) 339bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_firstLazyFunction(0) 340bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_lastLazyFunction(0) 34181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_globalData(scopeChain->globalData) 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_lastOpcodeID(op_end) 343a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#ifndef NDEBUG 344a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_lastOpcodePosition(0) 345a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif 346f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_stack(m_globalData->stack()) 34706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen , m_usesExceptions(false) 34865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_expressionTooDeep(false) 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_shouldEmitDebugHooks) 351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->setNeedsFullScopeChain(true); 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->setGlobalData(m_globalData); 354a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 355a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_enter); 356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_codeBlock->needsFullScopeChain()) { 357e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block m_activationRegister = addVar(); 358a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitInitLazyRegister(m_activationRegister); 359a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_codeBlock->setActivationRegister(m_activationRegister->index()); 360a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 362e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments' 363e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // object, if created. 364e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (m_codeBlock->needsFullScopeChain() || functionBody->usesArguments()) { 365e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code. 366e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'. 367e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 368e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // We can save a little space by hard-coding the knowledge that the two 369e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // 'arguments' values are stored in consecutive registers, and storing 370e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // only the index of the assignable one. 371e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock->setArgumentsRegister(argumentsRegister->index()); 372e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister())); 373e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 374bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitInitLazyRegister(argumentsRegister); 375bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitInitLazyRegister(unmodifiedArgumentsRegister); 376a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 377a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (m_codeBlock->isStrictMode()) { 378a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_create_arguments); 379a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(argumentsRegister->index()); 380a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // The debugger currently retrieves the arguments object from an activation rather than pulling 3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // it from a call frame. In the long-term it should stop doing that (<rdar://problem/6911886>), 3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // but for now we force eager creation of the arguments object when debugging. 385e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (m_shouldEmitDebugHooks) { 3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_create_arguments); 387e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(argumentsRegister->index()); 388e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack(); 392bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen const DeclarationStacks::VarStack& varStack = functionBody->varStack(); 393bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 394bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Captured variables and functions go first so that activations don't have 395bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // to step over the non-captured locals to mark them. 396a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_hasCreatedActivation = false; 397bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (functionBody->hasCapturedVariables()) { 398bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen for (size_t i = 0; i < functionStack.size(); ++i) { 399bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen FunctionBodyNode* function = functionStack[i]; 400bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen const Identifier& ident = function->ident(); 401bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (functionBody->captures(ident)) { 402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!m_hasCreatedActivation) { 403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_hasCreatedActivation = true; 404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_create_activation); 405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(m_activationRegister->index()); 406a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 407bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_functions.add(ident.impl()); 408bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitNewFunction(addVar(ident, false), function); 409bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 410bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 411bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen for (size_t i = 0; i < varStack.size(); ++i) { 412bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen const Identifier& ident = *varStack[i].first; 413bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (functionBody->captures(ident)) 414bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen addVar(ident, varStack[i].second & DeclarationStacks::IsConstant); 415bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 416bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 4174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks; 418a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!canLazilyCreateFunctions && !m_hasCreatedActivation) { 419a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_hasCreatedActivation = true; 420a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_create_activation); 421a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(m_activationRegister->index()); 422a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 423a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 424bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen codeBlock->m_numCapturedVars = codeBlock->m_numVars; 425bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_firstLazyFunction = codeBlock->m_numVars; 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < functionStack.size(); ++i) { 427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionBodyNode* function = functionStack[i]; 428231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const Identifier& ident = function->ident(); 429bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!functionBody->captures(ident)) { 430bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_functions.add(ident.impl()); 431bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen RefPtr<RegisterID> reg = addVar(ident, false); 432bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // Don't lazily create functions that override the name 'arguments' 433bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // as this would complicate lazy instantiation of actual arguments. 434bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!canLazilyCreateFunctions || ident == propertyNames().arguments) 435bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitNewFunction(reg.get(), function); 436bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen else { 437bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitInitLazyRegister(reg.get()); 438bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_lazyFunctions.set(reg->index(), function); 439bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 440bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 442bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction; 443bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen for (size_t i = 0; i < varStack.size(); ++i) { 444bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen const Identifier& ident = *varStack[i].first; 445bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!functionBody->captures(ident)) 446bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen addVar(ident, varStack[i].second & DeclarationStacks::IsConstant); 447bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 448bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 4494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (m_shouldEmitDebugHooks) 450bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen codeBlock->m_numCapturedVars = codeBlock->m_numVars; 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 452231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionParameters& parameters = *functionBody->parameters(); 453231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block size_t parameterCount = parameters.size(); 454545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1; 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_parameters.grow(1 + parameterCount); // reserve space for "this" 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Add "this" as a parameter 458545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch m_thisRegister.setIndex(nextParameterIndex); 459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ++m_codeBlock->m_numParameters; 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < parameterCount; ++i) 462545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch addParameter(parameters[i], ++nextParameterIndex); 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch preserveLastVar(); 4655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (isConstructor()) { 4675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RefPtr<RegisterID> func = newTemporary(); 4685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke RefPtr<RegisterID> funcProto = newTemporary(); 4695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke emitOpcode(op_get_callee); 4715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke instructions().append(func->index()); 4725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Load prototype. 4735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke emitGetById(funcProto.get(), func.get(), globalData()->propertyNames->prototype); 4745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 4755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke emitOpcode(op_create_this); 4765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke instructions().append(m_thisRegister.index()); 4775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke instructions().append(funcProto->index()); 4785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } else if (functionBody->usesThis() || m_shouldEmitDebugHooks) { 479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (codeBlock->isStrictMode()) 480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_convert_this_strict); 481a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch else 482a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_convert_this); 4835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke instructions().append(m_thisRegister.index()); 4845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochBytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock) 48881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger()) 48981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling()) 49081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo()) 49181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_scopeChain(*scopeChain->globalData, scopeChain) 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_symbolTable(symbolTable) 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_scopeNode(evalNode) 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_codeBlock(codeBlock) 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_thisRegister(RegisterFile::ProgramCodeThisRegister) 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_finallyDepth(0) 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_dynamicScopeDepth(0) 498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project , m_baseScopeDepth(codeBlock->baseScopeDepth()) 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_codeType(EvalCode) 5000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch , m_nextConstantOffset(0) 5015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_globalConstantIndex(0) 502a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_hasCreatedActivation(true) 503bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_firstLazyFunction(0) 504bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen , m_lastLazyFunction(0) 50581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch , m_globalData(scopeChain->globalData) 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_lastOpcodeID(op_end) 507a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#ifndef NDEBUG 508a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch , m_lastOpcodePosition(0) 509a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif 510f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch , m_stack(m_globalData->stack()) 51106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen , m_usesExceptions(false) 51265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_expressionTooDeep(false) 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_shouldEmitDebugHooks || m_baseScopeDepth) 515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->setNeedsFullScopeChain(true); 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_enter); 518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->setGlobalData(m_globalData); 519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->m_numParameters = 1; // Allocate space for "this" 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 521231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); 522231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (size_t i = 0; i < functionStack.size(); ++i) 523231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i])); 524231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 525231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const DeclarationStacks::VarStack& varStack = evalNode->varStack(); 526231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block unsigned numVariables = varStack.size(); 527231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Vector<Identifier> variables; 528231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block variables.reserveCapacity(numVariables); 529231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (size_t i = 0; i < numVariables; ++i) 530231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block variables.append(*varStack[i].first); 531231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block codeBlock->adoptVariables(variables); 532bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen codeBlock->m_numCapturedVars = codeBlock->m_numVars; 5330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch preserveLastVar(); 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 536bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg) 537bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 538bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitOpcode(op_init_lazy_reg); 539bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(reg->index()); 540bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return reg; 541bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 542bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 543545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex) 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Parameters overwrite var declarations, but not function declarations. 546f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick StringImpl* rep = ident.impl(); 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_functions.contains(rep)) { 548545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch symbolTable().set(rep, parameterIndex); 549545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch RegisterID& parameter = registerFor(parameterIndex); 550545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch parameter.setIndex(parameterIndex); 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // To maintain the calling convention, we have to allocate unique space for 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // each parameter, even if the parameter doesn't make it into the symbol table. 555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ++m_codeBlock->m_numParameters; 5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::registerFor(const Identifier& ident) 5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ident == propertyNames().thisIdentifier) 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return &m_thisRegister; 5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!shouldOptimizeLocals()) 5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 566f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick SymbolTableEntry entry = symbolTable().get(ident.impl()); 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (entry.isNull()) 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (ident == propertyNames().arguments) 5715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian createArgumentsIfNecessary(); 5725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 573bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); 5745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 5755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool BytecodeGenerator::willResolveToArguments(const Identifier& ident) 5775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 5785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (ident != propertyNames().arguments) 5795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 5805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!shouldOptimizeLocals()) 5825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 5835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 584f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick SymbolTableEntry entry = symbolTable().get(ident.impl()); 5855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (entry.isNull()) 5865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 5875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_codeBlock->usesArguments() && m_codeType == FunctionCode) 5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 5905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 5925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 5935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5945f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::uncheckedRegisterForArguments() 5955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 5965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(willResolveToArguments(propertyNames().arguments)); 5975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 598f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl()); 5995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!entry.isNull()); 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ®isterFor(entry.getIndex()); 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 603bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg) 604bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 605bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction) 606bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return reg; 607bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index())); 608bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return reg; 609bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 610bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 611635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident) 6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_codeType == EvalCode) 6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 616f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick SymbolTableEntry entry = symbolTable().get(ident.impl()); 617231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (entry.isNull()) 618231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return 0; 6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 620bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); 6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 623635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::isLocal(const Identifier& ident) 6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ident == propertyNames().thisIdentifier) 6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 628f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return shouldOptimizeLocals() && symbolTable().contains(ident.impl()); 6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 631635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool BytecodeGenerator::isLocalConstant(const Identifier& ident) 6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 633f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return symbolTable().get(ident.impl()).isReadOnly(); 6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 636635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::newRegister() 6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_calleeRegisters.append(m_calleeRegisters.size()); 639635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size()); 6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return &m_calleeRegisters.last(); 6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 643635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::newTemporary() 6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reclaim free register IDs. 6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount()) 6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_calleeRegisters.removeLast(); 6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RegisterID* result = newRegister(); 6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result->setTemporary(); 6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 654635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::highestUsedRegister() 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 656635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project size_t count = m_codeBlock->m_numCalleeRegisters; 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (m_calleeRegisters.size() < count) 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newRegister(); 6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return &m_calleeRegisters.last(); 6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 662635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name) 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reclaim free label scopes. 6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (m_labelScopes.size() && !m_labelScopes.last().refCount()) 6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_labelScopes.removeLast(); 6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Allocate new label scope. 6690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets. 6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_labelScopes.append(scope); 6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return &m_labelScopes.last(); 6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::newLabel() 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reclaim free label IDs. 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (m_labels.size() && !m_labels.last().refCount()) 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_labels.removeLast(); 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Allocate new label ID. 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_labels.append(m_codeBlock); 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return &m_labels.last(); 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 685635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0) 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 687635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project unsigned newLabelIndex = instructions().size(); 688635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project l0->setLocation(newLabelIndex); 689635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 690635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_codeBlock->numberOfJumpTargets()) { 691635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project unsigned lastLabelIndex = m_codeBlock->lastJumpTarget(); 692635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(lastLabelIndex <= newLabelIndex); 693635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (newLabelIndex == lastLabelIndex) { 694635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Peephole optimizations have already been disabled by emitting the last label 695635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return l0; 696635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 697635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 698635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 699635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addJumpTarget(newLabelIndex); 700635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This disables peephole optimizations when an instruction is a jump target 7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_lastOpcodeID = op_end; 7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return l0; 7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 706635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitOpcode(OpcodeID opcodeID) 7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 708dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#ifndef NDEBUG 709dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch size_t opcodePosition = instructions().size(); 710dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end); 711dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_lastOpcodePosition = opcodePosition; 712dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#endif 713635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project instructions().append(globalData()->interpreter->getOpcode(opcodeID)); 7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_lastOpcodeID = opcodeID; 7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index) 7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(instructions().size() >= 4); 7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t size = instructions().size(); 7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dstIndex = instructions().at(size - 3).u.operand; 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src1Index = instructions().at(size - 2).u.operand; 7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src2Index = instructions().at(size - 1).u.operand; 7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex) 7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(instructions().size() >= 3); 7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t size = instructions().size(); 7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dstIndex = instructions().at(size - 2).u.operand; 7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcIndex = instructions().at(size - 1).u.operand; 7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 734635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp() 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(instructions().size() >= 4); 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().shrink(instructions().size() - 4); 738dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_lastOpcodeID = op_end; 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp() 7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(instructions().size() >= 3); 7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().shrink(instructions().size() - 3); 745dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch m_lastOpcodeID = op_end; 7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 748635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJump(Label* target) 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 750cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 751635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project emitOpcode(target->isForward() ? op_jmp : op_loop); 752cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 756635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target) 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 758643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (m_lastOpcodeID == op_less) { 7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int src1Index; 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int src2Index; 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindBinaryOp(); 767cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 768cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 769643ca7872b450ea4efacab6188849e5aac2ba161Steve Block emitOpcode(target->isForward() ? op_jless : op_loop_if_less); 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src1Index); 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src2Index); 772cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 77521939df44de1705786c545cd1bf519d47250322dBen Murdoch } else if (m_lastOpcodeID == op_lesseq) { 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int src1Index; 7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int src2Index; 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindBinaryOp(); 784cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 785cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 78621939df44de1705786c545cd1bf519d47250322dBen Murdoch emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq); 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src1Index); 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src2Index); 789cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (m_lastOpcodeID == op_eq_null && target->isForward()) { 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int srcIndex; 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastUnaryOp(dstIndex, srcIndex); 7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 800cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 801cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jeq_null); 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 804cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 807635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (m_lastOpcodeID == op_neq_null && target->isForward()) { 8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int srcIndex; 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastUnaryOp(dstIndex, srcIndex); 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 815cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 816cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jneq_null); 8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 819cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 824cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 825cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 826635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true); 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(cond->index()); 828cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 832635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target) 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 834643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (m_lastOpcodeID == op_less && target->isForward()) { 8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int src1Index; 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int src2Index; 8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindBinaryOp(); 843cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 844cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jnless); 8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src1Index); 8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src2Index); 848cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 851643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else if (m_lastOpcodeID == op_lesseq && target->isForward()) { 8525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int dstIndex; 8535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int src1Index; 8545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int src2Index; 8555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian retrieveLastBinaryOp(dstIndex, src1Index, src2Index); 8575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 8595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian rewindBinaryOp(); 860cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 861cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 8625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_jnlesseq); 8635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(src1Index); 8645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(src2Index); 865cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return target; 8675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (m_lastOpcodeID == op_not) { 8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int srcIndex; 8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastUnaryOp(dstIndex, srcIndex); 8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 876cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 877cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 878643ca7872b450ea4efacab6188849e5aac2ba161Steve Block emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true); 8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 880cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 883643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else if (m_lastOpcodeID == op_eq_null && target->isForward()) { 8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int srcIndex; 8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastUnaryOp(dstIndex, srcIndex); 8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 891cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 892cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jneq_null); 8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 895cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 898643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else if (m_lastOpcodeID == op_neq_null && target->isForward()) { 8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int srcIndex; 9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastUnaryOp(dstIndex, srcIndex); 9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) { 9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 906cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 907cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jeq_null); 9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 910cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 915cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 916643ca7872b450ea4efacab6188849e5aac2ba161Steve Block emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false); 9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(cond->index()); 918cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9225f1ab04193ad0130ca8204aadaceae083aca9881Feng QianPassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target) 9235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 924cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 925cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 9265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_jneq_ptr); 9275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(cond->index()); 9282bde8e466a4451c7319e3a072d118917957d6554Steve Block instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->callFunction())); 929cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 9305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return target; 9315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 9325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9335f1ab04193ad0130ca8204aadaceae083aca9881Feng QianPassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target) 9345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 935cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 936cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 9375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_jneq_ptr); 9385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(cond->index()); 9392bde8e466a4451c7319e3a072d118917957d6554Steve Block instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->applyFunction())); 940cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 9415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return target; 9425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 9435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 944635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectunsigned BytecodeGenerator::addConstant(const Identifier& ident) 9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 946f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick StringImpl* rep = ident.impl(); 947635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers()); 9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result.second) // new entry 949635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addIdentifier(Identifier(m_globalData, rep)); 9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result.first->second; 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochRegisterID* BytecodeGenerator::addConstantValue(JSValue v) 9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int index = m_nextConstantOffset; 9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset); 9590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (result.second) { 9600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset); 9610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ++m_nextConstantOffset; 9622bde8e466a4451c7319e3a072d118917957d6554Steve Block m_codeBlock->addConstant(JSValue(v)); 9630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } else 9640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch index = result.first->second; 9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return &m_constantPoolRegisters[index]; 9675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 9685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9692bde8e466a4451c7319e3a072d118917957d6554Steve Blockunsigned BytecodeGenerator::addRegExp(PassRefPtr<RegExp> r) 9706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 9716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return m_codeBlock->addRegExp(r); 9726c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 9736c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 974635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src) 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_mov); 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src->index()); 9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 982635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src) 9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 984635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project emitOpcode(opcodeID); 9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src->index()); 9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 990635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst) 9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_pre_inc); 9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcDst->index()); 9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return srcDst; 9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 997635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst) 9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_pre_dec); 10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcDst->index()); 10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return srcDst; 10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1004635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst) 10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_post_inc); 10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcDst->index()); 10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1012635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst) 10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_post_dec); 10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcDst->index()); 10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1020635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types) 10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1022635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project emitOpcode(opcodeID); 10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src1->index()); 10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src2->index()); 10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1027635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor || 10280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div) 10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(types.toInt()); 10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1034635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2) 10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_lastOpcodeID == op_typeof) { 10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dstIndex; 10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int srcIndex; 10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project retrieveLastUnaryOp(dstIndex, srcIndex); 10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (src1->index() == dstIndex 10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project && src1->isTemporary() 1044635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project && m_codeBlock->isConstantRegisterIndex(src2->index()) 10452bde8e466a4451c7319e3a072d118917957d6554Steve Block && m_codeBlock->constantRegister(src2->index()).get().isString()) { 10462bde8e466a4451c7319e3a072d118917957d6554Steve Block const UString& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue(); 10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (value == "undefined") { 10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_is_undefined); 10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (value == "boolean") { 10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_is_boolean); 10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (value == "number") { 10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_is_number); 10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (value == "string") { 10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_is_string); 10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (value == "object") { 10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_is_object); 10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (value == "function") { 10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rewindUnaryOp(); 10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_is_function); 10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(srcIndex); 10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1092635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project emitOpcode(opcodeID); 10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src1->index()); 10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src2->index()); 10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1099635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b) 11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitLoad(dst, jsBoolean(b)); 11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number) 11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time. 1107ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // Later we can do the extra work to handle that like the other cases. They also don't 1108ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // work correctly with NaN as a key. 1109ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number)) 1110e14391e94c850b8bd03680c23b38978db68687a8John Reck return emitLoad(dst, jsNumber(number)); 11115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second; 11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!valueInMap) 1113e14391e94c850b8bd03680c23b38978db68687a8John Reck valueInMap = jsNumber(number); 11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitLoad(dst, valueInMap); 11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier) 11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1119f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second; 1120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!stringInMap) 1121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project stringInMap = jsOwnedString(globalData(), identifier.ustring()); 11225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return emitLoad(dst, JSValue(stringInMap)); 11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11255f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v) 11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch RegisterID* constantID = addConstantValue(v); 11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (dst) 11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitMove(dst, constantID); 11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return constantID; 11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject) 11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cases where we cannot statically optimize the lookup. 11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (property == propertyNames().arguments || !canOptimizeNonLocals()) { 11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stackDepth = 0; 11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project index = missingSymbolMarker(); 11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (shouldOptimizeLocals() && m_codeType == GlobalCode) { 11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = m_scopeChain->begin(); 11422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block globalObject = iter->get(); 11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT((++iter) == m_scopeChain->end()); 11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t depth = 0; 11496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen requiresDynamicChecks = false; 11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = m_scopeChain->begin(); 11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = m_scopeChain->end(); 11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (; iter != end; ++iter, ++depth) { 11532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObject* currentScope = iter->get(); 11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!currentScope->isVariableObject()) 11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope); 1157f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl()); 11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Found the property 11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!entry.isNull()) { 11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (entry.isReadOnly() && forWriting) { 11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stackDepth = 0; 11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project index = missingSymbolMarker(); 11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (++iter == end) 11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project globalObject = currentVariableObject; 11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1168e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block stackDepth = depth + m_codeBlock->needsFullScopeChain(); 11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project index = entry.getIndex(); 11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (++iter == end) 11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project globalObject = currentVariableObject; 11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool scopeRequiresDynamicChecks = false; 11756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks)) 11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 11776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen requiresDynamicChecks |= scopeRequiresDynamicChecks; 11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Can't locate the property but we're able to avoid a few lookups. 1180e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block stackDepth = depth + m_codeBlock->needsFullScopeChain(); 11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project index = missingSymbolMarker(); 11822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObject* scope = iter->get(); 11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (++iter == end) 11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project globalObject = scope; 11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid BytecodeGenerator::emitCheckHasInstance(RegisterID* base) 11896b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 11906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner emitOpcode(op_check_has_instance); 11916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner instructions().append(base->index()); 11926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 11936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 1194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype) 11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_instanceof); 11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(basePrototype->index()); 12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property) 12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t depth = 0; 12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int index = 0; 12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* globalObject = 0; 12096c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool requiresDynamicChecks = false; 12106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) { 12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We can't optimise at all :-( 12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_resolve); 12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (globalObject) { 1219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool forceGlobalResolve = false; 1220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 12216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) { 1222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Directly index the property lookup across multiple scopes. 1223635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return emitGetScopedVar(dst, depth, index, globalObject); 1224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 1225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1227635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addGlobalResolveInfo(instructions().size()); 1228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 1229635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addGlobalResolveInstruction(instructions().size()); 1230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 12316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global); 12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 12366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (requiresDynamicChecks) 12376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen instructions().append(depth); 12386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return dst; 12396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 12406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 12416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (requiresDynamicChecks) { 12426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // If we get here we have eval nested inside a |with| just give up 12436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen emitOpcode(op_resolve); 12446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen instructions().append(dst->index()); 12456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen instructions().append(addConstant(property)); 12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (index != missingSymbolMarker()) { 1250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Directly index the property lookup across multiple scopes. 1251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return emitGetScopedVar(dst, depth, index, globalObject); 1252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 1253635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // In this case we are at least able to drop a few scope chains from the 12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // lookup chain, although we still need to hash from then on. 12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_resolve_skip); 12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(depth); 12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12635f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue globalObject) 12648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (globalObject) { 12668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_get_global_var); 12678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(index); 12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_get_scoped_var); 12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(index); 12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(depth); 12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12795f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue globalObject) 12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (globalObject) { 12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_global_var); 12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(index); 12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_scoped_var); 12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(index); 12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(depth); 12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property) 12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t depth = 0; 12975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int index = 0; 12985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSObject* globalObject = 0; 12996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool requiresDynamicChecks = false; 13006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject); 13016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!globalObject || requiresDynamicChecks) { 13025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We can't optimise at all :-( 13035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_resolve_base); 13045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(dst->index()); 13055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(addConstant(property)); 1306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(false); 13075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return dst; 13085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Global object is the base 13110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return emitLoad(dst, JSValue(globalObject)); 13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1314a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const Identifier& property) 1315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 1316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!m_codeBlock->isStrictMode()) 1317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return emitResolveBase(dst, property); 1318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch size_t depth = 0; 1319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int index = 0; 1320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSObject* globalObject = 0; 1321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool requiresDynamicChecks = false; 1322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject); 1323a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!globalObject || requiresDynamicChecks) { 1324a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // We can't optimise at all :-( 1325a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_resolve_base); 1326a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(dst->index()); 1327a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(addConstant(property)); 1328a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(true); 1329a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return dst; 1330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1331a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // Global object is the base 1333a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<RegisterID> result = emitLoad(dst, JSValue(globalObject)); 1334a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_ensure_property_exists); 1335a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(dst->index()); 1336a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(addConstant(property)); 1337a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return result.get(); 1338a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 1339a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property) 13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 13425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t depth = 0; 13435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int index = 0; 13445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSObject* globalObject = 0; 13456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool requiresDynamicChecks = false; 13466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) { 13475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We can't optimise at all :-( 13485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_resolve_with_base); 13495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(baseDst->index()); 13505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(propDst->index()); 13515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(addConstant(property)); 13525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return baseDst; 13535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool forceGlobalResolve = false; 13565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Global object is the base 13580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch emitLoad(baseDst, JSValue(globalObject)); 13595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (index != missingSymbolMarker() && !forceGlobalResolve) { 13615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Directly index the property lookup across multiple scopes. 13625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitGetScopedVar(propDst, depth, index, globalObject); 13635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return baseDst; 13645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 13655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 13665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(JIT) 13675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_codeBlock->addGlobalResolveInfo(instructions().size()); 13685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else 13695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_codeBlock->addGlobalResolveInstruction(instructions().size()); 13705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 13716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global); 13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(propDst->index()); 13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 13745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(0); 13755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(0); 13766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (requiresDynamicChecks) 13776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen instructions().append(depth); 13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return baseDst; 13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 13808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid BytecodeGenerator::emitMethodCheck() 13825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 13835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_method_check); 13845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 13855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1386635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property) 13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1388635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 13890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_codeBlock->addStructureStubInfo(StructureStubInfo(access_get_by_id)); 1390635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 1391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addPropertyAccessInstruction(instructions().size()); 1392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_get_by_id); 13958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1405bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base) 1406bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 1407bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitOpcode(op_get_arguments_length); 1408bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(dst->index()); 1409bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen ASSERT(base->index() == m_codeBlock->argumentsRegister()); 1410bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(base->index()); 1411bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(addConstant(propertyNames().length)); 1412bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return dst; 1413bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 1414bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 1415635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value) 14168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 14180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id)); 1419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 1420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addPropertyAccessInstruction(instructions().size()); 1421635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 14228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_by_id); 14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); 1431e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(0); 1432e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return value; 1433e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 1434e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1435e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkeRegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value) 1436e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 1437e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 1438e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id)); 1439e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#else 1440e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_codeBlock->addPropertyAccessInstruction(instructions().size()); 1441e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1442e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1443e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke emitOpcode(op_put_by_id); 1444e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(base->index()); 1445e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(addConstant(property)); 1446e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(value->index()); 1447e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(0); 1448e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(0); 1449e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(0); 1450e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(0); 1451e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke instructions().append(property != m_globalData->propertyNames->underscoreProto); 14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1455635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value) 14568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_getter); 14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 14628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value) 14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_setter); 14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property) 14748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_del_by_id); 14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1482bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property) 1483bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 1484bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen emitOpcode(op_get_argument_by_val); 1485bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(dst->index()); 1486bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen ASSERT(base->index() == m_codeBlock->argumentsRegister()); 1487bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(base->index()); 1488bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(property->index()); 1489bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return dst; 1490bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 1491bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 1492635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property) 14938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1494cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for (size_t i = m_forInContextStack.size(); i > 0; i--) { 1495cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ForInContext& context = m_forInContextStack[i - 1]; 1496cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (context.propertyRegister == property) { 1497cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block emitOpcode(op_get_by_pname); 1498cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(dst->index()); 1499cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(base->index()); 1500cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(property->index()); 1501cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(context.expectedSubscriptRegister->index()); 1502cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(context.iterRegister->index()); 1503cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(context.indexRegister->index()); 1504cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return dst; 1505cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 1506cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_get_by_val); 15088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 15108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(property->index()); 15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 15128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value) 15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_by_val); 15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(property->index()); 15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1523635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property) 15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_del_by_val); 15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(property->index()); 15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1532635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value) 15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_put_by_index); 15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(base->index()); 15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(index); 15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value; 15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1541635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst) 15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_new_object); 15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 15458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements) 15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<RefPtr<RegisterID>, 16> argv; 15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (ElementNode* n = elements; n; n = n->next()) { 15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (n->elision()) 15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project argv.append(newTemporary()); 1555635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // op_new_array requires the initial values to be a sequential range of registers 1556635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1); 15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitNode(argv.last().get(), n->value()); 15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_new_array); 15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(argv.size() ? argv[0]->index() : 0); // argv 15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(argv.size()); // argc 15638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1566231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function) 15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1568bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)), false); 1569bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 1570231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1571bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function) 1572bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 1573bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen std::pair<FunctionOffsetMap::iterator, bool> ptr = m_functionOffsets.add(function, 0); 1574bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (ptr.second) 1575bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen ptr.first->second = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)); 1576bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return emitNewFunctionInternal(dst, ptr.first->second, true); 1577bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 1578bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 1579bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenRegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck) 1580bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 1581a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch createActivationIfNecessary(); 15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_new_func); 15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 1584231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block instructions().append(index); 1585bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen instructions().append(doNullCheck); 15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15892bde8e466a4451c7319e3a072d118917957d6554Steve BlockRegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, PassRefPtr<RegExp> regExp) 15906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 15916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen emitOpcode(op_new_regexp); 15926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen instructions().append(dst->index()); 15936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen instructions().append(addRegExp(regExp)); 15946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return dst; 15956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 15966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1597635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n) 15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1599231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionBodyNode* function = n->body(); 1600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function)); 1601a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1602a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch createActivationIfNecessary(); 16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_new_func_exp); 16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(r0->index()); 1605231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block instructions().append(index); 16068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return r0; 16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1609545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1611545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return emitCall(op_call, dst, func, callArguments, divot, startOffset, endOffset); 16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid BytecodeGenerator::createArgumentsIfNecessary() 16155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 1616e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (m_codeType != FunctionCode) 1617e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return; 1618f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 1619f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_codeBlock->usesArguments()) 1620f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 1621e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 1622a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // If we're in strict mode we tear off the arguments on function 1623a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // entry, so there's no need to check if we need to create them 1624a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // now 1625a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (m_codeBlock->isStrictMode()) 1626a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 1627a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1628e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block emitOpcode(op_create_arguments); 1629e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(m_codeBlock->argumentsRegister()); 16305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 16315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1632a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid BytecodeGenerator::createActivationIfNecessary() 1633a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 1634a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (m_hasCreatedActivation) 1635a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 1636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!m_codeBlock->needsFullScopeChain()) 1637a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return; 1638a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch emitOpcode(op_create_activation); 1639a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch instructions().append(m_activationRegister->index()); 1640a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 1641a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 1642545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1644545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset); 16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1647545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(opcodeID == op_call || opcodeID == op_call_eval); 16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(func->refCount()); 1651635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1652545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (m_shouldEmitProfileHooks) 1653545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch emitMove(callArguments.profileHookRegister(), func); 1654635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 16558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Generate code for arguments. 1656545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch unsigned argumentIndex = 0; 1657545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next) 1658545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch emitNode(callArguments.argumentRegister(argumentIndex++), n); 16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reserve space for call frame. 16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; 16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) 16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame.append(newTemporary()); 16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_shouldEmitProfileHooks) { 16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_profile_will_call); 1667545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.profileHookRegister()->index()); 16688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitExpressionInfo(divot, startOffset, endOffset); 1671635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1672635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1673635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addCallLinkInfo(); 1674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 1675635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Emit call. 16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(opcodeID); 1678635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project instructions().append(func->index()); // func 1679545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.count()); // argCount 1680545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.callFrame()); // registerOffset 1681e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (dst != ignoredResult()) { 1682e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block emitOpcode(op_call_put_result); 1683e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(dst->index()); // dst 1684e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 16858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_shouldEmitProfileHooks) { 16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_profile_did_call); 1688545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.profileHookRegister()->index()); 16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 16938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 169428040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuRegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* arguments) 16955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 16965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(argCountDst->index() < arguments->index()); 16975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_load_varargs); 16985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(argCountDst->index()); 16995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(arguments->index()); 170028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset 17015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return argCountDst; 17025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 17035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17045f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCountRegister, unsigned divot, unsigned startOffset, unsigned endOffset) 17055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 17065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(func->refCount()); 17075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(thisRegister->refCount()); 17085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(dst != func); 17095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_shouldEmitProfileHooks) { 17105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_profile_will_call); 17115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(func->index()); 17125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 17135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitExpressionInfo(divot, startOffset, endOffset); 17155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 17165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Emit call. 17175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_call_varargs); 17185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(func->index()); // func 17195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(argCountRegister->index()); // arg count 17205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset 1721e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (dst != ignoredResult()) { 1722e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block emitOpcode(op_call_put_result); 1723e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(dst->index()); // dst 1724e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 17255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_shouldEmitProfileHooks) { 17265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_profile_did_call); 17275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(func->index()); 17285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 17295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return dst; 17305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 17315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1732635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitReturn(RegisterID* src) 17338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1734635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_codeBlock->needsFullScopeChain()) { 17358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_tear_off_activation); 1736e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(m_activationRegister->index()); 1737e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(m_codeBlock->argumentsRegister()); 1738a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1 1739a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch && !m_codeBlock->isStrictMode()) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time. 17408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_tear_off_arguments); 1741e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(m_codeBlock->argumentsRegister()); 1742e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 17438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1744e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // Constructors use op_ret_object_or_this to check the result is an 1745e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // object, unless we can trivially determine the check is not 1746e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block // necessary (currently, if the return value is 'this'). 1747e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (isConstructor() && (src->index() != m_thisRegister.index())) { 1748e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block emitOpcode(op_ret_object_or_this); 1749e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(src->index()); 1750e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(m_thisRegister.index()); 1751e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return src; 1752e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitUnaryNoDstOp(op_ret, src); 17548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1756635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src) 17578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1758635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project emitOpcode(opcodeID); 17598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(src->index()); 17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return src; 17618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1763545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochRegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset) 17648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 17658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(func->refCount()); 17668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1767545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (m_shouldEmitProfileHooks) 1768545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch emitMove(callArguments.profileHookRegister(), func); 1769635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 17708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Generate code for arguments. 1771545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch unsigned argumentIndex = 0; 1772545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) { 1773545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) 1774545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch emitNode(callArguments.argumentRegister(argumentIndex++), n); 17758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_shouldEmitProfileHooks) { 17788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_profile_will_call); 1779545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.profileHookRegister()->index()); 17808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reserve space for call frame. 17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; 17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) 17858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame.append(newTemporary()); 17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitExpressionInfo(divot, startOffset, endOffset); 1788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1789635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1790635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addCallLinkInfo(); 1791635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 1792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_construct); 1794635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project instructions().append(func->index()); // func 1795545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.count()); // argCount 1796545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.callFrame()); // registerOffset 1797e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (dst != ignoredResult()) { 1798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block emitOpcode(op_call_put_result); 1799e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block instructions().append(dst->index()); // dst 1800e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 18018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_shouldEmitProfileHooks) { 18038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_profile_did_call); 1804545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch instructions().append(callArguments.profileHookRegister()->index()); 18058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 18088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18105f1ab04193ad0130ca8204aadaceae083aca9881Feng QianRegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count) 18115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 18125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_strcat); 18135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(dst->index()); 18145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(src->index()); 18155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(count); 18165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return dst; 18185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 18195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 18205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src) 18215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 18225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian emitOpcode(op_to_primitive); 18235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(dst->index()); 18245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian instructions().append(src->index()); 18255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 18265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1827635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope) 18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1829635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(scope->isTemporary()); 18308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ControlFlowContext context; 18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project context.isFinallyBlock = false; 18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_scopeContextStack.append(context); 18338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_dynamicScopeDepth++; 18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitUnaryNoDstOp(op_push_scope, scope); 18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1838635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitPopScope() 18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_scopeContextStack.size()); 18418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!m_scopeContextStack.last().isFinallyBlock); 18428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_pop_scope); 18448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_scopeContextStack.removeLast(); 18468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_dynamicScopeDepth--; 18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1849635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine) 18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 185121939df44de1705786c545cd1bf519d47250322dBen Murdoch#if ENABLE(DEBUG_WITH_BREAKPOINT) 185221939df44de1705786c545cd1bf519d47250322dBen Murdoch if (debugHookID != DidReachBreakpoint) 185321939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 185421939df44de1705786c545cd1bf519d47250322dBen Murdoch#else 18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_shouldEmitDebugHooks) 18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 185721939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif 18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_debug); 18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(debugHookID); 18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(firstLine); 18618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(lastLine); 18628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1864635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst) 18658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ControlFlowContext scope; 18678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scope.isFinallyBlock = true; 18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FinallyContext context = { target, retAddrDst }; 18698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scope.finallyContext = context; 18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_scopeContextStack.append(scope); 18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_finallyDepth++; 18728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1874635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::popFinallyContext() 18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_scopeContextStack.size()); 18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_scopeContextStack.last().isFinallyBlock); 18788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_finallyDepth > 0); 18798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_scopeContextStack.removeLast(); 18808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_finallyDepth--; 18818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 18828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1883635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectLabelScope* BytecodeGenerator::breakTarget(const Identifier& name) 18848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 18858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reclaim free label scopes. 18865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // 18875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()', 18885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // however sometimes this appears to lead to GCC going a little haywire and entering the loop with 18895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // size 0, leading to segfaulty badness. We are yet to identify a valid cause within our code to 18905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the 18915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // loop condition is a workaround. 18925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian while (m_labelScopes.size()) { 18935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_labelScopes.last().refCount()) 18945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian break; 18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_labelScopes.removeLast(); 18965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_labelScopes.size()) 18998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We special-case the following, which is a syntax error in Firefox: 19028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // label: 19038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // break; 19048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (name.isEmpty()) { 19058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = m_labelScopes.size() - 1; i >= 0; --i) { 19068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LabelScope* scope = &m_labelScopes[i]; 19078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (scope->type() != LabelScope::NamedLabel) { 19088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->breakTarget()); 19098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return scope; 19108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = m_labelScopes.size() - 1; i >= 0; --i) { 19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LabelScope* scope = &m_labelScopes[i]; 19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (scope->name() && *scope->name() == name) { 19188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->breakTarget()); 19198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return scope; 19208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 19238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 19248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1925635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectLabelScope* BytecodeGenerator::continueTarget(const Identifier& name) 19268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 19278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Reclaim free label scopes. 19288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (m_labelScopes.size() && !m_labelScopes.last().refCount()) 19298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_labelScopes.removeLast(); 19308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_labelScopes.size()) 19328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 19338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (name.isEmpty()) { 19358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = m_labelScopes.size() - 1; i >= 0; --i) { 19368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LabelScope* scope = &m_labelScopes[i]; 19378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (scope->type() == LabelScope::Loop) { 19388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->continueTarget()); 19398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return scope; 19408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Continue to the loop nested nearest to the label scope that matches 19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // 'name'. 19478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LabelScope* result = 0; 19488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = m_labelScopes.size() - 1; i >= 0; --i) { 19498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LabelScope* scope = &m_labelScopes[i]; 19508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (scope->type() == LabelScope::Loop) { 19518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->continueTarget()); 19528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = scope; 19538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (scope->name() && *scope->name() == name) 19558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; // may be 0 19568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 19598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1960635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope) 19618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (topScope > bottomScope) { 19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // First we count the number of dynamic scopes we need to remove to get 19648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to a finally block. 19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int nNormalScopes = 0; 19668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (topScope > bottomScope) { 19678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (topScope->isFinallyBlock) 19688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 19698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++nNormalScopes; 19708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project --topScope; 19718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (nNormalScopes) { 1974cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 1975cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 19768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to remove a number of dynamic scopes to get to the next 19778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // finally block 19788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jmp_scopes); 19798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(nNormalScopes); 19808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If topScope == bottomScope then there isn't actually a finally block 19828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // left to emit, so make the jmp_scopes jump directly to the target label 19838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (topScope == bottomScope) { 1984cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 19858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Otherwise we just use jmp_scopes to pop a group of scopes and go 19898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to the next instruction 1990635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RefPtr<Label> nextInsn = newLabel(); 1991cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(nextInsn->bind(begin, instructions().size())); 19928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitLabel(nextInsn.get()); 19938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian while (topScope > bottomScope && topScope->isFinallyBlock) { 19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr); 19978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project --topScope; 19985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 19998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitJump(target); 20018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 20028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2003635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth) 20048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 20058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scopeDepth() - targetScopeDepth >= 0); 2006635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(target->isForward()); 20078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t scopeDelta = scopeDepth() - targetScopeDepth; 20098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scopeDelta <= m_scopeContextStack.size()); 20108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!scopeDelta) 20118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitJump(target); 20128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_finallyDepth) 20148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta); 20158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2016cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 2017cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 20188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jmp_scopes); 20198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(scopeDelta); 2020cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 20218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return target; 20228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 20238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2024cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockRegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget) 20258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2026cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 2027cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 2028cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block emitOpcode(op_get_pnames); 2029cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(dst->index()); 2030cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(base->index()); 2031cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(i->index()); 2032cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(size->index()); 2033cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(breakTarget->bind(begin, instructions().size())); 2034cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return dst; 2035cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block} 2036cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 2037cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockRegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target) 2038cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{ 2039cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 2040cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_next_pname); 20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 2043cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(base->index()); 2044cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(i->index()); 2045cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(size->index()); 20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(iter->index()); 2047cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(target->bind(begin, instructions().size())); 20488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dst; 20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2051635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end) 20528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 205306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen m_usesExceptions = true; 2054635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 2055cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; 2056635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 2057cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; 2058635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 2059635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2060635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_codeBlock->addExceptionHandler(info); 20618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_catch); 20628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(targetRegister->index()); 20638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return targetRegister; 20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 20658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid BytecodeGenerator::emitThrowReferenceError(const UString& message) 20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 20686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner emitOpcode(op_throw_reference_error); 20696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner instructions().append(addConstantValue(jsString(globalData(), message))->index()); 20706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 20716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2072635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally) 20738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2074cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block size_t begin = instructions().size(); 2075cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 20768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_jsr); 20778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(retAddrDst->index()); 2078cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions().append(finally->bind(begin, instructions().size())); 20790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it. 20808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return finally; 20818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 20828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2083635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc) 20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_sret); 20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(retAddrSrc->index()); 20878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2089231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value) 20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ControlFlowContext context; 20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project context.isFinallyBlock = false; 20938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_scopeContextStack.append(context); 20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_dynamicScopeDepth++; 20955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 20968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_push_new_scope); 20978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(dst->index()); 20988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(addConstant(property)); 20998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(value->index()); 21008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type) 21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SwitchInfo info = { instructions().size(), type }; 21058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (type) { 21068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case SwitchInfo::SwitchImmediate: 21078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_switch_imm); 21088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case SwitchInfo::SwitchCharacter: 21108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_switch_char); 21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 21128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case SwitchInfo::SwitchString: 21138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project emitOpcode(op_switch_string); 21148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 21158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 21168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT_NOT_REACHED(); 21178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); // place holder for table index 21208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(0); // place holder for default target 21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instructions().append(scrutineeRegister->index()); 21228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_switchContextStack.append(info); 21238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max) 21268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UNUSED_PARAM(max); 21288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node->isNumber()); 21298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double value = static_cast<NumberNode*>(node)->value(); 21308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int32_t key = static_cast<int32_t>(value); 21318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(key == value); 21328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(key >= min); 21338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(key <= max); 21348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return key - min; 21358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max) 21388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.min = min; 21408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.branchOffsets.resize(max - min + 1); 21418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.branchOffsets.fill(0); 21428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (uint32_t i = 0; i < clauseCount; ++i) { 21438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We're emitting this after the clause labels should have been fixed, so 21448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the labels should not be "forward" references 2145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!labels[i]->isForward()); 2146cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); 21478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max) 21518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UNUSED_PARAM(max); 21538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node->isString()); 2154f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick StringImpl* clause = static_cast<StringNode*>(node)->value().impl(); 2155692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(clause->length() == 1); 21568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int32_t key = clause->characters()[0]; 21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(key >= min); 21598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(key <= max); 21608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return key - min; 21618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max) 21648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.min = min; 21668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.branchOffsets.resize(max - min + 1); 21678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.branchOffsets.fill(0); 21688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (uint32_t i = 0; i < clauseCount; ++i) { 21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We're emitting this after the clause labels should have been fixed, so 21708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the labels should not be "forward" references 2171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!labels[i]->isForward()); 2172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); 21738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes) 21778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (uint32_t i = 0; i < clauseCount; ++i) { 21798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We're emitting this after the clause labels should have been fixed, so 21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the labels should not be "forward" references 2181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!labels[i]->isForward()); 21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(nodes[i]->isString()); 2184f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl(); 21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OffsetLocation location; 2186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3); 21878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jumpTable.offsetTable.add(clause, location); 21888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max) 21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SwitchInfo switchInfo = m_switchContextStack.last(); 21948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_switchContextStack.removeLast(); 21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (switchInfo.switchType == SwitchInfo::SwitchImmediate) { 2196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables(); 2197cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); 21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable(); 2200cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); 22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) { 2202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables(); 2203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); 22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2205635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable(); 2206cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max); 22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 22088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(switchInfo.switchType == SwitchInfo::SwitchString); 2209635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables(); 2210cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3); 22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable(); 2213cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes); 22148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 22168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2217635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException() 2218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 2219635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // It would be nice to do an even better job of identifying exactly where the expression is. 2220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // And we could make the caller pass the node pointer in, if there was some way of getting 2221635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // that from an arbitrary node. However, calling emitExpressionInfo without any useful data 2222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // is still good enough to get us an accurate line number. 222365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_expressionTooDeep = true; 22246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newTemporary(); 2225635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 2226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2227967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction) 2228967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 2229967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction); 2230967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 2231967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 2232967717af5423377c967781471ee106e2bb4e11c8Ben Murdochint BytecodeGenerator::argumentNumberFor(const Identifier& ident) 2233967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 2234967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch int parameterCount = m_parameters.size(); // includes 'this' 2235967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch RegisterID* registerID = registerFor(ident); 2236967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!registerID) 2237967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return 0; 2238967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch int index = registerID->index() + RegisterFile::CallFrameHeaderSize + parameterCount; 2239967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return (index > 0 && index < parameterCount) ? index : 0; 2240967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 2241967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 2243