Interpreter.cpp revision ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * Copyright (C) 2008, 2009, 2010 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 "Interpreter.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Arguments.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "BatchedTransitionOptimizer.h" 355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "CallFrame.h" 365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "CallFrameClosure.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CodeBlock.h" 3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "Heap.h" 395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Debugger.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DebuggerCallFrame.h" 416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "ErrorInstance.h" 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "EvalCodeCache.h" 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ExceptionHelpers.h" 44692e5dbf12901edacf14812a6fae25462920af42Steve Block#include "GetterSetter.h" 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GlobalEvalFunction.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSActivation.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSArray.h" 48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "JSByteArray.h" 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSFunction.h" 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSNotAnObject.h" 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSPropertyNameIterator.h" 525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "LiteralParser.h" 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSStaticScopeObject.h" 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSString.h" 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ObjectPrototype.h" 565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Operations.h" 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Parser.h" 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Profiler.h" 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegExpObject.h" 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegExpPrototype.h" 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Register.h" 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SamplingTool.h" 63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "StrictEvalActivation.h" 646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "UStringConcatenate.h" 650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <limits.h> 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h> 675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/Threading.h> 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "JIT.h" 71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 73bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(COMPUTED_GOTO_INTERPRETER) && !defined(__llvm__)) 74bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Returns the depth of the scope chain within a given call frame. 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic int depth(CodeBlock* codeBlock, ScopeChain& sc) 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!codeBlock->needsFullScopeChain()) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return sc.localDepth(); 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 87e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 88bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenstatic NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count) 89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen return jsString(exec, strings, count); 91bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 935f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 95cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 96cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* o = *iter; 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(o); 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->getPropertySlot(callFrame, ident, slot)) { 1095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = slot.getValue(callFrame, ident); 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = callFrame->globalData().exception; 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exceptionValue) 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (++iter != end); 1176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createUndefinedVariableError(callFrame, ident); 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1215f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 125cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 126cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 127e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int skip = vPC[3].u.operand; 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); 134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(skip || !checkTopLevel); 135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkTopLevel && skip--) { 1364576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) 137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++iter; 138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (skip--) { 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++iter; 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* o = *iter; 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(o); 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (o->getPropertySlot(callFrame, ident, slot)) { 1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = slot.getValue(callFrame, ident); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = callFrame->globalData().exception; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exceptionValue) 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 152a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(result); 1534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (++iter != end); 1576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createUndefinedVariableError(callFrame, ident); 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1615f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 164dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch CodeBlock* codeBlock = callFrame->codeBlock(); 165dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JSGlobalObject* globalObject = codeBlock->globalObject(); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(globalObject->isGlobalObject()); 167dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int property = vPC[2].u.operand; 168dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Structure* structure = vPC[3].u.structure; 169dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int offset = vPC[4].u.operand; 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (structure == globalObject->structure()) { 1724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(globalObject->getDirectOffset(offset)); 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(globalObject); 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (globalObject->getPropertySlot(callFrame, ident, slot)) { 1795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = slot.getValue(callFrame, ident); 180692e5dbf12901edacf14812a6fae25462920af42Steve Block if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { 181dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch if (vPC[3].u.structure) 182dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch vPC[3].u.structure->deref(); 183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project globalObject->structure()->ref(); 184dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch vPC[3] = globalObject->structure(); 185dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch vPC[4] = slot.cachedOffset(); 1864576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = callFrame->globalData().exception; 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exceptionValue) 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1934576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1976b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createUndefinedVariableError(callFrame, ident); 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenNEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) 2026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 2036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int dst = vPC[1].u.operand; 2046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen CodeBlock* codeBlock = callFrame->codeBlock(); 205dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JSGlobalObject* globalObject = codeBlock->globalObject(); 206dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch ASSERT(globalObject->isGlobalObject()); 207dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int property = vPC[2].u.operand; 208dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch Structure* structure = vPC[3].u.structure; 209dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int offset = vPC[4].u.operand; 210dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int skip = vPC[5].u.operand; 2116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ScopeChainNode* scopeChain = callFrame->scopeChain(); 2136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ScopeChainIterator iter = scopeChain->begin(); 2146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ScopeChainIterator end = scopeChain->end(); 2156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(iter != end); 216a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); 217a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(skip || !checkTopLevel); 218a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkTopLevel && skip--) { 2194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) 220a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++iter; 221a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen while (skip--) { 2236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen JSObject* o = *iter; 2246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (o->hasCustomProperties()) { 2256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Identifier& ident = codeBlock->identifier(property); 2266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen do { 2276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen PropertySlot slot(o); 2286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (o->getPropertySlot(callFrame, ident, slot)) { 2296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen JSValue result = slot.getValue(callFrame, ident); 2306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen exceptionValue = callFrame->globalData().exception; 2316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (exceptionValue) 2326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return false; 233a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(result); 2344576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 2356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return true; 2366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (iter == end) 2386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen break; 2396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen o = *iter; 2406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ++iter; 2416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } while (true); 2426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createUndefinedVariableError(callFrame, ident); 2436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return false; 2446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ++iter; 2466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (structure == globalObject->structure()) { 2494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(globalObject->getDirectOffset(offset)); 2504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(callFrame->uncheckedR(dst).jsValue()); 2516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return true; 2526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Identifier& ident = codeBlock->identifier(property); 2556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen PropertySlot slot(globalObject); 2566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (globalObject->getPropertySlot(callFrame, ident, slot)) { 2576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen JSValue result = slot.getValue(callFrame, ident); 2586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { 259dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch if (vPC[3].u.structure) 260dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch vPC[3].u.structure->deref(); 2616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen globalObject->structure()->ref(); 262dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch vPC[3] = globalObject->structure(); 263dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch vPC[4] = slot.cachedOffset(); 264a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(result); 2654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 2666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return true; 2676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen exceptionValue = callFrame->globalData().exception; 2706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (exceptionValue) 2716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return false; 272a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(result); 2734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(result); 2746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return true; 2756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 2776b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createUndefinedVariableError(callFrame, ident); 2786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen return false; 2796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 2806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC) 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 283cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 284cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 285a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool isStrictPut = vPC[3].u.operand; 286a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Identifier ident = callFrame->codeBlock()->identifier(property); 287a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue result = JSC::resolveBase(callFrame, ident, callFrame->scopeChain(), isStrictPut); 288e14391e94c850b8bd03680c23b38978db68687a8John Reck if (result) { 2894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(callFrame->uncheckedR(dst).jsValue()); 291a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else 292a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callFrame->globalData().exception = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring()); 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2955f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 297cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int baseDst = vPC[1].u.operand; 298cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int propDst = vPC[2].u.operand; 299cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: add scopeDepthIsZero optimization 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* base; 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project base = *iter; 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(base); 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (base->getPropertySlot(callFrame, ident, slot)) { 3165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = slot.getValue(callFrame, ident); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = callFrame->globalData().exception; 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (exceptionValue) 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 3204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(propDst) = JSValue(result); 3214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(baseDst) = JSValue(base); 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++iter; 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (iter != end); 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createUndefinedVariableError(callFrame, ident); 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 331e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif // ENABLE(INTERPRETER) 3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 333635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc) 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* r = callFrame->registers(); 336635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newEnd = r + registerOffset + newCodeBlock->m_numCalleeRegisters; 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(argc == newCodeBlock->m_numParameters)) { // correct number of arguments 3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!registerFile->grow(newEnd))) 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r += registerOffset; 342635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (argc < newCodeBlock->m_numParameters) { // too few arguments -- fill in the blanks 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project size_t omittedArgCount = newCodeBlock->m_numParameters - argc; 3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project registerOffset += omittedArgCount; 3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newEnd += omittedArgCount; 3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!registerFile->grow(newEnd)) 3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r += registerOffset; 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount; 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < omittedArgCount; ++i) 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project argv[i] = jsUndefined(); 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { // too many arguments -- copy expected arguments, leaving the extra arguments behind 354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project size_t numParameters = newCodeBlock->m_numParameters; 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project registerOffset += numParameters; 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newEnd += numParameters; 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!registerFile->grow(newEnd)) 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project r += registerOffset; 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argc; 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < numParameters; ++i) 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project argv[i + argc] = argv[i]; 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return CallFrame::create(r); 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 370e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 3716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, JSValue value, JSValue& exceptionData) 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (value.isObject()) 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 3756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionData = createInvalidParamError(callFrame, "in" , value); 3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return true; 3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 3785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, JSValue value, JSValue& exceptionData) 3805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (value.isObject() && asObject(value)->structure()->typeInfo().implementsHasInstance()) 3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return false; 3836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionData = createInvalidParamError(callFrame, "instanceof" , value); 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388e14391e94c850b8bd03680c23b38978db68687a8John ReckNEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset) 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (argc < 2) 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue program = argv[1].jsValue(); 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 395635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!program.isString()) 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return program; 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 398643ca7872b450ea4efacab6188849e5aac2ba161Steve Block UString programSource = asString(program)->value(callFrame); 399e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (callFrame->hadException()) 400e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return JSValue(); 401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CodeBlock* codeBlock = callFrame->codeBlock(); 403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock->isStrictMode()) { 404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // FIXME: We can use the preparser in strict mode, we just need additional logic 405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch // to prevent duplicates. 406a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON); 407a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (JSValue parsedObject = preparser.tryLiteralParse()) 408a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch return parsedObject; 409a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 410231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 412e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue exceptionValue; 413a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch RefPtr<EvalExecutable> eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue); 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 415e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(!eval == exceptionValue); 416e14391e94c850b8bd03680c23b38978db68687a8John Reck if (UNLIKELY(!eval)) 417e14391e94c850b8bd03680c23b38978db68687a8John Reck return throwError(callFrame, exceptionValue); 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->uncheckedR(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain); 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 422635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectInterpreter::Interpreter() 423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block : m_sampleEntryDepth(0) 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_reentryDepth(0) 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 426e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 427e14391e94c850b8bd03680c23b38978db68687a8John Reck privateExecute(InitializeAndReturn, 0, 0); 428d0825bca7fe65beaee391d30da42e937db621564Steve Block 429d0825bca7fe65beaee391d30da42e937db621564Steve Block for (int i = 0; i < numOpcodeIDs; ++i) 430d0825bca7fe65beaee391d30da42e937db621564Steve Block m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i)); 431e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif // ENABLE(COMPUTED_GOTO_INTERPRETER) 432d0825bca7fe65beaee391d30da42e937db621564Steve Block 433231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(OPCODE_SAMPLING) 434231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block enableSampler(); 435231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 436635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 438635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NDEBUG 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid Interpreter::dumpCallFrame(CallFrame* callFrame) 441635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project callFrame->codeBlock()->dump(callFrame); 443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project dumpRegisters(callFrame); 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid Interpreter::dumpRegisters(CallFrame* callFrame) 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project printf("Register frame: \n\n"); 4490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 4500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf(" use | address | value \n"); 4510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 454e14391e94c850b8bd03680c23b38978db68687a8John Reck RegisterFile* registerFile = &callFrame->scopeChain()->globalObject->globalData().interpreter->registerFile(); 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const Register* it; 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const Register* end; 4570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v; 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->codeType() == GlobalCode) { 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project it = registerFile->lastGlobal(); 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project end = it + registerFile->numGlobals(); 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (it != end) { 4630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch v = (*it).jsValue(); 4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(JSVALUE32_64) 4650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[global var] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); 4660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 4670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[global var] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); 4680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++it; 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->m_numParameters; 4750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch v = (*it).jsValue(); 4760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(JSVALUE32_64) 4770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[this] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it; 4780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 4790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[this] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it; 4800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project end = it + max(codeBlock->m_numParameters - 1, 0); // - 1 to skip "this" 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (it != end) { 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 4840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch v = (*it).jsValue(); 4850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(JSVALUE32_64) 4860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[param] | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); 4870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 4880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[param] | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); 4890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++it; 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (it != end); 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 4940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[CodeBlock] | %10p | %p \n", it, (*it).codeBlock()); ++it; 4950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[ScopeChain] | %10p | %p \n", it, (*it).scopeChain()); ++it; 4960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[CallerRegisters] | %10p | %d \n", it, (*it).i()); ++it; 4970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[ReturnPC] | %10p | %p \n", it, (*it).vPC()); ++it; 4980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[ArgumentCount] | %10p | %d \n", it, (*it).i()); ++it; 4990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[Callee] | %10p | %p \n", it, (*it).function()); ++it; 5000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int registerCount = 0; 5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 504635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project end = it + codeBlock->m_numVars; 5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (it != end) { 5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 5070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch v = (*it).jsValue(); 5080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(JSVALUE32_64) 5090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v)); 5100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 5110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v)); 5120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++it; 5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++registerCount; 5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (it != end); 5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars; 5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (it != end) { 5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { 5220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch v = (*it).jsValue(); 5230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(JSVALUE32_64) 5240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[r%2d] | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v)); 5250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 5260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("[r%2d] | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v)); 5270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++it; 5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++registerCount; 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (it != end); 5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch printf("-----------------------------------------------------------------------------\n"); 5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool Interpreter::isOpcode(Opcode opcode) 5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 539e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return opcode != HashTraits<Opcode>::emptyValue() 5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project && !HashTraits<Opcode>::isDeletedValue(opcode) 5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project && m_opcodeIDTable.contains(opcode); 5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return opcode >= 0 && opcode <= op_end; 5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5485f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock) 5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* oldCodeBlock = codeBlock; 5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) { 5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); 5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callFrame->callee()) 556231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine()); 5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 558231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine()); 5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If this call frame created an activation or an 'arguments' object, tear it off. 562635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) { 5634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue()) { 564a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch oldCodeBlock->createActivation(callFrame); 565a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain = callFrame->scopeChain(); 566a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 567231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block while (!scopeChain->object->inherits(&JSActivation::info)) 5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain = scopeChain->pop(); 569e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block JSActivation* activation = asActivation(scopeChain->object); 570e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block activation->copyRegisters(); 5714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) { 572a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!oldCodeBlock->isStrictMode()) 573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch asArguments(arguments)->setActivation(activation); 574a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 575a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) { 5764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) 577e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block asArguments(arguments)->copyRegisters(); 5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 580635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (oldCodeBlock->needsFullScopeChain()) 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->deref(); 5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 583e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CallFrame* callerFrame = callFrame->callerFrame(); 584e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (callerFrame->hasHostCallFrameFlag()) 5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 587e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callerFrame->codeBlock(); 588967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(JIT) && ENABLE(INTERPRETER) 589e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callerFrame->globalData().canUseJIT()) 5904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC()); 591e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 5924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()); 593967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#elif ENABLE(JIT) 5944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC()); 595e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#else 5964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()); 597e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 598967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 599e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block callFrame = callerFrame; 6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset) 6046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 6056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exception->clearAppendSourceToMessage(); 6066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!callFrame->codeBlock()->hasExpressionInfo()) 6084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return; 6094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int startOffset = 0; 6116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int endOffset = 0; 6126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int divotPoint = 0; 6136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CodeBlock* codeBlock = callFrame->codeBlock(); 6154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset); 6166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6176b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int expressionStart = divotPoint - startOffset; 6186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int expressionStop = divotPoint + endOffset; 6196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!expressionStop || expressionStart > codeBlock->source()->length()) 6216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 6226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSGlobalData* globalData = &callFrame->globalData(); 6246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSValue jsMessage = exception->getDirect(globalData->propertyNames->message); 6256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!jsMessage || !jsMessage.isString()) 6266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 6276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner UString message = asString(jsMessage)->value(callFrame); 6296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (expressionStart < expressionStop) 6316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner message = makeUString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')"); 6326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner else { 6336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // No range information, so give a few characters of context 6346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner const UChar* data = codeBlock->source()->data(); 6356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int dataLength = codeBlock->source()->length(); 6366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int start = expressionStart; 6376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int stop = expressionStart; 6386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Get up to 20 characters of context to the left and right of the divot, clamping to the line. 6396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // then strip whitespace. 6406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n') 6416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner start--; 6426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (start < (expressionStart - 1) && isStrWhiteSpace(data[start])) 6436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner start++; 6446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n') 6456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner stop++; 6466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (stop > expressionStart && isStrWhiteSpace(data[stop])) 6476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner stop--; 6486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner message = makeUString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')"); 6496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 6506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exception->putDirect(globalData->propertyNames->message, jsString(globalData, message)); 6526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 6536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangNEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset) 6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 6574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bool isInterrupt = false; 6584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Set up the exception object 660635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (exceptionValue.isObject()) { 6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* exception = asObject(exceptionValue); 6624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) 6646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset); 6656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6664576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Using hasExpressionInfo to imply we are interested in rich exception info. 6674576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) { 6684576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(codeBlock->hasLineInfo()); 6696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6704576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // FIXME: should only really be adding these properties to VM generated exceptions, 6714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // but the inspector currently requires these for all thrown objects. 6724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source()); 6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ComplType exceptionType = exception->exceptionType(); 6764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang isInterrupt = exceptionType == Interrupted || exceptionType == Terminated; 6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) { 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); 681d0825bca7fe65beaee391d30da42e937db621564Steve Block bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset); 6824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler); 6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Calculate an exception handler vPC, unwinding call frames as necessary. 686635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HandlerInfo* handler = 0; 6874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { 6884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) { 6894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (Profiler* profiler = *Profiler::enabledProfilerReference()) 6904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang profiler->exceptionUnwind(callFrame); 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (Profiler* profiler = *Profiler::enabledProfilerReference()) 6964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang profiler->exceptionUnwind(callFrame); 6974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Shrink the JS stack, in case stack overflow made it huge. 699e14391e94c850b8bd03680c23b38978db68687a8John Reck Register* highWaterMark = 0; 700e14391e94c850b8bd03680c23b38978db68687a8John Reck for (CallFrame* callerFrame = callFrame; callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) { 701a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CodeBlock* codeBlock = callerFrame->codeBlock(); 702a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock) 703a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch continue; 704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters; 705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch highWaterMark = max(highWaterMark, callerHighWaterMark); 706a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_registerFile.shrink(highWaterMark); 7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Unwind the scope chain within the exception handler's call frame. 710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 711635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ScopeChain sc(scopeChain); 712a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int scopeDelta = 0; 713a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode 7144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) 715a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeDelta = depth(codeBlock, sc) - handler->scopeDepth; 7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scopeDelta >= 0); 7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (scopeDelta--) 718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project scopeChain = scopeChain->pop(); 719635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project callFrame->setScopeChain(scopeChain); 7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return handler; 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 724e14391e94c850b8bd03680c23b38978db68687a8John Reckstatic inline JSValue checkedReturn(JSValue returnValue) 725e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 726e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(returnValue); 727e14391e94c850b8bd03680c23b38978db68687a8John Reck return returnValue; 728e14391e94c850b8bd03680c23b38978db68687a8John Reck} 729e14391e94c850b8bd03680c23b38978db68687a8John Reck 730e14391e94c850b8bd03680c23b38978db68687a8John Reckstatic inline JSObject* checkedReturn(JSObject* returnValue) 731e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 732e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(returnValue); 733e14391e94c850b8bd03680c23b38978db68687a8John Reck return returnValue; 734e14391e94c850b8bd03680c23b38978db68687a8John Reck} 735e14391e94c850b8bd03680c23b38978db68687a8John Reck 736e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj) 7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!scopeChain->globalData->exception); 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 740e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 741e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 743967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = program->compile(callFrame, scopeChain); 744e14391e94c850b8bd03680c23b38978db68687a8John Reck if (error) 745e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, error)); 746967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* codeBlock = &program->generatedBytecode(); 7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* oldEnd = m_registerFile.end(); 749635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; 750e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_registerFile.grow(newEnd)) 751e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSGlobalObject* lastGlobalObject = m_registerFile.globalObject(); 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSGlobalObject* globalObject = callFrame->dynamicGlobalObject(); 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project globalObject->copyGlobalsTo(m_registerFile); 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 757635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize); 7585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. 7595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->m_numParameters, 0); 7604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj); 7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 762635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->needsFullScopeChain()) 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->ref(); 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); 7665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** profiler = Profiler::enabledProfilerReference(); 7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 7694576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, program->sourceURL(), program->lineNo()); 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 773231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::CallRecord callRecord(m_sampler.get()); 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 775e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 776635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 777e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 778e14391e94c850b8bd03680c23b38978db68687a8John Reck result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData); 779e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 780e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 781e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 782e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reentryDepth--; 7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 787231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo()); 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject) 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastGlobalObject->copyGlobalsTo(m_registerFile); 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 794e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 797e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) 7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(!callFrame->hadException()); 8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 801e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 802e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* oldEnd = m_registerFile.end(); 8055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke int argCount = 1 + args.size(); // implicit "this" parameter 8065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; 8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 808e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_registerFile.grow(oldEnd + registerOffset)) 809e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(oldEnd); 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t dst = 0; 8134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(0) = thisValue; 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ArgList::const_iterator end = args.end(); 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (ArgList::const_iterator it = args.begin(); it != end; ++it) 8164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(++dst) = *it; 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (callType == CallTypeJS) { 8195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 8205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 821967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain); 822967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!compileError)) { 823967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_registerFile.shrink(oldEnd); 824e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 825967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 826967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 827967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); 828967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount); 8295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (UNLIKELY(!newCallFrame)) { 8305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_registerFile.shrink(oldEnd); 831e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 8335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function); 8355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DynamicGlobalObjectScope globalObjectScope(newCallFrame, callDataScopeChain->globalObject); 8375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Profiler** profiler = Profiler::enabledProfilerReference(); 8395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (*profiler) 8404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, function); 8415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSValue result; 8435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke { 8445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke SamplingTool::CallRecord callRecord(m_sampler.get()); 8455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 846e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 847e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 848e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 849e14391e94c850b8bd03680c23b38978db68687a8John Reck result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData); 850e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 851e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 852e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 8535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_reentryDepth--; 8545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 8555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (*profiler) 8574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, function); 8585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 860e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(callType == CallTypeHost); 8645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ScopeChainNode* scopeChain = callFrame->scopeChain(); 8655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset); 8665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function); 8675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject); 8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** profiler = Profiler::enabledProfilerReference(); 8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 8724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, function); 8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 8765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke SamplingTool::HostCallRecord callRecord(m_sampler.get()); 877545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch result = JSValue::decode(callData.native.function(newCallFrame)); 8786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 8796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 8806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (*profiler) 8814576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, function); 8826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 8836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_registerFile.shrink(oldEnd); 884e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 8856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 8866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 887e14391e94c850b8bd03680c23b38978db68687a8John ReckJSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args) 8886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 889545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(!callFrame->hadException()); 8906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 891e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 892e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 8946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Register* oldEnd = m_registerFile.end(); 895545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch int argCount = 1 + args.size(); // implicit "this" parameter 896545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; 8976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 898e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_registerFile.grow(oldEnd + registerOffset)) 899e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 9006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 9016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen CallFrame* newCallFrame = CallFrame::create(oldEnd); 9026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen size_t dst = 0; 9036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ArgList::const_iterator end = args.end(); 9046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen for (ArgList::const_iterator it = args.begin(); it != end; ++it) 9054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(++dst) = *it; 9066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 907545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (constructType == ConstructTypeJS) { 908545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ScopeChainNode* constructDataScopeChain = constructData.js.scopeChain; 909545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 910967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain); 911967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!compileError)) { 912967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_registerFile.shrink(oldEnd); 913e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 914967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 915967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 916967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct(); 917967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount); 918545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (UNLIKELY(!newCallFrame)) { 919545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch m_registerFile.shrink(oldEnd); 920e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 921545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 922545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 923545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor); 924545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 925545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch DynamicGlobalObjectScope globalObjectScope(newCallFrame, constructDataScopeChain->globalObject); 926545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 927545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch Profiler** profiler = Profiler::enabledProfilerReference(); 928545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (*profiler) 9294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, constructor); 930545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 931545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSValue result; 932545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch { 933545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch SamplingTool::CallRecord callRecord(m_sampler.get()); 934545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 935e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 936e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 937e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 938e14391e94c850b8bd03680c23b38978db68687a8John Reck result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData); 939e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 940e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 941e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 942545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch m_reentryDepth--; 943545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 944545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 945545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (*profiler) 9464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, constructor); 947545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 9486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_registerFile.shrink(oldEnd); 949545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (callFrame->hadException()) 950545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 951545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(result.isObject()); 952e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(asObject(result)); 9536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 9545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 955545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(constructType == ConstructTypeHost); 956545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ScopeChainNode* scopeChain = callFrame->scopeChain(); 957545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset); 958545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor); 959545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 960545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject); 9616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 9626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Profiler** profiler = Profiler::enabledProfilerReference(); 9636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (*profiler) 9644576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, constructor); 9656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 9666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen JSValue result; 9676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen { 968545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch SamplingTool::HostCallRecord callRecord(m_sampler.get()); 969545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch result = JSValue::decode(constructData.native.function(newCallFrame)); 9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 9734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, constructor); 9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 976545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (callFrame->hadException()) 977545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 978545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(result.isObject()); 979e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(asObject(result)); 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 982e14391e94c850b8bd03680c23b38978db68687a8John ReckCallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain) 9835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 9845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!scopeChain->globalData->exception); 9855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 986dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_reentryDepth >= MaxSmallThreadReentryDepth) { 987dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) { 988e14391e94c850b8bd03680c23b38978db68687a8John Reck throwStackOverflowError(callFrame); 9895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return CallFrameClosure(); 9905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* oldEnd = m_registerFile.end(); 9945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int argc = 1 + argCount; // implicit "this" parameter 9955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!m_registerFile.grow(oldEnd + argc)) { 997e14391e94c850b8bd03680c23b38978db68687a8John Reck throwStackOverflowError(callFrame); 9985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return CallFrameClosure(); 9995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallFrame* newCallFrame = CallFrame::create(oldEnd); 10025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t dst = 0; 10035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (int i = 0; i < argc; ++i) 10044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(++dst) = jsUndefined(); 10055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1006967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = FunctionExecutable->compileForCall(callFrame, scopeChain); 1007967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (error) { 1008e14391e94c850b8bd03680c23b38978db68687a8John Reck throwError(callFrame, error); 1009967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_registerFile.shrink(oldEnd); 1010967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return CallFrameClosure(); 1011967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 1012967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* codeBlock = &FunctionExecutable->generatedBytecodeForCall(); 1013967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 1014967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); 10155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (UNLIKELY(!newCallFrame)) { 1016e14391e94c850b8bd03680c23b38978db68687a8John Reck throwStackOverflowError(callFrame); 10175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_registerFile.shrink(oldEnd); 10185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return CallFrameClosure(); 10195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 1020e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function); 1021231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc }; 10225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return result; 10235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 10245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1025e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(CallFrameClosure& closure) 10265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 10275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian closure.resetCallFrame(); 10285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Profiler** profiler = Profiler::enabledProfilerReference(); 10295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (*profiler) 10305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian (*profiler)->willExecute(closure.oldCallFrame, closure.function); 10315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 10335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1034231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::CallRecord callRecord(m_sampler.get()); 10355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1036e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 10375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(JIT) 1038e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1039e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (closure.newCallFrame->globalData().canUseJIT()) 1040e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1041e14391e94c850b8bd03680c23b38978db68687a8John Reck result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData); 1042e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1043e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 1044e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1045e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1046e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1047e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, closure.newCallFrame); 10485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 10495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_reentryDepth--; 10505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (*profiler) 10535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian (*profiler)->didExecute(closure.oldCallFrame, closure.function); 1054e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 10555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 10565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Interpreter::endRepeatCall(CallFrameClosure& closure) 10585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 10595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_registerFile.shrink(closure.oldEnd); 10605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 10615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1062e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain) 10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1064967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = eval->compile(callFrame, scopeChain); 1065e14391e94c850b8bd03680c23b38978db68687a8John Reck if (UNLIKELY(!!compileError)) 1066e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 1067e14391e94c850b8bd03680c23b38978db68687a8John Reck return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->generatedBytecode().m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain); 10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1070e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain) 10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!scopeChain->globalData->exception); 10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1074e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 1075e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1077643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); 10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1079967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = eval->compile(callFrame, scopeChain); 1080e14391e94c850b8bd03680c23b38978db68687a8John Reck if (UNLIKELY(!!compileError)) 1081e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 1082967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch EvalCodeBlock* codeBlock = &eval->generatedBytecode(); 10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1084a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSObject* variableObject; 10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (ScopeChainNode* node = scopeChain; ; node = node->next) { 10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node); 10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->object->isVariableObject()) { 10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project variableObject = static_cast<JSVariableObject*>(node->object); 10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen unsigned numVariables = codeBlock->numVariables(); 10946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int numFunctions = codeBlock->numberOfFunctionDecls(); 1095a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool pushedScope = false; 10966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (numVariables || numFunctions) { 1097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (codeBlock->isStrictMode()) { 1098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch variableObject = new (callFrame) StrictEvalActivation(callFrame); 1099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain = scopeChain->push(variableObject); 1100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch pushedScope = true; 1101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 11026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // Scope for BatchedTransitionOptimizer 11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project BatchedTransitionOptimizer optimizer(variableObject); 11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 0; i < numVariables; ++i) { 1106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const Identifier& ident = codeBlock->variable(i); 11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!variableObject->hasProperty(callFrame, ident)) { 11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project variableObject->put(callFrame, ident, jsUndefined(), slot); 11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (int i = 0; i < numFunctions; ++i) { 1114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionExecutable* function = codeBlock->functionDecl(i); 11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 1116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot); 11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* oldEnd = m_registerFile.end(); 1121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->m_numCalleeRegisters; 11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_registerFile.grow(newEnd)) { 1123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (pushedScope) 1124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain->pop(); 1125e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset); 11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. 11315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->m_numParameters, 0); 11324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj); 11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->needsFullScopeChain()) 11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->ref(); 11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** profiler = Profiler::enabledProfilerReference(); 11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 11394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, eval->sourceURL(), eval->lineNo()); 11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::CallRecord callRecord(m_sampler.get()); 11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reentryDepth++; 1146e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1149e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 1150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1151e14391e94c850b8bd03680c23b38978db68687a8John Reck result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData); 1152e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1153e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 1154e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1155e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1156e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1157e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reentryDepth--; 11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 1163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo()); 11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 1166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (pushedScope) 1167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain->pop(); 1168e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine) 11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Debugger* debugger = callFrame->dynamicGlobalObject()->debugger(); 11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!debugger) 11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (debugHookID) { 11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case DidEnterCallFrame: 1179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); 11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WillLeaveCallFrame: 1182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); 11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WillExecuteStatement: 1185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); 11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WillExecuteProgram: 1188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); 11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case DidExecuteProgram: 1191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); 11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case DidReachBreakpoint: 1194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); 11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1199e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC) 12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1202cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 1204cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Identifier& property = codeBlock->identifier(vPC[2].u.operand); 1205cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue value = callFrame->r(vPC[3].u.operand).jsValue(); 12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete); 12074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(scope); 12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return callFrame->scopeChain()->push(scope); 12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12125f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot) 12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Recursive invocation may already have specialized this instruction. 12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vPC[0].u.opcode != getOpcode(op_put_by_id)) 12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1218635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!baseValue.isCell()) 12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Uncacheable: give up. 12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!slot.isCacheable()) { 12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1227e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 1228635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = baseCell->structure(); 12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (structure->isUncacheableDictionary()) { 12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1235635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache miss: record Structure to compare against next time. 1236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* lastStructure = vPC[4].u.structure; 1237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (structure != lastStructure) { 1238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // First miss: record Structure to compare against next time. 1239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!lastStructure) { 1240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure; 12418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Second miss: give up. 12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1249635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache hit: Specialize instruction and ref Structures. 12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If baseCell != slot.base(), then baseCell must be a proxy for another object. 12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (baseCell != slot.base()) { 12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1257635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Structure transition, cache transition info 12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (slot.type() == PutPropertySlot::NewProperty) { 1259231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (structure->isDictionary()) { 1260231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block vPC[0] = getOpcode(op_put_by_id_generic); 1261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 1262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1263cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1264cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // put_by_id_transition checks the prototype chain for setters. 1265cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block normalizePrototypeChain(callFrame, baseCell); 1266cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 12678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_transition); 1268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure->previousID(); 1269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[5] = structure; 1270cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC[6] = structure->prototypeChain(callFrame); 12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[7] = slot.cachedOffset(); 1272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_replace); 12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[5] = slot.cachedOffset(); 1278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::uncachePutByID(CodeBlock* codeBlock, Instruction* vPC) 12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->derefStructures(vPC); 12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id); 12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[4] = 0; 12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12885f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot) 12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Recursive invocation may already have specialized this instruction. 12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vPC[0].u.opcode != getOpcode(op_get_by_id)) 12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Cache property access for immediates. 1295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!baseValue.isCell()) { 12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JSGlobalData* globalData = &callFrame->globalData(); 13018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) { 13028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_array_length); 13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) { 13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_string_length); 13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Uncacheable: give up. 13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!slot.isCacheable()) { 13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1317e14391e94c850b8bd03680c23b38978db68687a8John Reck Structure* structure = baseValue.asCell()->structure(); 13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1319231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (structure->isUncacheableDictionary()) { 13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cache miss 1325635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* lastStructure = vPC[4].u.structure; 1326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (structure != lastStructure) { 1327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // First miss: record Structure to compare against next time. 1328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!lastStructure) { 1329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure; 13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Second miss: give up. 13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1338635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache hit: Specialize instruction and ref Structures. 13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (slot.slotBase() == baseValue) { 1341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (slot.cachedPropertyType()) { 1342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Getter: 1343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_getter_self); 1344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[5] = slot.cachedOffset(); 1345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Custom: 1347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_custom_self); 1348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[5] = slot.customGetter(); 1349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 1351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_self); 1352dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[5] = slot.cachedOffset(); 1353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1360643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (structure->isDictionary()) { 1361643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC[0] = getOpcode(op_get_by_id_generic); 1362643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 1363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1364643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1365635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (slot.slotBase() == structure->prototypeForLookup(callFrame)) { 1366635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(slot.slotBase().isObject()); 13678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(slot.slotBase()); 1369d0825bca7fe65beaee391d30da42e937db621564Steve Block size_t offset = slot.cachedOffset(); 13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Since we're accessing a prototype in a loop, it's a good bet that it 1372635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // should not be treated as a dictionary. 1373d0825bca7fe65beaee391d30da42e937db621564Steve Block if (baseObject->structure()->isDictionary()) { 1374643ca7872b450ea4efacab6188849e5aac2ba161Steve Block baseObject->flattenDictionaryObject(); 1375d0825bca7fe65beaee391d30da42e937db621564Steve Block offset = baseObject->structure()->get(propertyName); 1376d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1377643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1378643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(!baseObject->structure()->isUncacheableDictionary()); 1379dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1380dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (slot.cachedPropertyType()) { 1381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Getter: 1382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_getter_proto); 1383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[6] = offset; 1384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Custom: 1386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_custom_proto); 1387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[6] = slot.customGetter(); 1388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 1390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_proto); 1391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[6] = offset; 1392dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1393dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1394635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[5] = baseObject->structure(); 13958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1400d0825bca7fe65beaee391d30da42e937db621564Steve Block size_t offset = slot.cachedOffset(); 1401d0825bca7fe65beaee391d30da42e937db621564Steve Block size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); 1402635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!count) { 1403635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 1404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 14058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1407dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1408dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (slot.cachedPropertyType()) { 1409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Getter: 1410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_getter_chain); 1411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[7] = offset; 1412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Custom: 1414dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_custom_chain); 1415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[7] = slot.customGetter(); 1416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 1418dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_chain); 1419dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[7] = offset; 1420dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1421dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1422635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure; 1423cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC[5] = structure->prototypeChain(callFrame); 14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[6] = count; 1425635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1428635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction* vPC) 14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->derefStructures(vPC); 14318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id); 14328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[4] = 0; 14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1435e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif // ENABLE(INTERPRETER) 14365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1437e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame) 14388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // One-time initialization of our address tables. We have to put this code 14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // here because our labels are only in scope inside this function. 1441d0825bca7fe65beaee391d30da42e937db621564Steve Block if (UNLIKELY(flag == InitializeAndReturn)) { 1442e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke #if ENABLE(COMPUTED_GOTO_INTERPRETER) 1443d0825bca7fe65beaee391d30da42e937db621564Steve Block #define LIST_OPCODE_LABEL(id, length) &&id, 1444d0825bca7fe65beaee391d30da42e937db621564Steve Block static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) }; 1445e14391e94c850b8bd03680c23b38978db68687a8John Reck for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i) 1446d0825bca7fe65beaee391d30da42e937db621564Steve Block m_opcodeTable[i] = labels[i]; 1447d0825bca7fe65beaee391d30da42e937db621564Steve Block #undef LIST_OPCODE_LABEL 1448e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke #endif // ENABLE(COMPUTED_GOTO_INTERPRETER) 14495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return JSValue(); 14508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1451e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1452635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1453e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 14540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Mixing Interpreter + JIT is not supported. 1455e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 1456e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1457e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT_NOT_REACHED(); 14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1459e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1460e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if !ENABLE(INTERPRETER) 14615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UNUSED_PARAM(registerFile); 14625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UNUSED_PARAM(callFrame); 14635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return JSValue(); 14645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else 14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSGlobalData* globalData = &callFrame->globalData(); 14675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue exceptionValue; 1468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HandlerInfo* handler = 0; 14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1470e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CodeBlock* codeBlock = callFrame->codeBlock(); 1471e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Instruction* vPC = codeBlock->instructions().begin(); 14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** enabledProfilerReference = Profiler::enabledProfilerReference(); 14738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); 1474e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block JSValue functionReturnValue; 14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define CHECK_FOR_EXCEPTION() \ 14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { \ 14785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (UNLIKELY(globalData->exception != JSValue())) { \ 14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = globalData->exception; \ 14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; \ 14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } \ 14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (0) 14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 14858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define CHECK_FOR_TIMEOUT() \ 14898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!--tickCount) { \ 1490dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \ 1491635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project exceptionValue = jsNull(); \ 14928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; \ 1493635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } \ 14948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \ 14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_SAMPLING) 14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC) 14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #define SAMPLE(codeBlock, vPC) 15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1503e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 1504e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto *vPC->u.opcode 15058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 1506635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode); 15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1508635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) opcode: 15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1510635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1512e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto interpreterLoopStart 15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 1514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode); 15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) case opcode: 15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (1) { // iterator loop begins 15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project interpreterLoopStart:; 15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (vPC->u.opcode) 15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1523635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_object) { 15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_object dst(r) 15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new empty Object instance using the original 15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, and puts the result in register dst. 15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1529cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 15304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(constructEmptyObject(callFrame)); 15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1532cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_object); 1533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_array) { 15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_array dst(r) firstArg(r) argCount(n) 15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new Array instance using the original 15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, and puts the result in register dst. 15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project The array will contain argCount elements with values 15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project taken from registers starting at register firstArg. 15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1543cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1544cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int firstArg = vPC[2].u.operand; 1545cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int argCount = vPC[3].u.operand; 15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ArgList args(callFrame->registers() + firstArg, argCount); 15474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, args)); 15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1549cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_array); 1550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen DEFINE_OPCODE(op_new_regexp) { 15536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen /* new_regexp dst(r) regExp(re) 15546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 15556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Constructs a new RegExp instance using the original 15566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen constructor from regexp regExp, and puts the result in 15576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen register dst. 15586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen */ 15596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int dst = vPC[1].u.operand; 15606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int regExp = vPC[2].u.operand; 15614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(new (globalData) RegExpObject(callFrame->lexicalGlobalObject(), callFrame->scopeChain()->globalObject->regExpStructure(), codeBlock->regexp(regExp))); 15626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 15636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen vPC += OPCODE_LENGTH(op_new_regexp); 15646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen NEXT_INSTRUCTION(); 15656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_mov) { 15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* mov dst(r) src(r) 15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Copies register src to register dst. 15708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1571cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1572cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 1573a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 15744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(src); 15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1576cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mov); 1577635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1579635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_eq) { 15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* eq dst(r) src1(r) src2(r) 15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are equal, 15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project as with the ECMAScript '==' operator, and puts the result 15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project as a boolean in register dst. 15858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1586cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1587cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1588cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 15890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 15904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() == src2.asInt32()); 15918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 15925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2)); 1593635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 15944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 15958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1597cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_eq); 1598635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1600635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_eq_null) { 16018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* eq_null dst(r) src(r) 16028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src is null, as with the ECMAScript '!=' 16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project operator, and puts the result as a boolean in register dst. 16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1606cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1607cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 16088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1609635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (src.isUndefinedOrNull()) { 16104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(true); 1611cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_eq_null); 1612635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); 1616cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_eq_null); 1617635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1619635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_neq) { 16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* neq dst(r) src1(r) src2(r) 16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are not 16238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal, as with the ECMAScript '!=' operator, and puts the 16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result as a boolean in register dst. 16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1626cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1627cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1628cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 16290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 16304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() != src2.asInt32()); 16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 16325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2)); 1633635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 16344576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 16358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1637cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_neq); 1638635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1640635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_neq_null) { 16418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* neq_null dst(r) src(r) 16428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src is not null, as with the ECMAScript '!=' 16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project operator, and puts the result as a boolean in register dst. 16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1646cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1647cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1649635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (src.isUndefinedOrNull()) { 16504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(false); 1651cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_neq_null); 1652635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); 1656cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_neq_null); 1657635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1659635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_stricteq) { 16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* stricteq dst(r) src1(r) src2(r) 16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are strictly 16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal, as with the ECMAScript '===' operator, and puts the 16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result as a boolean in register dst. 16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1666cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1667cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1668cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1669e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bool result = JSValue::strictEqual(callFrame, src1, src2); 1670e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CHECK_FOR_EXCEPTION(); 16714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1673cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_stricteq); 1674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_nstricteq) { 16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* nstricteq dst(r) src1(r) src2(r) 16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are not 16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project strictly equal, as with the ECMAScript '!==' operator, and 16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result as a boolean in register dst. 16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1683cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1684cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1685cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1686e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bool result = !JSValue::strictEqual(callFrame, src1, src2); 1687e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CHECK_FOR_EXCEPTION(); 16884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1690cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_nstricteq); 1691635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1693635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_less) { 16948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* less dst(r) src1(r) src2(r) 16958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than register src2, as 16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project with the ECMAScript '<' operator, and puts the result as 16988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a boolean in register dst. 16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1700cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1701cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1702cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 17035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(jsLess(callFrame, src1, src2)); 1704635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 17068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1707cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_less); 1708635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_lesseq) { 17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* lesseq dst(r) src1(r) src2(r) 17128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than or equal to 17148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register src2, as with the ECMAScript '<=' operator, and 17158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result as a boolean in register dst. 17168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1717cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1718cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1719cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 17205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2)); 1721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17224576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 17238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1724cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_lesseq); 1725635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_pre_inc) { 17288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* pre_inc srcDst(r) 17298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number, adds one, and puts the result 17318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back in register srcDst. 17328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1733cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[1].u.operand; 17340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() < INT_MAX) 17364576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1); 17378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1738e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(v.toNumber(callFrame) + 1); 1739635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = result; 17418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1743cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_pre_inc); 1744635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1746635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_pre_dec) { 17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* pre_dec srcDst(r) 17488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number, subtracts one, and puts the result 17508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back in register srcDst. 17518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1752cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[1].u.operand; 17530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() > INT_MIN) 17554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1); 17568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1757e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(v.toNumber(callFrame) - 1); 1758635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = result; 17608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1762cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_pre_dec); 1763635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1765635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_post_inc) { 17668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* post_inc dst(r) srcDst(r) 17678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number. The number itself is 17698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project written to register dst, and the number plus one is written 17708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back to register srcDst. 17718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1772cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1773cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[2].u.operand; 17740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() < INT_MAX) { 17764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1); 17774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = v; 17788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 17790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); 1780635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17814576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(number.uncheckedGetNumber() + 1); 17824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = number; 17838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1785cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_post_inc); 1786635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_post_dec) { 17898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* post_dec dst(r) srcDst(r) 17908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number. The number itself is 17928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project written to register dst, and the number minus one is written 17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back to register srcDst. 17948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1795cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1796cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[2].u.operand; 17970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() > INT_MIN) { 17994576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1); 18004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = v; 18018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 18020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); 1803635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(number.uncheckedGetNumber() - 1); 18054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = number; 18068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1808cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_post_dec); 1809635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1811635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_to_jsnumber) { 18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* to_jsnumber dst(r) src(r) 18138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register src to number, and puts the result 18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1817cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1818cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 18198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcVal = callFrame->r(src).jsValue(); 18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1822635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(srcVal.isNumber())) 18234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(src); 18248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 18255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = srcVal.toJSNumber(callFrame); 1826635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18274576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1830cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_to_jsnumber); 1831635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1833635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_negate) { 18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* negate dst(r) src(r) 18358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register src to number, negates it, and puts the 18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result in register dst. 18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1839cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1840cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 1841dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow 18424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(-src.asInt32()); 18438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1844e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(-src.toNumber(callFrame)); 1845635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1849cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_negate); 1850635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1852635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_add) { 18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* add dst(r) src1(r) src2(r) 18548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Adds register src1 and register src2, and puts the result 18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. (JS add may be string concatenation or 18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project numeric add, depending on the types of the operands.) 18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1859cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1860cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1861cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1862643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow 18634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() + src2.asInt32()); 18648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 18655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsAdd(callFrame, src1, src2); 1866635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18674576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1869cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_add); 1870635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1872635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_mul) { 18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* mul dst(r) src1(r) src2(r) 18748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Multiplies register src1 and register src2 (converted to 18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project numbers), and puts the product in register dst. 18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1878cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1879cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1880cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 18810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow 18824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() * src2.asInt32()); 18838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1884e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame)); 1885635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18864576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1889cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mul); 1890635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1892635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_div) { 18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* div dst(r) dividend(r) divisor(r) 18948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Divides register dividend (converted to number) by the 18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register divisor (converted to number), and puts the 18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project quotient in register dst. 18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1899cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1900cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); 1901cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); 19020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1903e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); 19040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CHECK_FOR_EXCEPTION(); 19054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1907cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_div); 1908635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1910635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_mod) { 19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* mod dst(r) dividend(r) divisor(r) 19128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Divides register dividend (converted to number) by 19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register divisor (converted to number), and puts the 19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project remainder in register dst. 19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1917cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1918cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); 1919cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); 19208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) { 1922e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32()); 1923635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(result); 19244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 1925cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mod); 1926635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Conversion to double must happen outside the call to fmod since the 19300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // order of argument evaluation is not guaranteed. 19310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch double d1 = dividend.toNumber(callFrame); 19320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch double d2 = divisor.toNumber(callFrame); 1933e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(fmod(d1, d2)); 1934635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 1936cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mod); 1937635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1939635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_sub) { 19408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* sub dst(r) src1(r) src2(r) 19418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Subtracts register src2 (converted to number) from register 19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src1 (converted to number), and puts the difference in 19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register dst. 19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1946cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1947cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1948cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1949643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow 19504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() - src2.asInt32()); 19518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1952e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame)); 1953635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1956cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_sub); 1957635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1959635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_lshift) { 19608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* lshift dst(r) val(r) shift(r) 19618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs left shift of register val (converted to int32) by 19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register shift (converted to uint32), and puts the result 19648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1966cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1967cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); 1968cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); 19690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 19700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (val.isInt32() && shift.isInt32()) 19714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f)); 19728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1973e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); 1974635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1978cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_lshift); 1979635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1981635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_rshift) { 19828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* rshift dst(r) val(r) shift(r) 19838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs arithmetic right shift of register val (converted 19858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to int32) by register shift (converted to 19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32), and puts the result in register dst. 19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1988cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1989cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); 1990cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); 19910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 19920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (val.isInt32() && shift.isInt32()) 19934576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f)); 19948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1995e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); 1996635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2000cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_rshift); 2001635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2003635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_urshift) { 20048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* rshift dst(r) val(r) shift(r) 20058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs logical right shift of register val (converted 20078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to uint32) by register shift (converted to 20088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32), and puts the result in register dst. 20098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2010cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2011cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); 2012cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); 20130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (val.isUInt32() && shift.isInt32()) 20144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f)); 20158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2016e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); 2017635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2021cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_urshift); 2022635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2024635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitand) { 20258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitand dst(r) src1(r) src2(r) 20268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise AND of register src1 (converted to int32) 20288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and register src2 (converted to int32), and puts the result 20298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 20308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2031cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2032cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 2033cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 20340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 20354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() & src2.asInt32()); 20368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2037e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame)); 2038635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2042cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitand); 2043635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2045635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitxor) { 20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitxor dst(r) src1(r) src2(r) 20478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise XOR of register src1 (converted to int32) 20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and register src2 (converted to int32), and puts the result 20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 20518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2052cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2053cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 2054cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 20550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 20564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() ^ src2.asInt32()); 20578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2058e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame)); 2059635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2063cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitxor); 2064635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2066635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitor) { 20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitor dst(r) src1(r) src2(r) 20688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise OR of register src1 (converted to int32) 20708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and register src2 (converted to int32), and puts the 20718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result in register dst. 20728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2073cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2074cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 2075cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 20760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 20774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() | src2.asInt32()); 20788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2079e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame)); 2080635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20814576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2084cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitor); 2085635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2087635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitnot) { 20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitnot dst(r) src(r) 20898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise NOT of register src1 (converted to int32), 20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and puts the result in register dst. 20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2093cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2094cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 20950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src.isInt32()) 20964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(~src.asInt32()); 20978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2098e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(~src.toInt32(callFrame)); 2099635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 21004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 21018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2102cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitnot); 2103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2105635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_not) { 21068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* not dst(r) src(r) 21078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes logical NOT of register src (converted to 21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boolean), and puts the result in register dst. 21108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2111cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2112cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 21130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame)); 2114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 21154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 21168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2117cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_not); 2118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner DEFINE_OPCODE(op_check_has_instance) { 21216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner /* check_has_instance constructor(r) 21226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 21236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Check 'constructor' is an object with the internal property 21246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner [HasInstance] (i.e. is a function ... *shakes head sadly at 21256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSC API*). Raises an exception if register constructor is not 21266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner an valid parameter for instanceof. 21276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner */ 21286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int base = vPC[1].u.operand; 21296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSValue baseVal = callFrame->r(base).jsValue(); 21306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 21316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue)) 21326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner goto vm_throw; 21336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 21346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner vPC += OPCODE_LENGTH(op_check_has_instance); 21356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner NEXT_INSTRUCTION(); 21366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_instanceof) { 21388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* instanceof dst(r) value(r) constructor(r) constructorProto(r) 21398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Tests whether register value is an instance of register 21418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, and puts the boolean result in register 21428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst. Register constructorProto must contain the "prototype" 21438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property (not the actual prototype) of the object in 21448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register constructor. This lookup is separated so that 21458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project polymorphic inline caching can apply. 21468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Raises an exception if register constructor is not an 21488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object. 21498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 21518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[2].u.operand; 21528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[3].u.operand; 21538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int baseProto = vPC[4].u.operand; 21548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseVal = callFrame->r(base).jsValue(); 21568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue)); 21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool result = asObject(baseVal)->hasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue()); 21605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 21614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 21628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_instanceof); 2164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_typeof) { 21678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* typeof dst(r) src(r) 21688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines the type string for src according to ECMAScript 21708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rules, and puts the result in register dst. 21718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2172cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2173cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 21744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue())); 21758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_typeof); 2177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_undefined) { 21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_undefined dst(r) src(r) 21818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "undefined", and puts the result 21848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 21880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(src).jsValue(); 21894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()); 21908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2191cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_undefined); 2192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_boolean) { 21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_boolean dst(r) src(r) 21968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "boolean", and puts the result 21998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2201cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2202cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean()); 22048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2205cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_boolean); 2206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_number) { 22098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_number dst(r) src(r) 22108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "number", and puts the result 22138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2215cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2216cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber()); 22188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2219cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_number); 2220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_string) { 22238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_string dst(r) src(r) 22248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "string", and puts the result 22278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2229cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2230cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isString()); 22328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2233cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_string); 2234635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_object) { 22378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_object dst(r) src(r) 22388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "object", and puts the result 22418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2243cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2244cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue())); 22468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2247cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_object); 2248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_function) { 22518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_function dst(r) src(r) 22528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "function", and puts the result 22558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2257cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2258cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue())); 22608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2261cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_function); 2262635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_in) { 22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* in dst(r) property(r) base(r) 22668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Tests whether register base has a property named register 22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property, and puts the boolean result in register dst. 22698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Raises an exception if register constructor is not an 22718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object. 22728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2273cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2274cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 2275cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[3].u.operand; 22768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseVal = callFrame->r(base).jsValue(); 22786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (isInvalidParamForIn(callFrame, baseVal, exceptionValue)) 22798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 22808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObj = asObject(baseVal); 22828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue propName = callFrame->r(property).jsValue(); 22848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32_t i; 2286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (propName.getUInt32(i)) 22874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i)); 22888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, propName.toString(callFrame)); 2290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 22914576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property)); 22928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2294cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_in); 2295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve) { 22988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve dst(r) property(id) 22998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Looks up the property named by identifier property in the 23018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scope chain, and writes the resulting value to register 23028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst. If the property is not found, raises an exception. 23038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 23048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue))) 23058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 23068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2307cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve); 2308635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_skip) { 23118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve_skip dst(r) property(id) skip(n) 23128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Looks up the property named by identifier property in the 23148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scope chain skipping the top 'skip' levels, and writes the resulting 23158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value to register dst. If the property is not found, raises an exception. 23168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 23178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue))) 23188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 23198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2320cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_skip); 23218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2322635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_global) { 2325635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n) 23268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a dynamic property lookup for the given property, on the provided 2328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project global object. If structure matches the Structure of the global then perform 23298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a fast lookup using the case offset, otherwise fall back to a full resolve and 2330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cache the new structure and offset 23318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 23328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue))) 23338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 23348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2335cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_global); 23368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen DEFINE_OPCODE(op_resolve_global_dynamic) { 23406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n) 23416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Performs a dynamic property lookup for the given property, on the provided 23436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen global object. If structure matches the Structure of the global then perform 23446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen a fast lookup using the case offset, otherwise fall back to a full resolve and 23456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen cache the new structure and offset. 23466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen This walks through n levels of the scope chain to verify that none of those levels 23486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen in the scope chain include dynamically added properties. 23496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen */ 23506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (UNLIKELY(!resolveGlobalDynamic(callFrame, vPC, exceptionValue))) 23516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen goto vm_throw; 23526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen vPC += OPCODE_LENGTH(op_resolve_global_dynamic); 23546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen NEXT_INSTRUCTION(); 23566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2357635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_global_var) { 23588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* get_global_var dst(r) globalObject(c) index(n) 23598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Gets the global var at global slot index and places it in register dst. 23618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2362cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2363dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JSGlobalObject* scope = codeBlock->globalObject(); 23648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->isGlobalObject()); 2365dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int index = vPC[2].u.operand; 23668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23674576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = scope->registerAt(index); 2368cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_global_var); 2369635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_global_var) { 23728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_global_var globalObject(c) index(n) value(r) 23738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Puts value into global slot index. 23758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2376dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JSGlobalObject* scope = codeBlock->globalObject(); 23778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->isGlobalObject()); 2378dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int index = vPC[1].u.operand; 2379dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int value = vPC[2].u.operand; 23808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); 2382cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_global_var); 2383635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2385635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_scoped_var) { 23868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* get_scoped_var dst(r) index(n) skip(n) 23878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Loads the contents of the index-th local from the scope skip nodes from 2389e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block the top of the scope chain, and places it in register dst. 23908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2391cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2392cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int index = vPC[2].u.operand; 2393e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int skip = vPC[3].u.operand; 23948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 23968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 23978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 23988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 2399a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock == callFrame->codeBlock()); 2400a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); 2401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(skip || !checkTopLevel); 2402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkTopLevel && skip--) { 2403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (callFrame->r(codeBlock->activationRegister()).jsValue()) 2404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++iter; 2405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 24068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (skip--) { 24078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++iter; 24088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 24098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT((*iter)->isVariableObject()); 24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); 24124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = scope->registerAt(index); 2413a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(callFrame->r(dst).jsValue()); 2414cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_scoped_var); 2415635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_scoped_var) { 24188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_scoped_var index(n) skip(n) value(r) 24198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2421cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int index = vPC[1].u.operand; 2422e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int skip = vPC[2].u.operand; 2423cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int value = vPC[3].u.operand; 24248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 24268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 24278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 2428a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock == callFrame->codeBlock()); 24298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 2430a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); 2431a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(skip || !checkTopLevel); 2432a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkTopLevel && skip--) { 2433a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (callFrame->r(codeBlock->activationRegister()).jsValue()) 2434a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++iter; 2435a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 24368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (skip--) { 24378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++iter; 24388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 24398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT((*iter)->isVariableObject()); 24428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); 2443a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(callFrame->r(value).jsValue()); 24440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); 2445cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_scoped_var); 2446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2448635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_base) { 24498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve_base dst(r) property(id) 24508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Searches the scope chain for an object containing 24528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project identifier property, and if one is found, writes it to 24538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register dst. If none is found, the outermost scope (which 24548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project will be the global object) is stored in register dst. 24558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 24568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolveBase(callFrame, vPC); 24578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2458cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_base); 2459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2461a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch DEFINE_OPCODE(op_ensure_property_exists) { 2462a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /* ensure_property_exists base(r) property(id) 2463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Throws an exception if property does not exist on base 2465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */ 2466a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int base = vPC[1].u.operand; 2467a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int property = vPC[2].u.operand; 2468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Identifier& ident = codeBlock->identifier(property); 2469a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2470a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue baseVal = callFrame->r(base).jsValue(); 2471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSObject* baseObject = asObject(baseVal); 2472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PropertySlot slot(baseVal); 2473a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!baseObject->getPropertySlot(callFrame, ident, slot)) { 2474a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring()); 2475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch goto vm_throw; 2476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch NEXT_INSTRUCTION(); 2478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_with_base) { 24808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve_with_base baseDst(r) propDst(r) property(id) 24818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Searches the scope chain for an object containing 24838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project identifier property, and if one is found, writes it to 24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register srcDst, and the retrieved property value to register 24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project propDst. If the property is not found, raises an exception. 24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This is more efficient than doing resolve_base followed by 24888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolve, or resolve_base followed by get_by_id, as it 24898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project avoids duplicate hash lookups. 24908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 24918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue))) 24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 24938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2494cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_with_base); 2495635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id) { 2498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n) 24998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Gets the property named by identifier 25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property from the value base, and puts the result in register dst. 25028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 25058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[3].u.operand; 25068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2507635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 25080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 25098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(baseValue); 25105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = baseValue.get(callFrame, ident, slot); 2511635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 25128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot); 25148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2516cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id); 2517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_self) { 2520635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n) 25218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to get a cached property from the 25238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value base. If the cache misses, op_get_by_id_self reverts to 25248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project op_get_by_id. 25258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 25270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 25288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 2530e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 25328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 25348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(baseCell->isObject()); 25358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(baseCell); 25368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 25378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = vPC[5].u.operand; 25388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2539e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); 25404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset)); 25418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2542cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_self); 2543635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2547e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2548635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_proto) { 2551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n) 25528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to get a cached property from the 25548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value base's prototype. If the cache misses, op_get_by_id_proto 25558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_get_by_id. 25568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 25580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 25598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2560635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 2561e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2562635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 25638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2564635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 2565635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(structure->prototypeForLookup(callFrame).isObject()); 2566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 2567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* prototypeStructure = vPC[5].u.structure; 25688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2569635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(protoObject->structure() == prototypeStructure)) { 25708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 25718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = vPC[6].u.operand; 25728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2573e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(protoObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); 2574e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); 25754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(protoObject->getDirectOffset(offset)); 25768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2577cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_proto); 2578635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2583e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2584635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2586bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2587692e5dbf12901edacf14812a6fae25462920af42Steve Block goto *(&&skip_id_getter_proto); 2588692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2589692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_proto) { 2590692e5dbf12901edacf14812a6fae25462920af42Steve Block /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n) 2591692e5dbf12901edacf14812a6fae25462920af42Steve Block 2592692e5dbf12901edacf14812a6fae25462920af42Steve Block Cached property access: Attempts to get a cached getter property from the 2593692e5dbf12901edacf14812a6fae25462920af42Steve Block value base's prototype. If the cache misses, op_get_by_id_getter_proto 2594692e5dbf12901edacf14812a6fae25462920af42Steve Block reverts to op_get_by_id. 2595692e5dbf12901edacf14812a6fae25462920af42Steve Block */ 2596692e5dbf12901edacf14812a6fae25462920af42Steve Block int base = vPC[2].u.operand; 2597692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue baseValue = callFrame->r(base).jsValue(); 2598692e5dbf12901edacf14812a6fae25462920af42Steve Block 2599692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseValue.isCell())) { 2600e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2601692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* structure = vPC[4].u.structure; 2602692e5dbf12901edacf14812a6fae25462920af42Steve Block 2603692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseCell->structure() == structure)) { 2604692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(structure->prototypeForLookup(callFrame).isObject()); 2605692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 2606692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* prototypeStructure = vPC[5].u.structure; 2607692e5dbf12901edacf14812a6fae25462920af42Steve Block 2608692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(protoObject->structure() == prototypeStructure)) { 2609692e5dbf12901edacf14812a6fae25462920af42Steve Block int dst = vPC[1].u.operand; 2610692e5dbf12901edacf14812a6fae25462920af42Steve Block int offset = vPC[6].u.operand; 2611692e5dbf12901edacf14812a6fae25462920af42Steve Block if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) { 2612692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* getter = getterSetter->getter(); 2613692e5dbf12901edacf14812a6fae25462920af42Steve Block CallData callData; 2614692e5dbf12901edacf14812a6fae25462920af42Steve Block CallType callType = getter->getCallData(callData); 2615692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList()); 2616692e5dbf12901edacf14812a6fae25462920af42Steve Block CHECK_FOR_EXCEPTION(); 26174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2618692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 26194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsUndefined(); 2620692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_getter_proto); 2621692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2622692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2623692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2624692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2625e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2626692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2627692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2628bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2629692e5dbf12901edacf14812a6fae25462920af42Steve Block skip_id_getter_proto: 2630692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2631bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2632dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block goto *(&&skip_id_custom_proto); 2633dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2634dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_proto) { 2635dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n) 2636dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Cached property access: Attempts to use a cached named property getter 2638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block from the value base's prototype. If the cache misses, op_get_by_id_custom_proto 2639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block reverts to op_get_by_id. 2640dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 2641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int base = vPC[2].u.operand; 2642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 2643dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2644dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseValue.isCell())) { 2645e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2646dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* structure = vPC[4].u.structure; 2647dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2648dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseCell->structure() == structure)) { 2649dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(structure->prototypeForLookup(callFrame).isObject()); 2650dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 2651dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* prototypeStructure = vPC[5].u.structure; 2652dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2653dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(protoObject->structure() == prototypeStructure)) { 2654dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int dst = vPC[1].u.operand; 2655dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int property = vPC[3].u.operand; 2656e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 2657dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2658dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc; 2659dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = getter(callFrame, protoObject, ident); 2660dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CHECK_FOR_EXCEPTION(); 26614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2662dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_proto); 2663dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2664dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2665dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2666dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2667e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2668dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2669dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2670bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2671dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block skip_id_custom_proto: 2672dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2673635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_self_list) { 2674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Polymorphic self access caching currently only supported when JITting. 2675635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT_NOT_REACHED(); 2676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! 2677cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_self_list); 2678635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 2679635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 2680635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_proto_list) { 2681635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Polymorphic prototype access caching currently only supported when JITting. 2682635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT_NOT_REACHED(); 2683635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! 2684cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_proto_list); 2685635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 2686635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 2687692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_self_list) { 2688692e5dbf12901edacf14812a6fae25462920af42Steve Block // Polymorphic self access caching currently only supported when JITting. 2689692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT_NOT_REACHED(); 2690692e5dbf12901edacf14812a6fae25462920af42Steve Block // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! 2691692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_self_list); 2692692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2693692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2694692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_proto_list) { 2695692e5dbf12901edacf14812a6fae25462920af42Steve Block // Polymorphic prototype access caching currently only supported when JITting. 2696692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT_NOT_REACHED(); 2697692e5dbf12901edacf14812a6fae25462920af42Steve Block // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! 2698692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_proto_list); 2699692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2700692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2701dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_self_list) { 2702dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Polymorphic self access caching currently only supported when JITting. 2703dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT_NOT_REACHED(); 2704dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! 2705dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_self_list); 2706dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2707dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2708dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_proto_list) { 2709dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Polymorphic prototype access caching currently only supported when JITting. 2710dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT_NOT_REACHED(); 2711dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! 2712dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_proto_list); 2713dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2714dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2715635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_chain) { 2716635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n) 27178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to get a cached property from the 27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value base's prototype chain. If the cache misses, op_get_by_id_chain 27208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_get_by_id. 27218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 27230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2725635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 2726e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 27288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2729635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 2730635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RefPtr<Structure>* it = vPC[5].u.structureChain->head(); 27318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t count = vPC[6].u.operand; 2732635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RefPtr<Structure>* end = it + count; 27338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2734635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (true) { 2735635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame)); 2736635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2737635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (UNLIKELY(baseObject->structure() != (*it).get())) 27388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 27398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (++it == end) { 27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = vPC[7].u.operand; 27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2744e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); 2745e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); 27464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset)); 27478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2748cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_chain); 2749635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 27508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2751635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2752635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype. 2753635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project baseCell = baseObject; 27548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2758e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2759635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 27608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2761bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2762692e5dbf12901edacf14812a6fae25462920af42Steve Block goto *(&&skip_id_getter_self); 2763692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2764692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_self) { 2765692e5dbf12901edacf14812a6fae25462920af42Steve Block /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n) 2766692e5dbf12901edacf14812a6fae25462920af42Steve Block 2767692e5dbf12901edacf14812a6fae25462920af42Steve Block Cached property access: Attempts to get a cached property from the 2768692e5dbf12901edacf14812a6fae25462920af42Steve Block value base. If the cache misses, op_get_by_id_getter_self reverts to 2769692e5dbf12901edacf14812a6fae25462920af42Steve Block op_get_by_id. 2770692e5dbf12901edacf14812a6fae25462920af42Steve Block */ 2771692e5dbf12901edacf14812a6fae25462920af42Steve Block int base = vPC[2].u.operand; 2772692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue baseValue = callFrame->r(base).jsValue(); 2773692e5dbf12901edacf14812a6fae25462920af42Steve Block 2774692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseValue.isCell())) { 2775e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2776692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* structure = vPC[4].u.structure; 2777692e5dbf12901edacf14812a6fae25462920af42Steve Block 2778692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseCell->structure() == structure)) { 2779692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(baseCell->isObject()); 2780692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* baseObject = asObject(baseCell); 2781692e5dbf12901edacf14812a6fae25462920af42Steve Block int dst = vPC[1].u.operand; 2782692e5dbf12901edacf14812a6fae25462920af42Steve Block int offset = vPC[5].u.operand; 2783692e5dbf12901edacf14812a6fae25462920af42Steve Block 2784692e5dbf12901edacf14812a6fae25462920af42Steve Block if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) { 2785692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* getter = getterSetter->getter(); 2786692e5dbf12901edacf14812a6fae25462920af42Steve Block CallData callData; 2787692e5dbf12901edacf14812a6fae25462920af42Steve Block CallType callType = getter->getCallData(callData); 2788692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue result = call(callFrame, getter, callType, callData, baseObject, ArgList()); 2789692e5dbf12901edacf14812a6fae25462920af42Steve Block CHECK_FOR_EXCEPTION(); 27904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2791692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 27924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsUndefined(); 2793692e5dbf12901edacf14812a6fae25462920af42Steve Block 2794692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_getter_self); 2795692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2796692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2797692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2798e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2799692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2800692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2801bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2802692e5dbf12901edacf14812a6fae25462920af42Steve Block skip_id_getter_self: 2803692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2804bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2805dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block goto *(&&skip_id_custom_self); 2806dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2807dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_self) { 2808dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block /* op_get_by_id_custom_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n) 2809dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2810dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Cached property access: Attempts to use a cached named property getter 2811dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block from the value base. If the cache misses, op_get_by_id_custom_self reverts to 2812dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block op_get_by_id. 2813dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 2814dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int base = vPC[2].u.operand; 2815dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 2816dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2817dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseValue.isCell())) { 2818e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2819dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* structure = vPC[4].u.structure; 2820dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2821dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseCell->structure() == structure)) { 2822dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(baseCell->isObject()); 2823dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int dst = vPC[1].u.operand; 2824dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int property = vPC[3].u.operand; 2825e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 2826dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2827dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PropertySlot::GetValueFunc getter = vPC[5].u.getterFunc; 2828dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = getter(callFrame, baseValue, ident); 2829dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CHECK_FOR_EXCEPTION(); 28304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2831dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_self); 2832dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2833dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2834dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2835e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2836dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2837dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2838bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2839dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockskip_id_custom_self: 2840dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2841635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_generic) { 28428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n) 28438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Gets the property named by identifier 28458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property from the value base, and puts the result in register dst. 28468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 28478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 28488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 28498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[3].u.operand; 28508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2851e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 28520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 28538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(baseValue); 28545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = baseValue.get(callFrame, ident, slot); 2855635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 28568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2858cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_generic); 2859635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 28608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2861bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2862692e5dbf12901edacf14812a6fae25462920af42Steve Block goto *(&&skip_id_getter_chain); 2863692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2864692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_chain) { 2865692e5dbf12901edacf14812a6fae25462920af42Steve Block /* op_get_by_id_getter_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n) 2866692e5dbf12901edacf14812a6fae25462920af42Steve Block 2867692e5dbf12901edacf14812a6fae25462920af42Steve Block Cached property access: Attempts to get a cached property from the 2868692e5dbf12901edacf14812a6fae25462920af42Steve Block value base's prototype chain. If the cache misses, op_get_by_id_getter_chain 2869692e5dbf12901edacf14812a6fae25462920af42Steve Block reverts to op_get_by_id. 2870692e5dbf12901edacf14812a6fae25462920af42Steve Block */ 2871692e5dbf12901edacf14812a6fae25462920af42Steve Block int base = vPC[2].u.operand; 2872692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue baseValue = callFrame->r(base).jsValue(); 2873692e5dbf12901edacf14812a6fae25462920af42Steve Block 2874692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseValue.isCell())) { 2875e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2876692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* structure = vPC[4].u.structure; 2877692e5dbf12901edacf14812a6fae25462920af42Steve Block 2878692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseCell->structure() == structure)) { 2879692e5dbf12901edacf14812a6fae25462920af42Steve Block RefPtr<Structure>* it = vPC[5].u.structureChain->head(); 2880692e5dbf12901edacf14812a6fae25462920af42Steve Block size_t count = vPC[6].u.operand; 2881692e5dbf12901edacf14812a6fae25462920af42Steve Block RefPtr<Structure>* end = it + count; 2882692e5dbf12901edacf14812a6fae25462920af42Steve Block 2883692e5dbf12901edacf14812a6fae25462920af42Steve Block while (true) { 2884692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame)); 2885692e5dbf12901edacf14812a6fae25462920af42Steve Block 2886692e5dbf12901edacf14812a6fae25462920af42Steve Block if (UNLIKELY(baseObject->structure() != (*it).get())) 2887692e5dbf12901edacf14812a6fae25462920af42Steve Block break; 2888692e5dbf12901edacf14812a6fae25462920af42Steve Block 2889692e5dbf12901edacf14812a6fae25462920af42Steve Block if (++it == end) { 2890692e5dbf12901edacf14812a6fae25462920af42Steve Block int dst = vPC[1].u.operand; 2891692e5dbf12901edacf14812a6fae25462920af42Steve Block int offset = vPC[7].u.operand; 2892692e5dbf12901edacf14812a6fae25462920af42Steve Block if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) { 2893692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* getter = getterSetter->getter(); 2894692e5dbf12901edacf14812a6fae25462920af42Steve Block CallData callData; 2895692e5dbf12901edacf14812a6fae25462920af42Steve Block CallType callType = getter->getCallData(callData); 2896dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList()); 2897692e5dbf12901edacf14812a6fae25462920af42Steve Block CHECK_FOR_EXCEPTION(); 28984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2899692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 29004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsUndefined(); 2901692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_getter_chain); 2902692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2903692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2904692e5dbf12901edacf14812a6fae25462920af42Steve Block 2905692e5dbf12901edacf14812a6fae25462920af42Steve Block // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype. 2906692e5dbf12901edacf14812a6fae25462920af42Steve Block baseCell = baseObject; 2907692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2908692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2909692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2910e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2911692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2912692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2913bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2914692e5dbf12901edacf14812a6fae25462920af42Steve Block skip_id_getter_chain: 2915692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2916bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2917dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block goto *(&&skip_id_custom_chain); 2918dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2919dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_chain) { 2920dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block /* op_get_by_id_custom_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n) 2921dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2922dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Cached property access: Attempts to use a cached named property getter on the 2923dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block value base's prototype chain. If the cache misses, op_get_by_id_custom_chain 2924dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block reverts to op_get_by_id. 2925dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 2926dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int base = vPC[2].u.operand; 2927dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 2928dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2929dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseValue.isCell())) { 2930e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2931dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* structure = vPC[4].u.structure; 2932dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2933dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseCell->structure() == structure)) { 2934dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RefPtr<Structure>* it = vPC[5].u.structureChain->head(); 2935dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block size_t count = vPC[6].u.operand; 2936dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RefPtr<Structure>* end = it + count; 2937dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2938dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block while (true) { 2939dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame)); 2940dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2941dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (UNLIKELY(baseObject->structure() != (*it).get())) 2942dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 2943dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2944dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (++it == end) { 2945dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int dst = vPC[1].u.operand; 2946dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int property = vPC[3].u.operand; 2947e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 2948dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2949dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PropertySlot::GetValueFunc getter = vPC[7].u.getterFunc; 2950dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = getter(callFrame, baseObject, ident); 2951dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CHECK_FOR_EXCEPTION(); 29524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2953dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_chain); 2954dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2955dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2956dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2957dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype. 2958dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block baseCell = baseObject; 2959dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2960dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2961dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2962e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2963dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2964dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2965bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2966dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block skip_id_custom_chain: 2967dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2968635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_array_length) { 29698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n) 29708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Gets the length of the array in register base, 29728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and puts the result in register dst. If register base does not hold 29738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project an array, op_get_array_length reverts to op_get_by_id. 29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 29770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 29788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (LIKELY(isJSArray(globalData, baseValue))) { 29798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 29804576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(asArray(baseValue)->length()); 2981cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_array_length); 2982635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 29838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 29848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2985e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2986635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 29878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2988635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_string_length) { 29898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n) 29908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Gets the length of the string in register base, 29928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and puts the result in register dst. If register base does not hold 29938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a string, op_get_string_length reverts to op_get_by_id. 29948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 29958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 29970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 29988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (LIKELY(isJSString(globalData, baseValue))) { 29998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 30004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(asString(baseValue)->length()); 3001cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_string_length); 3002635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3005e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 3006635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3008635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id) { 3009e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b) 30108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Sets the property named by identifier 30128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property, belonging to register base, to register value. 30138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 3016e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 3017e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke The "direct" flag should only be set this put_by_id is to initialize 3018e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke an object literal. 30198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 30208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 30228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[2].u.operand; 30238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 3024e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int direct = vPC[8].u.operand; 30258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 3027635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 3028a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PutPropertySlot slot(codeBlock->isStrictMode()); 3029e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (direct) { 3030e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); 3031e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT(slot.base() == baseValue); 3032e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } else 3033e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 3034635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 30358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot); 30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3038cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id); 3039635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3041635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id_transition) { 3042e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b) 30438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to set a new property with a cached transition 30458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property named by identifier property, belonging to register base, 30468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register value. If the cache misses, op_put_by_id_transition 30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_put_by_id_generic. 30488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 30518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 30530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 30548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3055635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 3056e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 3057635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* oldStructure = vPC[4].u.structure; 3058635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* newStructure = vPC[5].u.structure; 30598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3060635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == oldStructure)) { 30618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(baseCell->isObject()); 30628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(baseCell); 3063e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int direct = vPC[8].u.operand; 3064e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 3065e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!direct) { 3066e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<Structure>* it = vPC[6].u.structureChain->head(); 3067e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 3068e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke JSValue proto = baseObject->structure()->prototypeForLookup(callFrame); 3069e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke while (!proto.isNull()) { 3070e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (UNLIKELY(asObject(proto)->structure() != (*it).get())) { 3071e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke uncachePutByID(codeBlock, vPC); 3072e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke NEXT_INSTRUCTION(); 3073e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 3074e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ++it; 3075e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke proto = asObject(proto)->structure()->prototypeForLookup(callFrame); 30768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3078635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project baseObject->transitionTo(newStructure); 30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 30818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned offset = vPC[7].u.operand; 3082e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(codeBlock->identifier(vPC[2].u.operand))) == offset); 30830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); 30848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3085cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id_transition); 3086635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3090e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncachePutByID(codeBlock, vPC); 3091635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3093635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id_replace) { 3094e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b) 30958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to set a pre-existing, cached 30978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property named by identifier property, belonging to register base, 30988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register value. If the cache misses, op_put_by_id_replace 30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_put_by_id. 31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 31038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 31050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 31068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 3108e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 3109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 31108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(baseCell->isObject()); 31138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(baseCell); 31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned offset = vPC[5].u.operand; 31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3117e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(codeBlock->identifier(vPC[2].u.operand))) == offset); 31180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseObject->putDirectOffset(offset, callFrame->r(value).jsValue()); 31198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3120cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id_replace); 3121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 31228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3125e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncachePutByID(codeBlock, vPC); 3126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 31278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id_generic) { 3129e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b) 31308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Sets the property named by identifier 31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property, belonging to register base, to register value. 31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 31368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 31388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[2].u.operand; 31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 3140e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int direct = vPC[8].u.operand; 31418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 3143e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 3144a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PutPropertySlot slot(codeBlock->isStrictMode()); 3145e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (direct) { 3146e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); 3147e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT(slot.base() == baseValue); 3148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } else 3149e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 3150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 31518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3152cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id_generic); 3153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 31548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_del_by_id) { 31568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* del_by_id dst(r) base(r) property(id) 31578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register base to Object, deletes the property 31598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project named by identifier property from the object, and writes a 31608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boolean indicating success (if true) or failure (if false) 31618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register dst. 31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3163cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3164cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 31668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); 3168e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 3169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool result = baseObj->deleteProperty(callFrame, ident); 3170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!result && codeBlock->isStrictMode()) { 3171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch exceptionValue = createTypeError(callFrame, "Unable to delete property."); 3172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch goto vm_throw; 3173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 31754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 3176cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_del_by_id); 3177cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 3178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 3179cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block DEFINE_OPCODE(op_get_by_pname) { 3180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3181cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 3183cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int expected = vPC[4].u.operand; 3184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int iter = vPC[5].u.operand; 3185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int i = vPC[6].u.operand; 3186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 3187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 3188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 3189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue subscript = callFrame->r(property).jsValue(); 3190cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue expectedSubscript = callFrame->r(expected).jsValue(); 3191cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int index = callFrame->r(i).i() - 1; 3192cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue result; 3193cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int offset = 0; 3194cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) { 31954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset)); 3196cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_pname); 3197cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 3198cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 3199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch { 3200f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch Identifier propertyName(callFrame, subscript.toString(callFrame)); 3201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch result = baseValue.get(callFrame, propertyName); 3202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 3203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block CHECK_FOR_EXCEPTION(); 32044576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 3205cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_pname); 3206635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 32078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3208bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen DEFINE_OPCODE(op_get_arguments_length) { 3209bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int dst = vPC[1].u.operand; 3210bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int argumentsRegister = vPC[2].u.operand; 3211bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int property = vPC[3].u.operand; 3212bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue arguments = callFrame->r(argumentsRegister).jsValue(); 3213bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (arguments) { 3214bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Identifier& ident = codeBlock->identifier(property); 3215bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen PropertySlot slot(arguments); 3216bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue result = arguments.get(callFrame, ident, slot); 3217bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen CHECK_FOR_EXCEPTION(); 32184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 3219bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } else 32204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(callFrame->argumentCount()); 3221bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 3222bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen vPC += OPCODE_LENGTH(op_get_arguments_length); 3223bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NEXT_INSTRUCTION(); 3224bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3225bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen DEFINE_OPCODE(op_get_argument_by_val) { 3226bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int dst = vPC[1].u.operand; 3227bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int argumentsRegister = vPC[2].u.operand; 3228bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int property = vPC[3].u.operand; 3229bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue arguments = callFrame->r(argumentsRegister).jsValue(); 3230bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue subscript = callFrame->r(property).jsValue(); 3231bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!arguments && subscript.isUInt32() && subscript.asUInt32() < callFrame->argumentCount()) { 3232bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen unsigned arg = subscript.asUInt32() + 1; 3233bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen unsigned numParameters = callFrame->codeBlock()->m_numParameters; 3234bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (arg < numParameters) 32354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(arg - RegisterFile::CallFrameHeaderSize - numParameters); 3236bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen else 32374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(arg - RegisterFile::CallFrameHeaderSize - numParameters - callFrame->argumentCount() - 1); 3238bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen vPC += OPCODE_LENGTH(op_get_argument_by_val); 3239bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NEXT_INSTRUCTION(); 3240bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3241bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!arguments) { 3242bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Arguments* arguments = new (globalData) Arguments(callFrame); 32434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(argumentsRegister) = JSValue(arguments); 32444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = JSValue(arguments); 3245bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3246bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // fallthrough 3247bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3248635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_val) { 32498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* get_by_val dst(r) base(r) property(r) 32508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register base to Object, gets the property named 32528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by register property from the object, and puts the result 32538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. property is nominally converted to string 32548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project but numbers are treated more efficiently. 32558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3256cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3257cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3258cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 32598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 32610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue subscript = callFrame->r(property).jsValue(); 32628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 32648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (LIKELY(subscript.isUInt32())) { 32660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint32_t i = subscript.asUInt32(); 32678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSArray(globalData, baseValue)) { 32688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSArray* jsArray = asArray(baseValue); 32698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (jsArray->canGetIndex(i)) 32708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = jsArray->getIndex(i); 32718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 32728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = jsArray->JSArray::get(callFrame, i); 32738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) 3274643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = asString(baseValue)->getIndex(callFrame, i); 32758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) 3276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project result = asByteArray(baseValue)->getIndex(callFrame, i); 32778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project result = baseValue.get(callFrame, i); 32798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, subscript.toString(callFrame)); 3281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project result = baseValue.get(callFrame, property); 32828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 32838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 32854576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 3286cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_val); 3287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 32888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_val) { 32908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_by_val base(r) property(r) value(r) 32918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register value on register base as the property named 32938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by register property. Base is converted to object 32948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project first. register property is nominally converted to string 32958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project but numbers are treated more efficiently. 32968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 32988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 32998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3300cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 3301cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 3302cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int value = vPC[3].u.operand; 33038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 33050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue subscript = callFrame->r(property).jsValue(); 33068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (LIKELY(subscript.isUInt32())) { 33080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint32_t i = subscript.asUInt32(); 33098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSArray(globalData, baseValue)) { 33108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSArray* jsArray = asArray(baseValue); 33118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (jsArray->canSetIndex(i)) 33120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch jsArray->setIndex(i, callFrame->r(value).jsValue()); 33138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 33140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch jsArray->JSArray::put(callFrame, i, callFrame->r(value).jsValue()); 33158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { 3316635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSByteArray* jsByteArray = asByteArray(baseValue); 3317635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double dValue = 0; 33180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue jsValue = callFrame->r(value).jsValue(); 33190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (jsValue.isInt32()) 33200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch jsByteArray->setIndex(i, jsValue.asInt32()); 3321635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else if (jsValue.getNumber(dValue)) 3322635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project jsByteArray->setIndex(i, dValue); 3323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else 3324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project baseValue.put(callFrame, i, jsValue); 33258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 33260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseValue.put(callFrame, i, callFrame->r(value).jsValue()); 33278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, subscript.toString(callFrame)); 33298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!globalData->exception) { // Don't put to an object if toString threw an exception. 3330a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PutPropertySlot slot(codeBlock->isStrictMode()); 33310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot); 33328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 33338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 33348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3335635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 3336cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_val); 3337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 33388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_del_by_val) { 33408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* del_by_val dst(r) base(r) property(r) 33418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register base to Object, deletes the property 33438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project named by register property from the object, and writes a 33448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boolean indicating success (if true) or failure (if false) 33458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register dst. 33468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3347cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3348cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3349cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 33508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw 33528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue subscript = callFrame->r(property).jsValue(); 3354a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool result; 33558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32_t i; 3356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (subscript.getUInt32(i)) 3357a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch result = baseObj->deleteProperty(callFrame, i); 33588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 3359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 3360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, subscript.toString(callFrame)); 3361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 3362a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch result = baseObj->deleteProperty(callFrame, property); 3363a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!result && codeBlock->isStrictMode()) { 3365a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch exceptionValue = createTypeError(callFrame, "Unable to delete property."); 3366a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch goto vm_throw; 33678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 33694576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 3370cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_del_by_val); 3371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 33728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_index) { 33748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_by_index base(r) property(n) value(r) 33758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register value on register base as the property named 33778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by the immediate number property. Base is converted to 33788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object first. 33798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 33818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 33828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This opcode is mainly used to initialize array literals. 33848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3385cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 3386cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block unsigned property = vPC[2].u.operand; 3387cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int value = vPC[3].u.operand; 33888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue()); 33908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3391cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_index); 3392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 33938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3394635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop) { 33958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop target(offset) 33968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps unconditionally to offset target from the current 33988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instruction. 33998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 34018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 34028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 34038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 34048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 34058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3406cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[1].u.operand; 34078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 34088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3409635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jmp) { 34128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jmp target(offset) 34138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps unconditionally to offset target from the current 34158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instruction. 34168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 34178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 34188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 34198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3420cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[1].u.operand; 34218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3423635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3425635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop_if_true) { 34268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop_if_true cond(r) target(offset) 34278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 34298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register cond converts to boolean as true. 34308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 34328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 34338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3434cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int cond = vPC[1].u.operand; 3435cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 34360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { 34378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 34388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 3439635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3442cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_loop_if_true); 3443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3445643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DEFINE_OPCODE(op_loop_if_false) { 3446643ca7872b450ea4efacab6188849e5aac2ba161Steve Block /* loop_if_true cond(r) target(offset) 3447643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3448643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Jumps to offset target from the current instruction, if and 3449643ca7872b450ea4efacab6188849e5aac2ba161Steve Block only if register cond converts to boolean as false. 3450643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3451643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Additionally this loop instruction may terminate JS execution is 3452643ca7872b450ea4efacab6188849e5aac2ba161Steve Block the JS timeout is reached. 3453643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */ 3454643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int cond = vPC[1].u.operand; 3455643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int target = vPC[2].u.operand; 3456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { 3457643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += target; 3458643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CHECK_FOR_TIMEOUT(); 3459643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3460643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3461643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3462643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += OPCODE_LENGTH(op_loop_if_true); 3463643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3464643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jtrue) { 34668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jtrue cond(r) target(offset) 34678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 34698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register cond converts to boolean as true. 34708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3471cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int cond = vPC[1].u.operand; 3472cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 34730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { 34748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3475635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3478cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jtrue); 3479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jfalse) { 34828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jfalse cond(r) target(offset) 34838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 34858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register cond converts to boolean as false. 34868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3487cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int cond = vPC[1].u.operand; 3488cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 34890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { 34908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3491635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3494cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jfalse); 3495635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jeq_null) { 34988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jeq_null src(r) target(offset) 34998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 35018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register src is null. 35028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3503cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[1].u.operand; 3504cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 35050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcValue = callFrame->r(src).jsValue(); 35068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3507635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { 35088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3509635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3512cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jeq_null); 3513635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jneq_null) { 35168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jneq_null src(r) target(offset) 35178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 35198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register src is not null. 35208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3521cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[1].u.operand; 3522cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 35230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcValue = callFrame->r(src).jsValue(); 35248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3525643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { 35268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3527635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3530cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jneq_null); 3531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_jneq_ptr) { 35345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian /* jneq_ptr src(r) ptr(jsCell) target(offset) 35355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 35365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Jumps to offset target from the current instruction, if the value r is equal 35375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian to ptr, using pointer equality. 35385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 3539cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[1].u.operand; 3540cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue ptr = JSValue(vPC[2].u.jsCell); 3541cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 35420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcValue = callFrame->r(src).jsValue(); 35435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (srcValue != ptr) { 35445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC += target; 35455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 35465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 35475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3548cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jneq_ptr); 35495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 35505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop_if_less) { 35528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop_if_less src1(r) src2(r) target(offset) 35538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than register src2, as 35558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project with the ECMAScript '<' operator, and then jumps to offset 35568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project target from the current instruction, if and only if the 35578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result of the comparison is true. 35588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 35608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 35618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3562cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3563cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3564cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 35658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = jsLess(callFrame, src1, src2); 3567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 35688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) { 35708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 35718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 3572635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3575cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_loop_if_less); 3576635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3578635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop_if_lesseq) { 35798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop_if_lesseq src1(r) src2(r) target(offset) 35808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than or equal to register 35828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src2, as with the ECMAScript '<=' operator, and then jumps to 35838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset target from the current instruction, if and only if the 35848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result of the comparison is true. 35858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 35878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 35888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3589cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3590cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3591cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 35928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = jsLessEq(callFrame, src1, src2); 3594635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 35958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) { 35978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 35988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 3599635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3602cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_loop_if_lesseq); 3603635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3605635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jnless) { 36068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jnless src1(r) src2(r) target(offset) 36078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than register src2, as 36098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project with the ECMAScript '<' operator, and then jumps to offset 36108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project target from the current instruction, if and only if the 36118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result of the comparison is false. 36128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3613cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3614cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3615cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 36168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = jsLess(callFrame, src1, src2); 3618635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 36198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result) { 36218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3622635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3625cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jnless); 3626635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3628643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DEFINE_OPCODE(op_jless) { 3629643ca7872b450ea4efacab6188849e5aac2ba161Steve Block /* jless src1(r) src2(r) target(offset) 3630643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3631643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Checks whether register src1 is less than register src2, as 3632643ca7872b450ea4efacab6188849e5aac2ba161Steve Block with the ECMAScript '<' operator, and then jumps to offset 3633643ca7872b450ea4efacab6188849e5aac2ba161Steve Block target from the current instruction, if and only if the 3634643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result of the comparison is true. 3635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */ 3636643ca7872b450ea4efacab6188849e5aac2ba161Steve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3637643ca7872b450ea4efacab6188849e5aac2ba161Steve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3638643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int target = vPC[3].u.operand; 3639643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3640643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool result = jsLess(callFrame, src1, src2); 3641643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CHECK_FOR_EXCEPTION(); 3642643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3643643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (result) { 3644643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += target; 3645643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3646643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3647643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3648643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += OPCODE_LENGTH(op_jless); 3649643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3650643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 36515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_jnlesseq) { 36525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian /* jnlesseq src1(r) src2(r) target(offset) 36535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 36545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Checks whether register src1 is less than or equal to 36555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian register src2, as with the ECMAScript '<=' operator, 36565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian and then jumps to offset target from the current instruction, 36575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if and only if theresult of the comparison is false. 36585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 3659cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3660cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3661cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 36625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 36635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool result = jsLessEq(callFrame, src1, src2); 36645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 36655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 36665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!result) { 36675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC += target; 36685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 36695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 36705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3671cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jnlesseq); 36725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 36735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 367421939df44de1705786c545cd1bf519d47250322dBen Murdoch DEFINE_OPCODE(op_jlesseq) { 367521939df44de1705786c545cd1bf519d47250322dBen Murdoch /* jlesseq src1(r) src2(r) target(offset) 367621939df44de1705786c545cd1bf519d47250322dBen Murdoch 367721939df44de1705786c545cd1bf519d47250322dBen Murdoch Checks whether register src1 is less than or equal to 367821939df44de1705786c545cd1bf519d47250322dBen Murdoch register src2, as with the ECMAScript '<=' operator, 367921939df44de1705786c545cd1bf519d47250322dBen Murdoch and then jumps to offset target from the current instruction, 368021939df44de1705786c545cd1bf519d47250322dBen Murdoch if and only if the result of the comparison is true. 368121939df44de1705786c545cd1bf519d47250322dBen Murdoch */ 368221939df44de1705786c545cd1bf519d47250322dBen Murdoch JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 368321939df44de1705786c545cd1bf519d47250322dBen Murdoch JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 368421939df44de1705786c545cd1bf519d47250322dBen Murdoch int target = vPC[3].u.operand; 368521939df44de1705786c545cd1bf519d47250322dBen Murdoch 368621939df44de1705786c545cd1bf519d47250322dBen Murdoch bool result = jsLessEq(callFrame, src1, src2); 368721939df44de1705786c545cd1bf519d47250322dBen Murdoch CHECK_FOR_EXCEPTION(); 368821939df44de1705786c545cd1bf519d47250322dBen Murdoch 368921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (result) { 369021939df44de1705786c545cd1bf519d47250322dBen Murdoch vPC += target; 369121939df44de1705786c545cd1bf519d47250322dBen Murdoch NEXT_INSTRUCTION(); 369221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 369321939df44de1705786c545cd1bf519d47250322dBen Murdoch 369421939df44de1705786c545cd1bf519d47250322dBen Murdoch vPC += OPCODE_LENGTH(op_jlesseq); 369521939df44de1705786c545cd1bf519d47250322dBen Murdoch NEXT_INSTRUCTION(); 369621939df44de1705786c545cd1bf519d47250322dBen Murdoch } 3697635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_switch_imm) { 36988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r) 36998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a range checked switch on the scrutinee value, using 37018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the tableIndex-th immediate switch jump table. If the scrutinee value 37028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is an immediate number in the range covered by the referenced jump 37038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project table, and the value at jumpTable[scrutinee value] is non-zero, then 37048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project that value is used as the jump offset, otherwise defaultOffset is used. 37058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3706cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int tableIndex = vPC[1].u.operand; 3707cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int defaultOffset = vPC[2].u.operand; 3708cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); 37090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (scrutinee.isInt32()) 3710e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset); 37118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 37128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double value; 37138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int32_t intValue; 37148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value)) 3715e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(intValue, defaultOffset); 3716635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else 3717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC += defaultOffset; 37188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3719635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_switch_char) { 37228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r) 37238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a range checked switch on the scrutinee value, using 37258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the tableIndex-th character switch jump table. If the scrutinee value 37268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is a single character string in the range covered by the referenced jump 37278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project table, and the value at jumpTable[scrutinee value] is non-zero, then 37288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project that value is used as the jump offset, otherwise defaultOffset is used. 37298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3730cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int tableIndex = vPC[1].u.operand; 3731cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int defaultOffset = vPC[2].u.operand; 3732cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); 3733635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!scrutinee.isString()) 37348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += defaultOffset; 37358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 3736f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick StringImpl* value = asString(scrutinee)->value(callFrame).impl(); 3737692e5dbf12901edacf14812a6fae25462920af42Steve Block if (value->length() != 1) 37388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += defaultOffset; 37398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3740e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += codeBlock->characterSwitchJumpTable(tableIndex).offsetForValue(value->characters()[0], defaultOffset); 37418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3742635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3744635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_switch_string) { 37458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r) 37468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a sparse hashmap based switch on the value in the scrutinee 37488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register, using the tableIndex-th string switch jump table. If the 37498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scrutinee value is a string that exists as a key in the referenced 37508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jump table, then the value associated with the string is used as the 37518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jump offset, otherwise defaultOffset is used. 37528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3753cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int tableIndex = vPC[1].u.operand; 3754cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int defaultOffset = vPC[2].u.operand; 3755cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); 3756635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!scrutinee.isString()) 37578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += defaultOffset; 37588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3759f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).impl(), defaultOffset); 3760635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3762635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_func) { 37638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_func dst(r) func(f) 37648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new Function instance from function func and 37668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the current scope chain using the original Function 37678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, using the rules for function declarations, and 37688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result in register dst. 37698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3770cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3771cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int func = vPC[2].u.operand; 3772bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int shouldCheck = vPC[3].u.operand; 3773a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue()); 3774bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!shouldCheck || !callFrame->r(dst).jsValue()) 37754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(codeBlock->functionDecl(func)->make(callFrame, callFrame->scopeChain())); 37768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3777cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_func); 3778635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3780635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_func_exp) { 37818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_func_exp dst(r) func(f) 37828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new Function instance from function func and 37848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the current scope chain using the original Function 37858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, using the rules for function expressions, and 37868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result in register dst. 37878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3788cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3789cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int funcIndex = vPC[2].u.operand; 3790a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3791a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue()); 3792e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block FunctionExecutable* function = codeBlock->functionExpr(funcIndex); 3793231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSFunction* func = function->make(callFrame, callFrame->scopeChain()); 3794231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3795231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block /* 3796231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block The Identifier in a FunctionExpression can be referenced from inside 3797231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block the FunctionExpression's FunctionBody to allow the function to call 3798231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block itself recursively. However, unlike in a FunctionDeclaration, the 3799231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Identifier in a FunctionExpression cannot be referenced from and 3800231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block does not affect the scope enclosing the FunctionExpression. 3801231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */ 3802231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!function->name().isNull()) { 3803231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete); 3804231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block func->scope().push(functionScopeObject); 3805231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 3806231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 38074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(func); 38088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3809cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_func_exp); 3810635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 38118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3812635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_call_eval) { 3813e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* call_eval func(r) argCount(n) registerOffset(n) 38148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Call a function named "eval" with no explicit "this" value 38168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (which may therefore be the eval operator). If register 38178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project thisVal is the global object, and register func contains 38188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project that global object's original global eval function, then 38198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project perform the eval operator in local scope (interpreting 38208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the argument registers as for the "call" 38218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project opcode). Otherwise, act exactly as the "call" opcode would. 38228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 38238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3824e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 3825e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCount = vPC[2].u.operand; 3826e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 3827a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3828a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue()); 38290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue funcVal = callFrame->r(func).jsValue(); 38308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3831635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newCallFrame = callFrame->registers() + registerOffset; 3832635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount; 38335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue thisValue = argv[0].jsValue(); 3834231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject; 3835635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3836635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (thisValue == globalObject && funcVal == globalObject->evalFunction()) { 3837e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset); 3838e14391e94c850b8bd03680c23b38978db68687a8John Reck if ((exceptionValue = globalData->exception)) 38398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 3840e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = result; 38418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3842cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_call_eval); 3843635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 38448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3846635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // We didn't find the blessed version of eval, so process this 3847635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // instruction as a normal function call. 38488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // fall through to op_call 38498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3850635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_call) { 3851e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* call func(r) argCount(n) registerOffset(n) 38528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3853635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Perform a function call. 3854635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3855635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project registerOffset is the distance the callFrame pointer should move 3856635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project before the VM initializes the new call frame's header. 3857635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3858635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project dst is where op_ret should store its result. 38598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 38608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3861e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 3862e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCount = vPC[2].u.operand; 3863e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 38648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(func).jsValue(); 38668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallData callData; 3868545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch CallType callType = getCallData(v, callData); 38698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callType == CallTypeJS) { 38718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 3872967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 3873967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain); 3874967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!error)) { 3875967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch exceptionValue = error; 3876967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch goto vm_throw; 3877967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 38788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* previousCallFrame = callFrame; 3880967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); 3881967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 38828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!callFrame)) { 38838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame = previousCallFrame; 38848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = createStackOverflowError(callFrame); 38858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 38868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); 3889e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = newCodeBlock; 3890e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 3891635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC = newCodeBlock->instructions().begin(); 38928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 38948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 38958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 38968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3897635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 38988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callType == CallTypeHost) { 39018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 39028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 390306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!registerFile->grow(newCallFrame->registers())) { 390406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen exceptionValue = createStackOverflowError(callFrame); 390506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto vm_throw; 390606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 390706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 39085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scopeChain, callFrame, argCount, asObject(v)); 39098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue returnValue; 39118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 3912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::HostCallRecord callRecord(m_sampler.get()); 3913545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch returnValue = JSValue::decode(callData.native.function(newCallFrame)); 39148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3915635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 39168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3917e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 39188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3919cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_call); 3920635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 39218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(callType == CallTypeNone); 39248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createNotAFunctionError(callFrame, v); 39268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 39278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_load_varargs) { 3929cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int argCountDst = vPC[1].u.operand; 3930cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int argsOffset = vPC[2].u.operand; 39315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 39320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue arguments = callFrame->r(argsOffset).jsValue(); 3933ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t argCount = 0; 39345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!arguments) { 39355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke argCount = (uint32_t)(callFrame->argumentCount()); 3936ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(!asFunction(callFrame->callee())->isHostFunction()); 3944e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount(); 3945e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int32_t inplaceArgs = min(static_cast<int32_t>(argCount), expectedParams); 3946e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int32_t i = 0; 39475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* argStore = callFrame->registers() + argsOffset; 39485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 39495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // First step is to copy the "expected" parameters from their normal location relative to the callframe 39505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (; i < inplaceArgs; i++) 39515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argStore[i] = callFrame->registers()[i - RegisterFile::CallFrameHeaderSize - expectedParams]; 39525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Then we copy any additional arguments that may be further up the stack ('-1' to account for 'this') 3953e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke for (; i < static_cast<int32_t>(argCount); i++) 3954e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke argStore[i] = callFrame->registers()[i - RegisterFile::CallFrameHeaderSize - expectedParams - static_cast<int32_t>(argCount) - 1]; 39555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (!arguments.isUndefinedOrNull()) { 39565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!arguments.isObject()) { 39576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments); 39585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (asObject(arguments)->classInfo() == &Arguments::info) { 39615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Arguments* args = asArguments(arguments); 39625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argCount = args->numProvidedArguments(callFrame); 3963ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian args->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); 39715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (isJSArray(&callFrame->globalData(), arguments)) { 39725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSArray* array = asArray(arguments); 39735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argCount = array->length(); 3974ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); 39825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (asObject(arguments)->inherits(&JSArray::info)) { 39835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSObject* argObject = asObject(arguments); 39845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); 3985ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* argsBuffer = callFrame->registers() + argsOffset; 3993ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block for (uint32_t i = 0; i < argCount; ++i) { 39945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argsBuffer[i] = asObject(arguments)->get(callFrame, i); 39955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 39965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else { 39986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments); 3999bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen goto vm_throw; 40005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 40034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(argCountDst) = Register::withInt(argCount + 1); 4004cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_load_varargs); 40055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 40065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_call_varargs) { 4008e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* call_varargs func(r) argCountReg(r) baseRegisterOffset(n) 40095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Perform a function call with a dynamic set of arguments. 40115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian registerOffset is the distance the callFrame pointer should move 40135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian before the VM initializes the new call frame's header, excluding 40145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian space for arguments. 40155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian dst is where op_ret should store its result. 40175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 40185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4019e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 4020e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCountReg = vPC[2].u.operand; 4021e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 40225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(func).jsValue(); 40240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int argCount = callFrame->r(argCountReg).i(); 40255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian registerOffset += argCount; 40265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallData callData; 4027545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch CallType callType = getCallData(v, callData); 40285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (callType == CallTypeJS) { 40305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 4031967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 4032967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain); 4033967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!error)) { 4034967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch exceptionValue = error; 4035967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch goto vm_throw; 4036967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 4037967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 40385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallFrame* previousCallFrame = callFrame; 4039967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); 4040967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 40415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (UNLIKELY(!callFrame)) { 40425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian callFrame = previousCallFrame; 40435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 40445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 40455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4046967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 40475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); 4048e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = newCodeBlock; 4049e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 40505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC = newCodeBlock->instructions().begin(); 40515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(OPCODE_STATS) 40535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OpcodeStats::resetLastInstruction(); 40545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 40555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 40575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (callType == CallTypeHost) { 40605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ScopeChainNode* scopeChain = callFrame->scopeChain(); 40615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 406206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!registerFile->grow(newCallFrame->registers())) { 406306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen exceptionValue = createStackOverflowError(callFrame); 406406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto vm_throw; 406506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 40665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scopeChain, callFrame, argCount, asObject(v)); 40675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue returnValue; 40695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 4070231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::HostCallRecord callRecord(m_sampler.get()); 4071545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch returnValue = JSValue::decode(callData.native.function(newCallFrame)); 40725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 40745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4075e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 40765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4077cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_call_varargs); 40785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 40795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(callType == CallTypeNone); 40825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createNotAFunctionError(callFrame, v); 40845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 40855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4086635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_tear_off_activation) { 4087e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* tear_off_activation activation(r) arguments(r) 40888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4089e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Copy locals and named parameters from the register file to the heap. 4090e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Point the bindings in 'activation' and 'arguments' to this new backing 4091e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block store. (Note that 'arguments' may not have been created. If created, 4092e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 'arguments' already holds a copy of any extra / unnamed parameters.) 40938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4094e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears before op_ret in functions that require full scope chains. 40958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 40968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int activation = vPC[1].u.operand; 4098a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int arguments = vPC[2].u.operand; 4099e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock->needsFullScopeChain()); 4100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue activationValue = callFrame->r(activation).jsValue(); 4101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (activationValue) { 4102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch asActivation(activationValue)->copyRegisters(); 4103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4104e14391e94c850b8bd03680c23b38978db68687a8John Reck if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) { 4105e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!codeBlock->isStrictMode()) 4106e14391e94c850b8bd03680c23b38978db68687a8John Reck asArguments(argumentsValue)->setActivation(asActivation(activationValue)); 4107e14391e94c850b8bd03680c23b38978db68687a8John Reck } 4108e14391e94c850b8bd03680c23b38978db68687a8John Reck } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) { 4109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock->isStrictMode()) 4110e14391e94c850b8bd03680c23b38978db68687a8John Reck asArguments(argumentsValue)->copyRegisters(); 4111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 41128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4113cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_tear_off_activation); 4114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 41158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_tear_off_arguments) { 4117e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* tear_off_arguments arguments(r) 41188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4119e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Copy named parameters from the register file to the heap. Point the 4120e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bindings in 'arguments' to this new backing store. (Note that 4121e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 'arguments' may not have been created. If created, 'arguments' already 4122e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block holds a copy of any extra / unnamed parameters.) 41238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4124e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears before op_ret in functions that don't require full 4125e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block scope chains, but do use 'arguments'. 41268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 41278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4128e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int src1 = vPC[1].u.operand; 4129e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(!codeBlock->needsFullScopeChain() && codeBlock->ownerExecutable()->usesArguments()); 41300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4131e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src1)).jsValue()) 4132e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block asArguments(arguments)->copyRegisters(); 41338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4134cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_tear_off_arguments); 4135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 41368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_ret) { 41388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* ret result(r) 41398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Return register result as the return value of the current 4141e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block function call, writing it into functionReturnValue. 4142e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block In addition, unwind one call frame and restore the scope 4143e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block chain, code block instruction pointer and register base 4144e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block to those of the calling function. 4145e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block */ 4146e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4147e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int result = vPC[1].u.operand; 4148e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4149a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (callFrame->codeBlock()->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue()) 4150e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block callFrame->scopeChain()->deref(); 4151e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4152e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block JSValue returnValue = callFrame->r(result).jsValue(); 4153e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4154e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke vPC = callFrame->returnVPC(); 4155e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block callFrame = callFrame->callerFrame(); 4156e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4157e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (callFrame->hasHostCallFrameFlag()) 4158e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return returnValue; 4159e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4160e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 4161e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4162e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 4163e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4164e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block NEXT_INSTRUCTION(); 4165e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 4166e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block DEFINE_OPCODE(op_call_put_result) { 4167e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* op_call_put_result result(r) 4168e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4169e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Move call result from functionReturnValue to caller's 4170e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block expected return value register. 4171e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block */ 4172e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 41734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(vPC[1].u.operand) = functionReturnValue; 4174e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4175e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += OPCODE_LENGTH(op_call_put_result); 4176e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block NEXT_INSTRUCTION(); 4177e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 4178e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block DEFINE_OPCODE(op_ret_object_or_this) { 4179e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* ret result(r) 4180e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4181e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Return register result as the return value of the current 41828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function call, writing it into the caller's expected return 41838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value register. In addition, unwind one call frame and 41848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project restore the scope chain, code block instruction pointer and 41858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register base to those of the calling function. 41868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 41878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int result = vPC[1].u.operand; 41898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (codeBlock->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue()) 41918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->scopeChain()->deref(); 41928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue returnValue = callFrame->r(result).jsValue(); 41948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4195e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (UNLIKELY(!returnValue.isObject())) 4196e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block returnValue = callFrame->r(vPC[2].u.operand).jsValue(); 4197e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4198e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke vPC = callFrame->returnVPC(); 41998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame = callFrame->callerFrame(); 42005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callFrame->hasHostCallFrameFlag()) 42028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return returnValue; 42038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4204e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 4205e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4206e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 42078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 42098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_enter) { 42118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* enter 42128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4213e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Initializes local variables to undefined. If the code block requires 4214e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block an activation, enter_with_activation is used instead. 42158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4216e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears only at the beginning of a code block. 42178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 42188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t i = 0; 4220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (size_t count = codeBlock->m_numVars; i < count; ++i) 42214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(i) = jsUndefined(); 42228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4223cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_enter); 4224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 42258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4226a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch DEFINE_OPCODE(op_create_activation) { 4227a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /* create_activation dst(r) 42288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch If the activation object for this callframe has not yet been created, 4230a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch this creates it and writes it back to dst. 42318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 42328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4233a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int activationReg = vPC[1].u.operand; 4234a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!callFrame->r(activationReg).jsValue()) { 4235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable())); 4236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callFrame->r(activationReg) = JSValue(activation); 4237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); 4238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 4239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch vPC += OPCODE_LENGTH(op_create_activation); 4240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 42418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 42425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DEFINE_OPCODE(op_get_callee) { 42435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke /* op_get_callee callee(r) 42445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Move callee into a register. 42465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke */ 42475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(vPC[1].u.operand) = JSValue(callFrame->callee()); 42495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke vPC += OPCODE_LENGTH(op_get_callee); 42515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke NEXT_INSTRUCTION(); 42525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 42535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DEFINE_OPCODE(op_create_this) { 42545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke /* op_create_this this(r) proto(r) 42555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Allocate an object as 'this', fr use in construction. 42575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke This opcode should only be used at the beginning of a code 42595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block. 42605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke */ 42615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke int thisRegister = vPC[1].u.operand; 42635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke int protoRegister = vPC[2].u.operand; 42645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSFunction* constructor = asFunction(callFrame->callee()); 42665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#if !ASSERT_DISABLED 42675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ConstructData constructData; 42685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS); 42695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#endif 42705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Structure* structure; 42725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSValue proto = callFrame->r(protoRegister).jsValue(); 42735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (proto.isObject()) 42745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke structure = asObject(proto)->inheritorID(); 42755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke else 42765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke structure = constructor->scope().node()->globalObject->emptyObjectStructure(); 42774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(thisRegister) = JSValue(new (&callFrame->globalData()) JSObject(structure)); 42785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke vPC += OPCODE_LENGTH(op_create_this); 42805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke NEXT_INSTRUCTION(); 42815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 4282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_convert_this) { 42838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* convert_this this(r) 42848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Takes the value in the 'this' register, converts it to a 42868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value that is suitable for use as the 'this' value, and 42878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stores it in the 'this' register. This opcode is emitted 42888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to avoid doing the conversion in the caller unnecessarily. 42898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This opcode should only be used at the beginning of a code 42918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project block. 42928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 42938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4294cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int thisRegister = vPC[1].u.operand; 42950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue thisVal = callFrame->r(thisRegister).jsValue(); 4296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (thisVal.needsThisConversion()) 42974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toThisObject(callFrame)); 42988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4299cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_convert_this); 4300635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 43018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4302a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch DEFINE_OPCODE(op_convert_this_strict) { 4303a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /* convert_this_strict this(r) 4304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Takes the value in the 'this' register, and converts it to 4306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch its "this" form if (and only if) "this" is an object with a 4307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch custom this conversion 4308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4309a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch This opcode should only be used at the beginning of a code 4310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch block. 4311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */ 4312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int thisRegister = vPC[1].u.operand; 4314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue thisVal = callFrame->r(thisRegister).jsValue(); 4315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (thisVal.isObject() && thisVal.needsThisConversion()) 43164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toStrictThisObject(callFrame)); 4317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4318a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch vPC += OPCODE_LENGTH(op_convert_this_strict); 4319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch NEXT_INSTRUCTION(); 4320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 4321bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen DEFINE_OPCODE(op_init_lazy_reg) { 4322bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen /* init_lazy_reg dst(r) 43238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4324bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Initialises dst(r) to JSValue(). 43258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4326e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears only at the beginning of a code block. 43275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 4328e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int dst = vPC[1].u.operand; 4329e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 43304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(); 4331bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen vPC += OPCODE_LENGTH(op_init_lazy_reg); 43325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 43335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 43345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_create_arguments) { 4335e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* create_arguments dst(r) 43368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Creates the 'arguments' object and places it in both the 43385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 'arguments' call frame slot and the local 'arguments' 43395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian register, if it has not already been initialised. 43405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 43418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4342e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int dst = vPC[1].u.operand; 4343e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4344e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (!callFrame->r(dst).jsValue()) { 4345e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Arguments* arguments = new (globalData) Arguments(callFrame); 43464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(arguments); 43474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(unmodifiedArgumentsRegister(dst)) = JSValue(arguments); 4348e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 4349cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_create_arguments); 4350635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 43518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_construct) { 4353e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* construct func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r) 43548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Invoke register "func" as a constructor. For JS 43568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project functions, the calling convention is exactly as for the 43578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "call" opcode, except that the "this" value is a newly 4358635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project created Object. For native constructors, no "this" 4359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project value is passed. In either case, the argCount and registerOffset 43608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project registers are interpreted as for the "call" opcode. 43618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register proto must contain the prototype property of 4363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project register func. This is to enable polymorphic inline 43648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project caching of this lookup. 43658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 43668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4367e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 4368e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCount = vPC[2].u.operand; 4369e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 43708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(func).jsValue(); 43728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ConstructData constructData; 4374545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ConstructType constructType = getConstructData(v, constructData); 43758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (constructType == ConstructTypeJS) { 43778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* callDataScopeChain = constructData.js.scopeChain; 43788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4379967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = constructData.js.functionExecutable->compileForConstruct(callFrame, callDataScopeChain); 4380967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!error)) { 4381967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch exceptionValue = error; 4382967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch goto vm_throw; 4383967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 438406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 4385967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CallFrame* previousCallFrame = callFrame; 4386967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct(); 4387967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 43888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!callFrame)) { 43898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame = previousCallFrame; 43908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = createStackOverflowError(callFrame); 43918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 43928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 43938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); 4395e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = newCodeBlock; 4396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC = newCodeBlock->instructions().begin(); 43978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 43988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 43998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 44008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4401635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (constructType == ConstructTypeHost) { 44058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 44068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 440706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!registerFile->grow(newCallFrame->registers())) { 440806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen exceptionValue = createStackOverflowError(callFrame); 440906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto vm_throw; 441006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 4411545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scopeChain, callFrame, argCount, asObject(v)); 44128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue returnValue; 44148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 4415231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::HostCallRecord callRecord(m_sampler.get()); 4416545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch returnValue = JSValue::decode(constructData.native.function(newCallFrame)); 44178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4418635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 4419545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch functionReturnValue = returnValue; 44208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4421cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_construct); 4422635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(constructType == ConstructTypeNone); 44268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createNotAConstructorError(callFrame, v); 44288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 44298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_strcat) { 4431bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen /* strcat dst(r) src(r) count(n) 4432bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 4433bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Construct a new String instance using the original 4434bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen constructor, and puts the result in register dst. 4435bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen The string will be the result of concatenating count 4436bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen strings with values taken from registers starting at 4437bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen register src. 4438bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen */ 4439cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4440cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 4441cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int count = vPC[3].u.operand; 44425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count); 4444643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CHECK_FOR_EXCEPTION(); 4445cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_strcat); 44465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 44485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 44495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_to_primitive) { 4450cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4451cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 44525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame); 4454cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_to_primitive); 44555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 44575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_push_scope) { 44598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* push_scope scope(r) 44608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register scope to object, and pushes it onto the top 4462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project of the current scope chain. The contents of the register scope 4463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project are replaced by the result of toObject conversion of the scope. 44648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4465cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int scope = vPC[1].u.operand; 44660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(scope).jsValue(); 4467635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSObject* o = v.toObject(callFrame); 4468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 44698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44704576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(scope) = JSValue(o); 44718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(callFrame->scopeChain()->push(o)); 44728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4473cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_push_scope); 4474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_pop_scope) { 44778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* pop_scope 44788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Removes the top item from the current scope chain. 44808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 44818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(callFrame->scopeChain()->pop()); 44828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4483cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_pop_scope); 4484635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_pnames) { 4487cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset) 44888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Creates a property name list for register base and puts it 4490cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block in register dst, initializing i and size for iteration. If 4491cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block base is undefined or null, jumps to breakTarget. 44928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4493cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4494cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 4495cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int i = vPC[3].u.operand; 4496cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int size = vPC[4].u.operand; 4497cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int breakTarget = vPC[5].u.operand; 44988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4499cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue v = callFrame->r(base).jsValue(); 4500cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (v.isUndefinedOrNull()) { 4501cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += breakTarget; 4502cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 4503cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 4504cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 4505cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSObject* o = v.toObject(callFrame); 4506cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Structure* structure = o->structure(); 4507cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); 4508cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) 4509cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); 4510cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 45114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsPropertyNameIterator; 45124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(base) = JSValue(o); 45134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(i) = Register::withInt(0); 45144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(size) = Register::withInt(jsPropertyNameIterator->size()); 4515cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_pnames); 4516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_next_pname) { 4519cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset) 45208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4521cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Copies the next name from the property name list in 4522cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block register iter to dst, then jumps to offset target. If there are no 4523cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block names left, invalidates the iterator and continues to the next 45248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instruction. 45258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4526cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4527cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 4528cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int i = vPC[3].u.operand; 4529cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int size = vPC[4].u.operand; 4530cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int iter = vPC[5].u.operand; 4531cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[6].u.operand; 45328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 4534cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block while (callFrame->r(i).i() != callFrame->r(size).i()) { 4535cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i()); 4536e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CHECK_FOR_EXCEPTION(); 45374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(i) = Register::withInt(callFrame->r(i).i() + 1); 4538cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (key) { 4539cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block CHECK_FOR_TIMEOUT(); 45404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = key; 4541cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += target; 4542cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 4543cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 45448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 45458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4546cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_next_pname); 4547635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4549635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jmp_scopes) { 45508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jmp_scopes count(n) target(offset) 45518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Removes the a number of items from the current scope chain 45538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project specified by immediate number count, then jumps to offset 45548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project target. 45558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4556cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int count = vPC[1].u.operand; 4557cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 45588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* tmp = callFrame->scopeChain(); 45608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (count--) 45618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tmp = tmp->pop(); 45628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(tmp); 45638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 4565635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4567e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 45688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Appease GCC 45698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto *(&&skip_new_scope); 45708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4571635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_push_new_scope) { 45728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_scope dst(r) property(id) value(r) 45738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new StaticScopeObject with property set to value. That scope 45758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object is then pushed onto the ScopeChain. The scope object is then stored 45768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in dst for GC. 45778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 45788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(createExceptionScope(callFrame, vPC)); 45798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4580cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_push_new_scope); 4581635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4583e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 45848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project skip_new_scope: 45858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4586635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_catch) { 45878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* catch ex(r) 45888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Retrieves the VM's current exception and puts it in register 45908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ex. This is only valid after an exception has been raised, 45918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and usually forms the beginning of an exception handler. 45928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 45938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(exceptionValue); 45948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!globalData->exception); 4595cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int ex = vPC[1].u.operand; 45964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(ex) = exceptionValue; 45975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = JSValue(); 45988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4599cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_catch); 4600635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_throw) { 46038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* throw ex(r) 46048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Throws register ex as an exception. This involves three 46068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project steps: first, it is set as the current exception in the 46078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VM's internal state, then the stack is unwound until an 46088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exception handler or a native code boundary is found, and 46098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project then control resumes at the exception handler if any or 46108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else the script returns control to the nearest native caller. 46118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 46128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4613cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int ex = vPC[1].u.operand; 46140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch exceptionValue = callFrame->r(ex).jsValue(); 46158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin()); 4617e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!handler) 4618e14391e94c850b8bd03680c23b38978db68687a8John Reck return throwError(callFrame, exceptionValue); 46198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4620e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4621e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC = codeBlock->instructions().begin() + handler->target; 4622635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner DEFINE_OPCODE(op_throw_reference_error) { 46256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner /* op_throw_reference_error message(k) 46268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Constructs a new reference Error instance using the 46286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner original constructor, using constant message as the 46296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner message string. The result is thrown. 46308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 46316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner UString message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame); 46326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = JSValue(createReferenceError(callFrame, message)); 46336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner goto vm_throw; 46346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 4635635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_end) { 46368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* end result(r) 46378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Return register result as the value of a global or eval 46398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project program. Return control to the calling native code. 46408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 46418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4642e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (codeBlock->needsFullScopeChain()) { 46438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 46448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scopeChain->refCount > 1); 46458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->deref(); 46468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4647cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int result = vPC[1].u.operand; 46480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return callFrame->r(result).jsValue(); 46498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4650635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_getter) { 46518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_getter base(r) property(id) function(r) 46528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register function on register base as the getter named 46548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by identifier property. Base and function are assumed to be 46558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project objects as this op should only be used for getters defined 46568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in object literal form. 46578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 46598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 46608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4661cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 4662cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 4663cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int function = vPC[3].u.operand; 46648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(base).jsValue().isObject()); 46660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = asObject(callFrame->r(base).jsValue()); 4667e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 46680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(function).jsValue().isObject()); 46690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); 46708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4671cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_getter); 4672635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_setter) { 46758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_setter base(r) property(id) function(r) 46768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register function on register base as the setter named 46788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by identifier property. Base and function are assumed to be 46798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project objects as this op should only be used for setters defined 46808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in object literal form. 46818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 46838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 46848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4685cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 4686cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 4687cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int function = vPC[3].u.operand; 46888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(base).jsValue().isObject()); 46900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = asObject(callFrame->r(base).jsValue()); 4691e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 46920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(function).jsValue().isObject()); 4693231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); 46948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4695cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_setter); 4696635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_method_check) { 46995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC++; 47005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 47015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4702635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jsr) { 47038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jsr retAddrDst(r) target(offset) 47048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Places the address of the next instruction into the retAddrDst 47068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register and jumps to offset target from the current instruction. 47078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4708cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int retAddrDst = vPC[1].u.operand; 4709cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 4710cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr); 47118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 4713635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4715635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_sret) { 47168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* sret retAddrSrc(r) 47178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to the address stored in the retAddrSrc register. This 47198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project differs from op_jmp because the target address is stored in a 47208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register, not as an immediate. 47218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4722cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int retAddrSrc = vPC[1].u.operand; 47230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch vPC = callFrame->r(retAddrSrc).vPC(); 4724635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_debug) { 47278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* debug debugHookID(n) firstLine(n) lastLine(n) 47288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Notifies the debugger of the current state of execution. This opcode 47308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is only generated while the debugger is attached. 47318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4732cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int debugHookID = vPC[1].u.operand; 4733cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int firstLine = vPC[2].u.operand; 4734cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int lastLine = vPC[3].u.operand; 47358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine); 47378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4738cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_debug); 4739635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_profile_will_call) { 47428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_profile_will_call function(r) 47438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Notifies the profiler of the beginning of a function call. This opcode 47458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is only generated if developer tools are enabled. 47468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 47478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int function = vPC[1].u.operand; 47488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*enabledProfilerReference) 47500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue()); 47518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4752cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_profile_will_call); 4753635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4755635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_profile_did_call) { 47568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_profile_did_call function(r) 47578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Notifies the profiler of the end of a function call. This opcode 47598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is only generated if developer tools are enabled. 47608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 47618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int function = vPC[1].u.operand; 47628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*enabledProfilerReference) 47640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue()); 47658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4766cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_profile_did_call); 4767635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vm_throw: { 47705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian globalData->exception = JSValue(); 47718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!tickCount) { 47728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The exceptionValue is a lie! (GCC produces bad code for reasons I 47738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // cannot fathom if we don't assign to the exceptionValue before branching) 47748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = createInterruptedExecutionException(globalData); 47758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin()); 4777e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!handler) 4778e14391e94c850b8bd03680c23b38978db68687a8John Reck return throwError(callFrame, exceptionValue); 4779635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4780e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4781e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC = codeBlock->instructions().begin() + handler->target; 4782635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4785e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if !ENABLE(COMPUTED_GOTO_INTERPRETER) 47868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } // iterator loop ends 47878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #undef NEXT_INSTRUCTION 4789635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #undef DEFINE_OPCODE 4790635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #undef CHECK_FOR_EXCEPTION 47918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #undef CHECK_FOR_TIMEOUT 4792e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif // ENABLE(INTERPRETER) 47938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 47948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47955f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const 47968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 47978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function); 47988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!functionCallFrame) 47998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = functionCallFrame->codeBlock(); 4802635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->usesArguments()) { 4803635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(codeBlock->codeType() == FunctionCode); 4804e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argumentsRegister = codeBlock->argumentsRegister(); 4805ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister); 4806ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (JSValue arguments = functionCallFrame->uncheckedR(argumentsRegister).jsValue()) 4807ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return arguments; 4808ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch JSValue arguments = JSValue(new (callFrame) Arguments(functionCallFrame)); 4809ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch functionCallFrame->r(argumentsRegister) = arguments; 4810ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch functionCallFrame->r(realArgumentsRegister) = arguments; 4811ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return arguments; 48128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4814e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Arguments* arguments = new (functionCallFrame) Arguments(functionCallFrame); 4815e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block arguments->copyRegisters(); 48168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return arguments; 48178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4819e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockJSValue Interpreter::retrieveCaller(CallFrame* callFrame, JSFunction* function) const 48208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function); 48228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!functionCallFrame) 48238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* callerFrame = functionCallFrame->callerFrame(); 48268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callerFrame->hasHostCallFrameFlag()) 48278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue caller = callerFrame->callee(); 48308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!caller) 48318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return caller; 48348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const 48378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian function = JSValue(); 48398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lineNumber = -1; 48408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sourceURL = UString(); 48418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* callerFrame = callFrame->callerFrame(); 48438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callerFrame->hasHostCallFrameFlag()) 48448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 48458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* callerCodeBlock = callerFrame->codeBlock(); 48478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!callerCodeBlock) 48488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 4849e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke unsigned bytecodeOffset = 0; 4850e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 4851e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (!callerFrame->globalData().canUseJIT()) 48524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC()); 4853e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 4854e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 48554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC()); 4856e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 4857e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#else 48584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC()); 4859e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 48604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1); 4861231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block sourceID = callerCodeBlock->ownerExecutable()->sourceID(); 4862231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block sourceURL = callerCodeBlock->ownerExecutable()->sourceURL(); 48638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function = callerFrame->callee(); 48648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4866e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockCallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, JSFunction* function) 48678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (CallFrame* candidate = callFrame; candidate; candidate = candidate->callerFrame()->removeHostCallFrameFlag()) { 48698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (candidate->callee() == function) 48708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return candidate; 48718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 48738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4875231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::enableSampler() 4876231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4877231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(OPCODE_SAMPLING) 4878231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_sampler) { 4879231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampler.set(new SamplingTool(this)); 4880231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampler->setup(); 4881231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 4882231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4883231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4884231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::dumpSampleData(ExecState* exec) 4885231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4886231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(OPCODE_SAMPLING) 4887231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_sampler) 4888231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampler->dump(exec); 4889231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else 4890231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block UNUSED_PARAM(exec); 4891231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4892231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4893231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::startSampling() 4894231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4895231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(SAMPLING_THREAD) 4896231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_sampleEntryDepth) 4897231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingThread::start(); 4898231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4899231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampleEntryDepth++; 4900231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4901231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4902231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::stopSampling() 4903231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4904231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(SAMPLING_THREAD) 4905231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampleEntryDepth--; 4906231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_sampleEntryDepth) 4907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingThread::stop(); 4908231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 49118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 4912