Interpreter.cpp revision 2fc2651226baac27029e38c9d6ef883fa32084db
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 { 1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObject* o = iter->get(); 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); 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = callFrame->globalData().exception.get(); 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 { 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObject* o = iter->get(); 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); 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = callFrame->globalData().exception.get(); 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 1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = callFrame->globalData().exception.get(); 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--) { 2232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSObject* o = iter->get(); 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); 2302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = callFrame->globalData().exception.get(); 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; 2392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block o = iter->get(); 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 2692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = callFrame->globalData().exception.get(); 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 { 3132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block base = iter->get(); 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); 3172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = callFrame->globalData().exception.get(); 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(); 5692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 5702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block callFrame->setScopeChain(scopeChain); 5712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSActivation* activation = asActivation(scopeChain->object.get()); 572e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block activation->copyRegisters(); 5734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) { 574a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!oldCodeBlock->isStrictMode()) 5752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block asArguments(arguments)->setActivation(callFrame->globalData(), activation); 576a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 577a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) { 5784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) 579e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block asArguments(arguments)->copyRegisters(); 5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 582635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (oldCodeBlock->needsFullScopeChain()) 5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->deref(); 5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 585e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CallFrame* callerFrame = callFrame->callerFrame(); 586e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (callerFrame->hasHostCallFrameFlag()) 5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 589e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callerFrame->codeBlock(); 590967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#if ENABLE(JIT) && ENABLE(INTERPRETER) 591e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callerFrame->globalData().canUseJIT()) 5924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC()); 593e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 5944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()); 595967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#elif ENABLE(JIT) 5964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC()); 597e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#else 5984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC()); 599e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 600967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 601e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block callFrame = callerFrame; 6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception, unsigned bytecodeOffset) 6066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{ 6076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exception->clearAppendSourceToMessage(); 6086b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!callFrame->codeBlock()->hasExpressionInfo()) 6104576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return; 6114576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int startOffset = 0; 6136b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int endOffset = 0; 6146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int divotPoint = 0; 6156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CodeBlock* codeBlock = callFrame->codeBlock(); 6174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset); 6186b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6196b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int expressionStart = divotPoint - startOffset; 6206b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int expressionStop = divotPoint + endOffset; 6216b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!expressionStop || expressionStart > codeBlock->source()->length()) 6236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 6246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSGlobalData* globalData = &callFrame->globalData(); 6266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSValue jsMessage = exception->getDirect(globalData->propertyNames->message); 6276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (!jsMessage || !jsMessage.isString()) 6286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return; 6296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner UString message = asString(jsMessage)->value(callFrame); 6316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (expressionStart < expressionStop) 6336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner message = makeUString(message, " (evaluating '", codeBlock->source()->getRange(expressionStart, expressionStop), "')"); 6346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner else { 6356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // No range information, so give a few characters of context 6366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner const UChar* data = codeBlock->source()->data(); 6376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int dataLength = codeBlock->source()->length(); 6386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int start = expressionStart; 6396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int stop = expressionStart; 6406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // Get up to 20 characters of context to the left and right of the divot, clamping to the line. 6416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // then strip whitespace. 6426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n') 6436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner start--; 6446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (start < (expressionStart - 1) && isStrWhiteSpace(data[start])) 6456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner start++; 6466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n') 6476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner stop++; 6486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner while (stop > expressionStart && isStrWhiteSpace(data[stop])) 6496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner stop--; 6506b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner message = makeUString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')"); 6516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 6526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exception->putDirect(*globalData, globalData->propertyNames->message, jsString(globalData, message)); 6546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner} 6556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangNEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset) 6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 6594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bool isInterrupt = false; 6604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Set up the exception object 662635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (exceptionValue.isObject()) { 6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* exception = asObject(exceptionValue); 6644576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) 6666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset); 6676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6684576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // Using hasExpressionInfo to imply we are interested in rich exception info. 6694576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) { 6704576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ASSERT(codeBlock->hasLineInfo()); 6716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 6724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // FIXME: should only really be adding these properties to VM generated exceptions, 6734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang // but the inspector currently requires these for all thrown objects. 6744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source()); 6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 6774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang ComplType exceptionType = exception->exceptionType(); 6784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang isInterrupt = exceptionType == Interrupted || exceptionType == Terminated; 6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) { 6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); 683d0825bca7fe65beaee391d30da42e937db621564Steve Block bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset); 6844576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler); 6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Calculate an exception handler vPC, unwinding call frames as necessary. 688635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HandlerInfo* handler = 0; 6894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang while (isInterrupt || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { 6904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) { 6914576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (Profiler* profiler = *Profiler::enabledProfilerReference()) 6924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang profiler->exceptionUnwind(callFrame); 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 6944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang } 6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (Profiler* profiler = *Profiler::enabledProfilerReference()) 6984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang profiler->exceptionUnwind(callFrame); 6994576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 7005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Shrink the JS stack, in case stack overflow made it huge. 701e14391e94c850b8bd03680c23b38978db68687a8John Reck Register* highWaterMark = 0; 702e14391e94c850b8bd03680c23b38978db68687a8John Reck for (CallFrame* callerFrame = callFrame; callerFrame; callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag()) { 703a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch CodeBlock* codeBlock = callerFrame->codeBlock(); 704a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock) 705a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch continue; 706a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters; 707a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch highWaterMark = max(highWaterMark, callerHighWaterMark); 708a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 709a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch m_registerFile.shrink(highWaterMark); 7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke // Unwind the scope chain within the exception handler's call frame. 712635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 713635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ScopeChain sc(scopeChain); 714a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int scopeDelta = 0; 715a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode 7164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) 717a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeDelta = depth(codeBlock, sc) - handler->scopeDepth; 7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scopeDelta >= 0); 7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (scopeDelta--) 720635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project scopeChain = scopeChain->pop(); 721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project callFrame->setScopeChain(scopeChain); 7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 723635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return handler; 7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 726e14391e94c850b8bd03680c23b38978db68687a8John Reckstatic inline JSValue checkedReturn(JSValue returnValue) 727e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 728e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(returnValue); 729e14391e94c850b8bd03680c23b38978db68687a8John Reck return returnValue; 730e14391e94c850b8bd03680c23b38978db68687a8John Reck} 731e14391e94c850b8bd03680c23b38978db68687a8John Reck 732e14391e94c850b8bd03680c23b38978db68687a8John Reckstatic inline JSObject* checkedReturn(JSObject* returnValue) 733e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 734e14391e94c850b8bd03680c23b38978db68687a8John Reck ASSERT(returnValue); 735e14391e94c850b8bd03680c23b38978db68687a8John Reck return returnValue; 736e14391e94c850b8bd03680c23b38978db68687a8John Reck} 737e14391e94c850b8bd03680c23b38978db68687a8John Reck 738e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj) 7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!scopeChain->globalData->exception); 7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 742e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 743e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 745967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = program->compile(callFrame, scopeChain); 746e14391e94c850b8bd03680c23b38978db68687a8John Reck if (error) 747e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, error)); 748967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* codeBlock = &program->generatedBytecode(); 7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* oldEnd = m_registerFile.end(); 751635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; 752e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_registerFile.grow(newEnd)) 753e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSGlobalObject* lastGlobalObject = m_registerFile.globalObject(); 7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSGlobalObject* globalObject = callFrame->dynamicGlobalObject(); 7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project globalObject->copyGlobalsTo(m_registerFile); 7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 759635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize); 7605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. 7615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->m_numParameters, 0); 7624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj); 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 764635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->needsFullScopeChain()) 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->ref(); 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); 7685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** profiler = Profiler::enabledProfilerReference(); 7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 7714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, program->sourceURL(), program->lineNo()); 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 775231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::CallRecord callRecord(m_sampler.get()); 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 777e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 778635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 779e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 780e14391e94c850b8bd03680c23b38978db68687a8John Reck result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData); 781e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 782e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 783e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 784e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reentryDepth--; 7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 789231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block (*profiler)->didExecute(callFrame, program->sourceURL(), program->lineNo()); 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject) 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastGlobalObject->copyGlobalsTo(m_registerFile); 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 796e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 799e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) 8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(!callFrame->hadException()); 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 803e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 804e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* oldEnd = m_registerFile.end(); 8075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke int argCount = 1 + args.size(); // implicit "this" parameter 8085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; 8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 810e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_registerFile.grow(oldEnd + registerOffset)) 811e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(oldEnd); 8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t dst = 0; 8154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(0) = thisValue; 8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ArgList::const_iterator end = args.end(); 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (ArgList::const_iterator it = args.begin(); it != end; ++it) 8184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(++dst) = *it; 8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (callType == CallTypeJS) { 8215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 8225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 823967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain); 824967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!compileError)) { 825967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_registerFile.shrink(oldEnd); 826e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 827967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 828967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 829967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); 830967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount); 8315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (UNLIKELY(!newCallFrame)) { 8325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_registerFile.shrink(oldEnd); 833e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 8355af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8365af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function); 8375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8385af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DynamicGlobalObjectScope globalObjectScope(newCallFrame, callDataScopeChain->globalObject); 8395af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Profiler** profiler = Profiler::enabledProfilerReference(); 8415af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (*profiler) 8424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, function); 8435af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSValue result; 8455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke { 8465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke SamplingTool::CallRecord callRecord(m_sampler.get()); 8475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 848e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 849e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 850e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 851e14391e94c850b8bd03680c23b38978db68687a8John Reck result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData); 852e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 853e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 854e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 8555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke m_reentryDepth--; 8565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 8575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (*profiler) 8594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, function); 8605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 862e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(callType == CallTypeHost); 8665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ScopeChainNode* scopeChain = callFrame->scopeChain(); 8675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset); 8685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function); 8695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 8705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject); 8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** profiler = Profiler::enabledProfilerReference(); 8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 8744576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, function); 8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 8785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke SamplingTool::HostCallRecord callRecord(m_sampler.get()); 879545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch result = JSValue::decode(callData.native.function(newCallFrame)); 8806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 8816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 8826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (*profiler) 8834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, function); 8846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 8856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_registerFile.shrink(oldEnd); 886e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 8876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen} 8886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 889e14391e94c850b8bd03680c23b38978db68687a8John ReckJSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* constructor, ConstructType constructType, const ConstructData& constructData, const ArgList& args) 8906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{ 891545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(!callFrame->hadException()); 8926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 893e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 894e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 8956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 8966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Register* oldEnd = m_registerFile.end(); 897545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch int argCount = 1 + args.size(); // implicit "this" parameter 898545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; 8996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 900e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!m_registerFile.grow(oldEnd + registerOffset)) 901e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 9026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 9036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen CallFrame* newCallFrame = CallFrame::create(oldEnd); 9046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen size_t dst = 0; 9056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ArgList::const_iterator end = args.end(); 9066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen for (ArgList::const_iterator it = args.begin(); it != end; ++it) 9074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(++dst) = *it; 9086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 909545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (constructType == ConstructTypeJS) { 910545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ScopeChainNode* constructDataScopeChain = constructData.js.scopeChain; 911545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 912967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain); 913967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!compileError)) { 914967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_registerFile.shrink(oldEnd); 915e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 916967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 917967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 918967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct(); 919967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount); 920545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (UNLIKELY(!newCallFrame)) { 921545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch m_registerFile.shrink(oldEnd); 922e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 923545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 924545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 925545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor); 926545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 927545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch DynamicGlobalObjectScope globalObjectScope(newCallFrame, constructDataScopeChain->globalObject); 928545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 929545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch Profiler** profiler = Profiler::enabledProfilerReference(); 930545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (*profiler) 9314576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, constructor); 932545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 933545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch JSValue result; 934545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch { 935545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch SamplingTool::CallRecord callRecord(m_sampler.get()); 936545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 937e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 938e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 939e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 940e14391e94c850b8bd03680c23b38978db68687a8John Reck result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData); 941e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 942e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 943e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 944545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch m_reentryDepth--; 945545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch } 946545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 947545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (*profiler) 9484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, constructor); 949545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 9506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_registerFile.shrink(oldEnd); 951545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (callFrame->hadException()) 952545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 953545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(result.isObject()); 954e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(asObject(result)); 9556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 9565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 957545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(constructType == ConstructTypeHost); 958545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ScopeChainNode* scopeChain = callFrame->scopeChain(); 959545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset); 960545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor); 961545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch 962545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject); 9636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 9646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Profiler** profiler = Profiler::enabledProfilerReference(); 9656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (*profiler) 9664576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, constructor); 9676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 9686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen JSValue result; 9696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen { 970545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch SamplingTool::HostCallRecord callRecord(m_sampler.get()); 971545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch result = JSValue::decode(constructData.native.function(newCallFrame)); 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 9754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->didExecute(callFrame, constructor); 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 978545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (callFrame->hadException()) 979545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return 0; 980545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ASSERT(result.isObject()); 981e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(asObject(result)); 9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 984e14391e94c850b8bd03680c23b38978db68687a8John ReckCallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionExecutable, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain) 9855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 9865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(!scopeChain->globalData->exception); 9875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 988dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_reentryDepth >= MaxSmallThreadReentryDepth) { 989dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) { 990e14391e94c850b8bd03680c23b38978db68687a8John Reck throwStackOverflowError(callFrame); 9915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return CallFrameClosure(); 9925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 9945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* oldEnd = m_registerFile.end(); 9965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int argc = 1 + argCount; // implicit "this" parameter 9975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 9985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!m_registerFile.grow(oldEnd + argc)) { 999e14391e94c850b8bd03680c23b38978db68687a8John Reck throwStackOverflowError(callFrame); 10005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return CallFrameClosure(); 10015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallFrame* newCallFrame = CallFrame::create(oldEnd); 10045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t dst = 0; 10055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (int i = 0; i < argc; ++i) 10064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(++dst) = jsUndefined(); 10075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1008967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = FunctionExecutable->compileForCall(callFrame, scopeChain); 1009967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (error) { 1010e14391e94c850b8bd03680c23b38978db68687a8John Reck throwError(callFrame, error); 1011967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_registerFile.shrink(oldEnd); 1012967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return CallFrameClosure(); 1013967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 1014967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* codeBlock = &FunctionExecutable->generatedBytecodeForCall(); 1015967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 1016967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc); 10175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (UNLIKELY(!newCallFrame)) { 1018e14391e94c850b8bd03680c23b38978db68687a8John Reck throwStackOverflowError(callFrame); 10195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_registerFile.shrink(oldEnd); 10205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return CallFrameClosure(); 10215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 1022e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function); 1023231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc }; 10245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return result; 10255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 10265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1027e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(CallFrameClosure& closure) 10285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 10295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian closure.resetCallFrame(); 10305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Profiler** profiler = Profiler::enabledProfilerReference(); 10315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (*profiler) 10325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian (*profiler)->willExecute(closure.oldCallFrame, closure.function); 10335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 10355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 1036231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::CallRecord callRecord(m_sampler.get()); 10375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1038e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_reentryDepth++; 10395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(JIT) 1040e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1041e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (closure.newCallFrame->globalData().canUseJIT()) 1042e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1043e14391e94c850b8bd03680c23b38978db68687a8John Reck result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData); 1044e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1045e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 1046e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1047e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1048e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1049e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, closure.newCallFrame); 10505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 10515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_reentryDepth--; 10525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 10535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (*profiler) 10555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian (*profiler)->didExecute(closure.oldCallFrame, closure.function); 1056e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 10575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 10585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 10595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Interpreter::endRepeatCall(CallFrameClosure& closure) 10605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 10615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_registerFile.shrink(closure.oldEnd); 10625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 10635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1064e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain) 10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1066967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = eval->compile(callFrame, scopeChain); 1067e14391e94c850b8bd03680c23b38978db68687a8John Reck if (UNLIKELY(!!compileError)) 1068e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 1069e14391e94c850b8bd03680c23b38978db68687a8John Reck return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->generatedBytecode().m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain); 10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1072e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain) 10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!scopeChain->globalData->exception); 10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1076e14391e94c850b8bd03680c23b38978db68687a8John Reck if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) 1077e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1079643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject); 10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1081967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* compileError = eval->compile(callFrame, scopeChain); 1082e14391e94c850b8bd03680c23b38978db68687a8John Reck if (UNLIKELY(!!compileError)) 1083e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwError(callFrame, compileError)); 1084967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch EvalCodeBlock* codeBlock = &eval->generatedBytecode(); 10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1086a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSObject* variableObject; 10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (ScopeChainNode* node = scopeChain; ; node = node->next) { 10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node); 10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (node->object->isVariableObject()) { 10902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block variableObject = static_cast<JSVariableObject*>(node->object.get()); 10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen unsigned numVariables = codeBlock->numVariables(); 10966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int numFunctions = codeBlock->numberOfFunctionDecls(); 1097a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool pushedScope = false; 10986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (numVariables || numFunctions) { 1099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (codeBlock->isStrictMode()) { 1100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch variableObject = new (callFrame) StrictEvalActivation(callFrame); 1101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain = scopeChain->push(variableObject); 1102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch pushedScope = true; 1103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 11046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen // Scope for BatchedTransitionOptimizer 11052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BatchedTransitionOptimizer optimizer(callFrame->globalData(), variableObject); 11068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (unsigned i = 0; i < numVariables; ++i) { 1108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const Identifier& ident = codeBlock->variable(i); 11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!variableObject->hasProperty(callFrame, ident)) { 11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project variableObject->put(callFrame, ident, jsUndefined(), slot); 11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block for (int i = 0; i < numFunctions; ++i) { 1116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FunctionExecutable* function = codeBlock->functionDecl(i); 11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PutPropertySlot slot; 1118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot); 11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Register* oldEnd = m_registerFile.end(); 1123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->m_numCalleeRegisters; 11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_registerFile.grow(newEnd)) { 1125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (pushedScope) 1126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain->pop(); 1127e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(throwStackOverflowError(callFrame)); 11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset); 11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11325af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(codeBlock->m_numParameters == 1); // 1 parameter for 'this'. 11335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->m_numParameters, 0); 11344576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj); 11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->needsFullScopeChain()) 11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->ref(); 11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** profiler = Profiler::enabledProfilerReference(); 11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 11414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang (*profiler)->willExecute(callFrame, eval->sourceURL(), eval->lineNo()); 11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::CallRecord callRecord(m_sampler.get()); 11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reentryDepth++; 1148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1151e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 1152e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1153e14391e94c850b8bd03680c23b38978db68687a8John Reck result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData); 1154e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1155e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 1156e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1157e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1158e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1159e14391e94c850b8bd03680c23b38978db68687a8John Reck result = privateExecute(Normal, &m_registerFile, newCallFrame); 11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reentryDepth--; 11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*profiler) 1165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block (*profiler)->didExecute(callFrame, eval->sourceURL(), eval->lineNo()); 11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_registerFile.shrink(oldEnd); 1168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (pushedScope) 1169a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch scopeChain->pop(); 1170e14391e94c850b8bd03680c23b38978db68687a8John Reck return checkedReturn(result); 11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine) 11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Debugger* debugger = callFrame->dynamicGlobalObject()->debugger(); 11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!debugger) 11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (debugHookID) { 11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case DidEnterCallFrame: 1181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); 11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WillLeaveCallFrame: 1184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); 11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WillExecuteStatement: 1187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); 11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case WillExecuteProgram: 1190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine); 11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case DidExecuteProgram: 1193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); 11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case DidReachBreakpoint: 1196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine); 11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1201e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 1202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC) 12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1204cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = callFrame->codeBlock(); 1206cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Identifier& property = codeBlock->identifier(vPC[2].u.operand); 1207cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue value = callFrame->r(vPC[3].u.operand).jsValue(); 12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete); 12094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(scope); 12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return callFrame->scopeChain()->push(scope); 12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12145f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot) 12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Recursive invocation may already have specialized this instruction. 12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vPC[0].u.opcode != getOpcode(op_put_by_id)) 12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1220635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!baseValue.isCell()) 12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Uncacheable: give up. 12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!slot.isCacheable()) { 12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1229e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 1230635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = baseCell->structure(); 12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1232231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (structure->isUncacheableDictionary()) { 12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache miss: record Structure to compare against next time. 1238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* lastStructure = vPC[4].u.structure; 1239635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (structure != lastStructure) { 1240635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // First miss: record Structure to compare against next time. 1241635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!lastStructure) { 1242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure; 12438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Second miss: give up. 12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache hit: Specialize instruction and ref Structures. 12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If baseCell != slot.base(), then baseCell must be a proxy for another object. 12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (baseCell != slot.base()) { 12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_generic); 12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Structure transition, cache transition info 12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (slot.type() == PutPropertySlot::NewProperty) { 1261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (structure->isDictionary()) { 1262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block vPC[0] = getOpcode(op_put_by_id_generic); 1263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 1264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1265cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 1266cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // put_by_id_transition checks the prototype chain for setters. 1267cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block normalizePrototypeChain(callFrame, baseCell); 1268cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_transition); 1270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure->previousID(); 1271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[5] = structure; 1272cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC[6] = structure->prototypeChain(callFrame); 12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[7] = slot.cachedOffset(); 1274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id_replace); 12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[5] = slot.cachedOffset(); 1280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::uncachePutByID(CodeBlock* codeBlock, Instruction* vPC) 12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->derefStructures(vPC); 12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_put_by_id); 12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[4] = 0; 12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12905f1ab04193ad0130ca8204aadaceae083aca9881Feng QianNEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot) 12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Recursive invocation may already have specialized this instruction. 12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (vPC[0].u.opcode != getOpcode(op_get_by_id)) 12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Cache property access for immediates. 1297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!baseValue.isCell()) { 12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 12998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JSGlobalData* globalData = &callFrame->globalData(); 13038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) { 13048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_array_length); 13058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) { 13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_string_length); 13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Uncacheable: give up. 13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!slot.isCacheable()) { 13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1319e14391e94c850b8bd03680c23b38978db68687a8John Reck Structure* structure = baseValue.asCell()->structure(); 13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (structure->isUncacheableDictionary()) { 13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Cache miss 1327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* lastStructure = vPC[4].u.structure; 1328635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (structure != lastStructure) { 1329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // First miss: record Structure to compare against next time. 1330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!lastStructure) { 1331635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure; 13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Second miss: give up. 13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 13378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Cache hit: Specialize instruction and ref Structures. 13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (slot.slotBase() == baseValue) { 1343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (slot.cachedPropertyType()) { 1344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Getter: 1345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_getter_self); 1346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[5] = slot.cachedOffset(); 1347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Custom: 1349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_custom_self); 1350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[5] = slot.customGetter(); 1351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1352dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 1353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_self); 1354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[5] = slot.cachedOffset(); 1355dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1356dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1358635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1362643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (structure->isDictionary()) { 1363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC[0] = getOpcode(op_get_by_id_generic); 1364643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 1365643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 1366643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1367635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (slot.slotBase() == structure->prototypeForLookup(callFrame)) { 1368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(slot.slotBase().isObject()); 13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(slot.slotBase()); 1371d0825bca7fe65beaee391d30da42e937db621564Steve Block size_t offset = slot.cachedOffset(); 13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Since we're accessing a prototype in a loop, it's a good bet that it 1374635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // should not be treated as a dictionary. 1375d0825bca7fe65beaee391d30da42e937db621564Steve Block if (baseObject->structure()->isDictionary()) { 13762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block baseObject->flattenDictionaryObject(callFrame->globalData()); 1377d0825bca7fe65beaee391d30da42e937db621564Steve Block offset = baseObject->structure()->get(propertyName); 1378d0825bca7fe65beaee391d30da42e937db621564Steve Block } 1379643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 1380643ca7872b450ea4efacab6188849e5aac2ba161Steve Block ASSERT(!baseObject->structure()->isUncacheableDictionary()); 1381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (slot.cachedPropertyType()) { 1383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Getter: 1384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_getter_proto); 1385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[6] = offset; 1386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Custom: 1388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_custom_proto); 1389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[6] = slot.customGetter(); 1390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 1392dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_proto); 1393dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[6] = offset; 1394dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1395dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[5] = baseObject->structure(); 13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1398635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1402d0825bca7fe65beaee391d30da42e937db621564Steve Block size_t offset = slot.cachedOffset(); 1403d0825bca7fe65beaee391d30da42e937db621564Steve Block size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); 1404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!count) { 1405635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[0] = getOpcode(op_get_by_id_generic); 1406635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 14078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 1410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block switch (slot.cachedPropertyType()) { 1411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Getter: 1412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_getter_chain); 1413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[7] = offset; 1414dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block case PropertySlot::Custom: 1416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_custom_chain); 1417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[7] = slot.customGetter(); 1418dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1419dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block default: 1420dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[0] = getOpcode(op_get_by_id_chain); 1421dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC[7] = offset; 1422dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 1423dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1424635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC[4] = structure; 1425cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC[5] = structure->prototypeChain(callFrame); 14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[6] = count; 1427635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->refStructures(vPC); 14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectNEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction* vPC) 14318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1432635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project codeBlock->derefStructures(vPC); 14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[0] = getOpcode(op_get_by_id); 14348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC[4] = 0; 14358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 14368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1437e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif // ENABLE(INTERPRETER) 14385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1439e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame) 14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // One-time initialization of our address tables. We have to put this code 14428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // here because our labels are only in scope inside this function. 1443d0825bca7fe65beaee391d30da42e937db621564Steve Block if (UNLIKELY(flag == InitializeAndReturn)) { 1444e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke #if ENABLE(COMPUTED_GOTO_INTERPRETER) 1445d0825bca7fe65beaee391d30da42e937db621564Steve Block #define LIST_OPCODE_LABEL(id, length) &&id, 1446d0825bca7fe65beaee391d30da42e937db621564Steve Block static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) }; 1447e14391e94c850b8bd03680c23b38978db68687a8John Reck for (size_t i = 0; i < WTF_ARRAY_LENGTH(labels); ++i) 1448d0825bca7fe65beaee391d30da42e937db621564Steve Block m_opcodeTable[i] = labels[i]; 1449d0825bca7fe65beaee391d30da42e937db621564Steve Block #undef LIST_OPCODE_LABEL 1450e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke #endif // ENABLE(COMPUTED_GOTO_INTERPRETER) 14515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return JSValue(); 14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1453e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1454635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if ENABLE(JIT) 1455e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 14560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Mixing Interpreter + JIT is not supported. 1457e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (callFrame->globalData().canUseJIT()) 1458e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 1459e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT_NOT_REACHED(); 14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1461e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 1462e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if !ENABLE(INTERPRETER) 14635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UNUSED_PARAM(registerFile); 14645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UNUSED_PARAM(callFrame); 14655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return JSValue(); 14665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#else 14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSGlobalData* globalData = &callFrame->globalData(); 14695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue exceptionValue; 1470635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project HandlerInfo* handler = 0; 14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1472e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CodeBlock* codeBlock = callFrame->codeBlock(); 1473e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Instruction* vPC = codeBlock->instructions().begin(); 14748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Profiler** enabledProfilerReference = Profiler::enabledProfilerReference(); 14758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); 1476e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block JSValue functionReturnValue; 14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define CHECK_FOR_EXCEPTION() \ 14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project do { \ 14802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (UNLIKELY(globalData->exception.get() != JSValue())) { \ 14812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block exceptionValue = globalData->exception.get(); \ 14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; \ 14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } \ 14848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } while (0) 14858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 14898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define CHECK_FOR_TIMEOUT() \ 14918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!--tickCount) { \ 1492dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \ 1493635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project exceptionValue = jsNull(); \ 14948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; \ 1495635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } \ 14968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \ 14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_SAMPLING) 15008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC) 15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #define SAMPLE(codeBlock, vPC) 15038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 15048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1505e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 1506e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto *vPC->u.opcode 15078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 1508635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode); 15098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1510635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) opcode: 15118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1512635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1514e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block #define NEXT_INSTRUCTION() SAMPLE(codeBlock, vPC); goto interpreterLoopStart 15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 1516635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode); 15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #define DEFINE_OPCODE(opcode) case opcode: 15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (1) { // iterator loop begins 15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project interpreterLoopStart:; 15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (vPC->u.opcode) 15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1525635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_object) { 15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_object dst(r) 15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new empty Object instance using the original 15298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, and puts the result in register dst. 15308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1531cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 15324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(constructEmptyObject(callFrame)); 15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1534cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_object); 1535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1537635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_array) { 15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_array dst(r) firstArg(r) argCount(n) 15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new Array instance using the original 15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, and puts the result in register dst. 15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project The array will contain argCount elements with values 15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project taken from registers starting at register firstArg. 15448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1545cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1546cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int firstArg = vPC[2].u.operand; 1547cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int argCount = vPC[3].u.operand; 15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ArgList args(callFrame->registers() + firstArg, argCount); 15494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, args)); 15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1551cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_array); 1552635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen DEFINE_OPCODE(op_new_regexp) { 15556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen /* new_regexp dst(r) regExp(re) 15566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 15576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Constructs a new RegExp instance using the original 15586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen constructor from regexp regExp, and puts the result in 15596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen register dst. 15606c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen */ 15616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int dst = vPC[1].u.operand; 15626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen int regExp = vPC[2].u.operand; 15634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(new (globalData) RegExpObject(callFrame->lexicalGlobalObject(), callFrame->scopeChain()->globalObject->regExpStructure(), codeBlock->regexp(regExp))); 15646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 15656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen vPC += OPCODE_LENGTH(op_new_regexp); 15666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen NEXT_INSTRUCTION(); 15676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1568635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_mov) { 15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* mov dst(r) src(r) 15708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Copies register src to register dst. 15728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1573cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1574cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 1575a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 15764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(src); 15778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1578cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mov); 1579635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1581635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_eq) { 15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* eq dst(r) src1(r) src2(r) 15838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are equal, 15858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project as with the ECMAScript '==' operator, and puts the result 15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project as a boolean in register dst. 15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1588cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1589cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1590cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 15910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 15924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() == src2.asInt32()); 15938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 15945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2)); 1595635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 15964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 15978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 15988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1599cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_eq); 1600635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_eq_null) { 16038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* eq_null dst(r) src(r) 16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src is null, as with the ECMAScript '!=' 16068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project operator, and puts the result as a boolean in register dst. 16078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1608cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1609cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1611635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (src.isUndefinedOrNull()) { 16124576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(true); 1613cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_eq_null); 1614635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); 1618cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_eq_null); 1619635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1621635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_neq) { 16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* neq dst(r) src1(r) src2(r) 16238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are not 16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal, as with the ECMAScript '!=' operator, and puts the 16268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result as a boolean in register dst. 16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1628cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1629cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1630cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 16310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 16324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(src1.asInt32() != src2.asInt32()); 16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 16345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2)); 1635635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 16364576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1639cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_neq); 1640635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1642635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_neq_null) { 16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* neq_null dst(r) src(r) 16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src is not null, as with the ECMAScript '!=' 16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project operator, and puts the result as a boolean in register dst. 16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1648cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1649cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1651635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (src.isUndefinedOrNull()) { 16524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(false); 1653cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_neq_null); 1654635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 16568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(!src.isCell() || !src.asCell()->structure()->typeInfo().masqueradesAsUndefined()); 1658cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_neq_null); 1659635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1661635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_stricteq) { 16628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* stricteq dst(r) src1(r) src2(r) 16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are strictly 16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal, as with the ECMAScript '===' operator, and puts the 16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result as a boolean in register dst. 16678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1668cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1669cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1670cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1671e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bool result = JSValue::strictEqual(callFrame, src1, src2); 1672e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CHECK_FOR_EXCEPTION(); 16734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1675cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_stricteq); 1676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1678635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_nstricteq) { 16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* nstricteq dst(r) src1(r) src2(r) 16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 and register src2 are not 16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project strictly equal, as with the ECMAScript '!==' operator, and 16838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result as a boolean in register dst. 16848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1685cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1686cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1687cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1688e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bool result = !JSValue::strictEqual(callFrame, src1, src2); 1689e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CHECK_FOR_EXCEPTION(); 16904576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 16918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1692cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_nstricteq); 1693635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 16948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1695635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_less) { 16968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* less dst(r) src1(r) src2(r) 16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 16988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than register src2, as 16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project with the ECMAScript '<' operator, and puts the result as 17008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a boolean in register dst. 17018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1702cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1703cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1704cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 17055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(jsLess(callFrame, src1, src2)); 1706635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 17088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1709cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_less); 1710635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1712635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_lesseq) { 17138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* lesseq dst(r) src1(r) src2(r) 17148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than or equal to 17168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register src2, as with the ECMAScript '<=' operator, and 17178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result as a boolean in register dst. 17188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1719cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1720cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1721cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 17225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2)); 1723635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 17258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1726cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_lesseq); 1727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1729635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_pre_inc) { 17308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* pre_inc srcDst(r) 17318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number, adds one, and puts the result 17338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back in register srcDst. 17348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1735cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[1].u.operand; 17360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() < INT_MAX) 17384576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1); 17398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1740e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(v.toNumber(callFrame) + 1); 1741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = result; 17438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1745cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_pre_inc); 1746635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1748635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_pre_dec) { 17498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* pre_dec srcDst(r) 17508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number, subtracts one, and puts the result 17528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back in register srcDst. 17538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1754cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[1].u.operand; 17550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() > INT_MIN) 17574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1); 17588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1759e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(v.toNumber(callFrame) - 1); 1760635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = result; 17628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1764cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_pre_dec); 1765635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1767635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_post_inc) { 17688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* post_inc dst(r) srcDst(r) 17698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number. The number itself is 17718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project written to register dst, and the number plus one is written 17728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back to register srcDst. 17738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1774cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1775cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[2].u.operand; 17760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 17770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() < INT_MAX) { 17784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() + 1); 17794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = v; 17808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 17810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); 1782635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 17834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(number.uncheckedGetNumber() + 1); 17844576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = number; 17858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 17868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1787cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_post_inc); 1788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 17898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1790635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_post_dec) { 17918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* post_dec dst(r) srcDst(r) 17928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register srcDst to number. The number itself is 17948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project written to register dst, and the number minus one is written 17958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project back to register srcDst. 17968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1797cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1798cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int srcDst = vPC[2].u.operand; 17990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(srcDst).jsValue(); 18000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (v.isInt32() && v.asInt32() > INT_MIN) { 18014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(v.asInt32() - 1); 18024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = v; 18038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 18040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame); 1805635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(srcDst) = jsNumber(number.uncheckedGetNumber() - 1); 18074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = number; 18088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1810cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_post_dec); 1811635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1813635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_to_jsnumber) { 18148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* to_jsnumber dst(r) src(r) 18158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register src to number, and puts the result 18178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 18188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1819cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1820cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 18218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcVal = callFrame->r(src).jsValue(); 18238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1824635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(srcVal.isNumber())) 18254576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(src); 18268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 18275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = srcVal.toJSNumber(callFrame); 1828635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18294576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1832cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_to_jsnumber); 1833635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1835635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_negate) { 18368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* negate dst(r) src(r) 18378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register src to number, negates it, and puts the 18398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result in register dst. 18408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1841cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1842cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 1843dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow 18444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(-src.asInt32()); 18458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1846e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(-src.toNumber(callFrame)); 1847635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1851cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_negate); 1852635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1854635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_add) { 18558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* add dst(r) src1(r) src2(r) 18568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Adds register src1 and register src2, and puts the result 18588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. (JS add may be string concatenation or 18598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project numeric add, depending on the types of the operands.) 18608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1861cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1862cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1863cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1864643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow 18654576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() + src2.asInt32()); 18668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 18675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = jsAdd(callFrame, src1, src2); 1868635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18694576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1871cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_add); 1872635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1874635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_mul) { 18758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* mul dst(r) src1(r) src2(r) 18768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Multiplies register src1 and register src2 (converted to 18788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project numbers), and puts the product in register dst. 18798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1880cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1881cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1882cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 18830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow 18844576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() * src2.asInt32()); 18858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1886e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame)); 1887635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 18884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 18898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 18908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1891cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mul); 1892635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 18938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1894635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_div) { 18958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* div dst(r) dividend(r) divisor(r) 18968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 18978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Divides register dividend (converted to number) by the 18988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register divisor (converted to number), and puts the 18998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project quotient in register dst. 19008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1901cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1902cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); 1903cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); 19040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1905e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(dividend.toNumber(callFrame) / divisor.toNumber(callFrame)); 19060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CHECK_FOR_EXCEPTION(); 19074576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1909cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_div); 1910635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1912635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_mod) { 19138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* mod dst(r) dividend(r) divisor(r) 19148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Divides register dividend (converted to number) by 19168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register divisor (converted to number), and puts the 19178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project remainder in register dst. 19188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1919cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1920cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue(); 1921cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue(); 19228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) { 1924e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(dividend.asInt32() % divisor.asInt32()); 1925635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(result); 19264576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 1927cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mod); 1928635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Conversion to double must happen outside the call to fmod since the 19320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // order of argument evaluation is not guaranteed. 19330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch double d1 = dividend.toNumber(callFrame); 19340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch double d2 = divisor.toNumber(callFrame); 1935e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(fmod(d1, d2)); 1936635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 1938cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_mod); 1939635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1941635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_sub) { 19428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* sub dst(r) src1(r) src2(r) 19438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Subtracts register src2 (converted to number) from register 19458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src1 (converted to number), and puts the difference in 19468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register dst. 19478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1948cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1949cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 1950cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 1951643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow 19524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() - src2.asInt32()); 19538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1954e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame)); 1955635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19564576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1958cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_sub); 1959635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1961635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_lshift) { 19628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* lshift dst(r) val(r) shift(r) 19638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs left shift of register val (converted to int32) by 19658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register shift (converted to uint32), and puts the result 19668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 19678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1968cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1969cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); 1970cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); 19710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 19720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (val.isInt32() && shift.isInt32()) 19734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(val.asInt32() << (shift.asInt32() & 0x1f)); 19748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1975e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f)); 1976635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 19788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 19798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1980cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_lshift); 1981635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 19828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1983635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_rshift) { 19848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* rshift dst(r) val(r) shift(r) 19858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 19868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs arithmetic right shift of register val (converted 19878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to int32) by register shift (converted to 19888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32), and puts the result in register dst. 19898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1990cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 1991cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); 1992cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); 19930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 19940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (val.isInt32() && shift.isInt32()) 19954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f)); 19968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1997e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); 1998635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 19994576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2002cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_rshift); 2003635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2005635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_urshift) { 20068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* rshift dst(r) val(r) shift(r) 20078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs logical right shift of register val (converted 20098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to uint32) by register shift (converted to 20108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32), and puts the result in register dst. 20118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2012cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2013cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue val = callFrame->r(vPC[2].u.operand).jsValue(); 2014cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue shift = callFrame->r(vPC[3].u.operand).jsValue(); 20150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (val.isUInt32() && shift.isInt32()) 20164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(val.asInt32() >> (shift.asInt32() & 0x1f)); 20178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2018e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f)); 2019635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2023cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_urshift); 2024635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2026635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitand) { 20278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitand dst(r) src1(r) src2(r) 20288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise AND of register src1 (converted to int32) 20308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and register src2 (converted to int32), and puts the result 20318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 20328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2033cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2034cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 2035cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 20360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 20374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() & src2.asInt32()); 20388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2039e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame)); 2040635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2044cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitand); 2045635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2047635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitxor) { 20488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitxor dst(r) src1(r) src2(r) 20498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise XOR of register src1 (converted to int32) 20518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and register src2 (converted to int32), and puts the result 20528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 20538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2054cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2055cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 2056cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 20570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 20584576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() ^ src2.asInt32()); 20598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2060e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame)); 2061635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2065cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitxor); 2066635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2068635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitor) { 20698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitor dst(r) src1(r) src2(r) 20708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise OR of register src1 (converted to int32) 20728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and register src2 (converted to int32), and puts the 20738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result in register dst. 20748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2075cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2076cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue(); 2077cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue(); 20780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src1.isInt32() && src2.isInt32()) 20794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(src1.asInt32() | src2.asInt32()); 20808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2081e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame)); 2082635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 20834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 20848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 20858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2086cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitor); 2087635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 20888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2089635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_bitnot) { 20908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* bitnot dst(r) src(r) 20918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 20928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes bitwise NOT of register src1 (converted to int32), 20938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and puts the result in register dst. 20948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2095cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2096cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src = callFrame->r(vPC[2].u.operand).jsValue(); 20970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (src.isInt32()) 20984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(~src.asInt32()); 20998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2100e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = jsNumber(~src.toInt32(callFrame)); 2101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 21024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 21038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2104cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_bitnot); 2105635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_not) { 21088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* not dst(r) src(r) 21098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Computes logical NOT of register src (converted to 21118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boolean), and puts the result in register dst. 21128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2113cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2114cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 21150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame)); 2116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 21174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 21188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2119cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_not); 2120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 21226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner DEFINE_OPCODE(op_check_has_instance) { 21236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner /* check_has_instance constructor(r) 21246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 21256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Check 'constructor' is an object with the internal property 21266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner [HasInstance] (i.e. is a function ... *shakes head sadly at 21276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSC API*). Raises an exception if register constructor is not 21286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner an valid parameter for instanceof. 21296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner */ 21306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner int base = vPC[1].u.operand; 21316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner JSValue baseVal = callFrame->r(base).jsValue(); 21326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 21336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue)) 21346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner goto vm_throw; 21356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 21366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner vPC += OPCODE_LENGTH(op_check_has_instance); 21376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner NEXT_INSTRUCTION(); 21386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_instanceof) { 21408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* instanceof dst(r) value(r) constructor(r) constructorProto(r) 21418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Tests whether register value is an instance of register 21438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, and puts the boolean result in register 21448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst. Register constructorProto must contain the "prototype" 21458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property (not the actual prototype) of the object in 21468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register constructor. This lookup is separated so that 21478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project polymorphic inline caching can apply. 21488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Raises an exception if register constructor is not an 21508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object. 21518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 21528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 21538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[2].u.operand; 21548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[3].u.operand; 21558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int baseProto = vPC[4].u.operand; 21568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseVal = callFrame->r(base).jsValue(); 21588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(!isInvalidParamForInstanceOf(callFrame, baseVal, exceptionValue)); 21608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool result = asObject(baseVal)->hasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue()); 21625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 21634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 21648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_instanceof); 2166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_typeof) { 21698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* typeof dst(r) src(r) 21708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines the type string for src according to ECMAScript 21728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project rules, and puts the result in register dst. 21738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2174cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2175cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 21764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue())); 21778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_typeof); 2179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_undefined) { 21828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_undefined dst(r) src(r) 21838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 21858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "undefined", and puts the result 21868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 21878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 21900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(src).jsValue(); 21914576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()); 21928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2193cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_undefined); 2194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 21958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_boolean) { 21978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_boolean dst(r) src(r) 21988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 21998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "boolean", and puts the result 22018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2204cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean()); 22068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2207cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_boolean); 2208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_number) { 22118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_number dst(r) src(r) 22128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "number", and puts the result 22158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2217cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2218cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber()); 22208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2221cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_number); 2222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2224635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_string) { 22258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_string dst(r) src(r) 22268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "string", and puts the result 22298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2231cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2232cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22334576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(callFrame->r(src).jsValue().isString()); 22348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2235cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_string); 2236635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2238635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_object) { 22398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_object dst(r) src(r) 22408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "object", and puts the result 22438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2245cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2246cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue())); 22488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2249cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_object); 2250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2252635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_is_function) { 22538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* is_function dst(r) src(r) 22548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Determines whether the type string for src according to 22568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the ECMAScript rules is "function", and puts the result 22578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. 22588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2259cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2260cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 22614576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue())); 22628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2263cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_is_function); 2264635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_in) { 22678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* in dst(r) property(r) base(r) 22688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Tests whether register base has a property named register 22708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property, and puts the boolean result in register dst. 22718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Raises an exception if register constructor is not an 22738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object. 22748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2275cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2276cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 2277cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[3].u.operand; 22788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseVal = callFrame->r(base).jsValue(); 22806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (isInvalidParamForIn(callFrame, baseVal, exceptionValue)) 22818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 22828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObj = asObject(baseVal); 22848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue propName = callFrame->r(property).jsValue(); 22868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 22878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32_t i; 2288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (propName.getUInt32(i)) 22894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i)); 22908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, propName.toString(callFrame)); 2292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 22934576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property)); 22948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 22958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2296cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_in); 2297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 22988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2299635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve) { 23008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve dst(r) property(id) 23018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Looks up the property named by identifier property in the 23038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scope chain, and writes the resulting value to register 23048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst. If the property is not found, raises an exception. 23058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 23068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue))) 23078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 23088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2309cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve); 2310635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2312635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_skip) { 23138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve_skip dst(r) property(id) skip(n) 23148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Looks up the property named by identifier property in the 23168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scope chain skipping the top 'skip' levels, and writes the resulting 23178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value to register dst. If the property is not found, raises an exception. 23188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 23198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue))) 23208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 23218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2322cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_skip); 23238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_global) { 2327635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n) 23288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a dynamic property lookup for the given property, on the provided 2330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project global object. If structure matches the Structure of the global then perform 23318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a fast lookup using the case offset, otherwise fall back to a full resolve and 2332635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project cache the new structure and offset 23338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 23348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue))) 23358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 23368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2337cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_global); 23388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 23416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen DEFINE_OPCODE(op_resolve_global_dynamic) { 23426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n) 23436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Performs a dynamic property lookup for the given property, on the provided 23456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen global object. If structure matches the Structure of the global then perform 23466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen a fast lookup using the case offset, otherwise fall back to a full resolve and 23476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen cache the new structure and offset. 23486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen This walks through n levels of the scope chain to verify that none of those levels 23506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen in the scope chain include dynamically added properties. 23516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen */ 23526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (UNLIKELY(!resolveGlobalDynamic(callFrame, vPC, exceptionValue))) 23536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen goto vm_throw; 23546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen vPC += OPCODE_LENGTH(op_resolve_global_dynamic); 23566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 23576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen NEXT_INSTRUCTION(); 23586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_global_var) { 23608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* get_global_var dst(r) globalObject(c) index(n) 23618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Gets the global var at global slot index and places it in register dst. 23638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2364cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2365dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JSGlobalObject* scope = codeBlock->globalObject(); 23668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->isGlobalObject()); 2367dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int index = vPC[2].u.operand; 23688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23694576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = scope->registerAt(index); 2370cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_global_var); 2371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_global_var) { 23748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_global_var globalObject(c) index(n) value(r) 23758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Puts value into global slot index. 23778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2378dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch JSGlobalObject* scope = codeBlock->globalObject(); 23798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scope->isGlobalObject()); 2380dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int index = vPC[1].u.operand; 2381dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch int value = vPC[2].u.operand; 23828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); 2384cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_global_var); 2385635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 23866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 2387635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_scoped_var) { 23888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* get_scoped_var dst(r) index(n) skip(n) 23898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Loads the contents of the index-th local from the scope skip nodes from 2391e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block the top of the scope chain, and places it in register dst. 23928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2393cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 2394cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int index = vPC[2].u.operand; 2395e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int skip = vPC[3].u.operand; 23968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 23978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 23988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 23998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 24008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 2401a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock == callFrame->codeBlock()); 2402a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); 2403a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(skip || !checkTopLevel); 2404a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkTopLevel && skip--) { 2405a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (callFrame->r(codeBlock->activationRegister()).jsValue()) 2406a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++iter; 2407a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 24088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (skip--) { 24098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++iter; 24108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 24118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT((*iter)->isVariableObject()); 24132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get()); 24144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = scope->registerAt(index); 2415a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(callFrame->r(dst).jsValue()); 2416cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_scoped_var); 2417635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_scoped_var) { 24208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_scoped_var index(n) skip(n) value(r) 24218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 2423cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int index = vPC[1].u.operand; 2424e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int skip = vPC[2].u.operand; 2425cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int value = vPC[3].u.operand; 24268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 24288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator iter = scopeChain->begin(); 24298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainIterator end = scopeChain->end(); 2430a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock == callFrame->codeBlock()); 24318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 2432a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); 2433a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(skip || !checkTopLevel); 2434a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (checkTopLevel && skip--) { 2435a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (callFrame->r(codeBlock->activationRegister()).jsValue()) 2436a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ++iter; 2437a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 24388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (skip--) { 24398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++iter; 24408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(iter != end); 24418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 24428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT((*iter)->isVariableObject()); 24442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get()); 2445a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(callFrame->r(value).jsValue()); 24460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); 2447cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_scoped_var); 2448635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_base) { 24518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve_base dst(r) property(id) 24528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Searches the scope chain for an object containing 24548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project identifier property, and if one is found, writes it to 24558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register dst. If none is found, the outermost scope (which 24568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project will be the global object) is stored in register dst. 24578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 24588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolveBase(callFrame, vPC); 24598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2460cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_base); 2461635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2463a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch DEFINE_OPCODE(op_ensure_property_exists) { 2464a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /* ensure_property_exists base(r) property(id) 2465a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2466a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Throws an exception if property does not exist on base 2467a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */ 2468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int base = vPC[1].u.operand; 2469a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int property = vPC[2].u.operand; 2470a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Identifier& ident = codeBlock->identifier(property); 2471a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 2472a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue baseVal = callFrame->r(base).jsValue(); 2473a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSObject* baseObject = asObject(baseVal); 2474a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PropertySlot slot(baseVal); 2475a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!baseObject->getPropertySlot(callFrame, ident, slot)) { 2476a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring()); 2477a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch goto vm_throw; 2478a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2479a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch NEXT_INSTRUCTION(); 2480a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 2481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_resolve_with_base) { 24828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* resolve_with_base baseDst(r) propDst(r) property(id) 24838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Searches the scope chain for an object containing 24858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project identifier property, and if one is found, writes it to 24868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register srcDst, and the retrieved property value to register 24878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project propDst. If the property is not found, raises an exception. 24888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 24898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This is more efficient than doing resolve_base followed by 24908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project resolve, or resolve_base followed by get_by_id, as it 24918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project avoids duplicate hash lookups. 24928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 24938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue))) 24948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 24958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2496cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_resolve_with_base); 2497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 24988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2499635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id) { 2500635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n) 25018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Gets the property named by identifier 25038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property from the value base, and puts the result in register dst. 25048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 25068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 25078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[3].u.operand; 25088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2509635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 25100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 25118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(baseValue); 25125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = baseValue.get(callFrame, ident, slot); 2513635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 25148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot); 25168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25174576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2518cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id); 2519635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2521635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_self) { 2522635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n) 25238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to get a cached property from the 25258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value base. If the cache misses, op_get_by_id_self reverts to 25268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project op_get_by_id. 25278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 25290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 25308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 2532e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 25348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2535635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 25368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(baseCell->isObject()); 25378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(baseCell); 25388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 25398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = vPC[5].u.operand; 25408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2541e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); 25424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset)); 25438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2544cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_self); 2545635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2549e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2550635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2552635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_proto) { 2553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n) 25548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 25558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to get a cached property from the 25568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value base's prototype. If the cache misses, op_get_by_id_proto 25578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_get_by_id. 25588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 25600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 25618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2562635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 2563e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2564635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 25658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 2567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(structure->prototypeForLookup(callFrame).isObject()); 2568635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 2569635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* prototypeStructure = vPC[5].u.structure; 25708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2571635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(protoObject->structure() == prototypeStructure)) { 25728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 25738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = vPC[6].u.operand; 25748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2575e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(protoObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); 2576e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset)); 25774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(protoObject->getDirectOffset(offset)); 25788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2579cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_proto); 2580635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 25848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2585e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2586635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 25878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2588bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2589692e5dbf12901edacf14812a6fae25462920af42Steve Block goto *(&&skip_id_getter_proto); 2590692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2591692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_proto) { 2592692e5dbf12901edacf14812a6fae25462920af42Steve Block /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n) 2593692e5dbf12901edacf14812a6fae25462920af42Steve Block 2594692e5dbf12901edacf14812a6fae25462920af42Steve Block Cached property access: Attempts to get a cached getter property from the 2595692e5dbf12901edacf14812a6fae25462920af42Steve Block value base's prototype. If the cache misses, op_get_by_id_getter_proto 2596692e5dbf12901edacf14812a6fae25462920af42Steve Block reverts to op_get_by_id. 2597692e5dbf12901edacf14812a6fae25462920af42Steve Block */ 2598692e5dbf12901edacf14812a6fae25462920af42Steve Block int base = vPC[2].u.operand; 2599692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue baseValue = callFrame->r(base).jsValue(); 2600692e5dbf12901edacf14812a6fae25462920af42Steve Block 2601692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseValue.isCell())) { 2602e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2603692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* structure = vPC[4].u.structure; 2604692e5dbf12901edacf14812a6fae25462920af42Steve Block 2605692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseCell->structure() == structure)) { 2606692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(structure->prototypeForLookup(callFrame).isObject()); 2607692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 2608692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* prototypeStructure = vPC[5].u.structure; 2609692e5dbf12901edacf14812a6fae25462920af42Steve Block 2610692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(protoObject->structure() == prototypeStructure)) { 2611692e5dbf12901edacf14812a6fae25462920af42Steve Block int dst = vPC[1].u.operand; 2612692e5dbf12901edacf14812a6fae25462920af42Steve Block int offset = vPC[6].u.operand; 2613692e5dbf12901edacf14812a6fae25462920af42Steve Block if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) { 2614692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* getter = getterSetter->getter(); 2615692e5dbf12901edacf14812a6fae25462920af42Steve Block CallData callData; 2616692e5dbf12901edacf14812a6fae25462920af42Steve Block CallType callType = getter->getCallData(callData); 2617692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList()); 2618692e5dbf12901edacf14812a6fae25462920af42Steve Block CHECK_FOR_EXCEPTION(); 26194576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2620692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 26214576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsUndefined(); 2622692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_getter_proto); 2623692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2624692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2625692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2626692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2627e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2628692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2629692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2630bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2631692e5dbf12901edacf14812a6fae25462920af42Steve Block skip_id_getter_proto: 2632692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2633bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2634dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block goto *(&&skip_id_custom_proto); 2635dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2636dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_proto) { 2637dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n) 2638dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2639dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Cached property access: Attempts to use a cached named property getter 2640dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block from the value base's prototype. If the cache misses, op_get_by_id_custom_proto 2641dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block reverts to op_get_by_id. 2642dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 2643dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int base = vPC[2].u.operand; 2644dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 2645dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2646dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseValue.isCell())) { 2647e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2648dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* structure = vPC[4].u.structure; 2649dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2650dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseCell->structure() == structure)) { 2651dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(structure->prototypeForLookup(callFrame).isObject()); 2652dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame)); 2653dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* prototypeStructure = vPC[5].u.structure; 2654dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2655dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(protoObject->structure() == prototypeStructure)) { 2656dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int dst = vPC[1].u.operand; 2657dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int property = vPC[3].u.operand; 2658e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 2659dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2660dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc; 2661dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = getter(callFrame, protoObject, ident); 2662dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CHECK_FOR_EXCEPTION(); 26634576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2664dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_proto); 2665dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2666dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2667dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2668dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2669e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2670dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2671dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2672bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2673dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block skip_id_custom_proto: 2674dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2675635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_self_list) { 2676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Polymorphic self access caching currently only supported when JITting. 2677635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT_NOT_REACHED(); 2678635860845790a19bf50bbc51ba8fb66a96dde068The 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)! 2679cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_self_list); 2680635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 2681635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 2682635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_proto_list) { 2683635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Polymorphic prototype access caching currently only supported when JITting. 2684635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT_NOT_REACHED(); 2685635860845790a19bf50bbc51ba8fb66a96dde068The 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)! 2686cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_proto_list); 2687635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 2688635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 2689692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_self_list) { 2690692e5dbf12901edacf14812a6fae25462920af42Steve Block // Polymorphic self access caching currently only supported when JITting. 2691692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT_NOT_REACHED(); 2692692e5dbf12901edacf14812a6fae25462920af42Steve Block // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! 2693692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_self_list); 2694692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2695692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2696692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_proto_list) { 2697692e5dbf12901edacf14812a6fae25462920af42Steve Block // Polymorphic prototype access caching currently only supported when JITting. 2698692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT_NOT_REACHED(); 2699692e5dbf12901edacf14812a6fae25462920af42Steve Block // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! 2700692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_proto_list); 2701692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2702692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2703dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_self_list) { 2704dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Polymorphic self access caching currently only supported when JITting. 2705dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT_NOT_REACHED(); 2706dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)! 2707dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_self_list); 2708dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2709dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2710dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_proto_list) { 2711dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Polymorphic prototype access caching currently only supported when JITting. 2712dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT_NOT_REACHED(); 2713dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)! 2714dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_proto_list); 2715dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2716dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_chain) { 2718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n) 27198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to get a cached property from the 27218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value base's prototype chain. If the cache misses, op_get_by_id_chain 27228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_get_by_id. 27238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 27248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 27250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 27268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2727635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 2728e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2729635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 27308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2731635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 2732635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RefPtr<Structure>* it = vPC[5].u.structureChain->head(); 27338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t count = vPC[6].u.operand; 2734635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RefPtr<Structure>* end = it + count; 27358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2736635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (true) { 2737635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame)); 2738635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2739635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (UNLIKELY(baseObject->structure() != (*it).get())) 27408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 27418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 27428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (++it == end) { 27438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 27448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int offset = vPC[7].u.operand; 27458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2746e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); 2747e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseValue.get(callFrame, codeBlock->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset)); 27484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(baseObject->getDirectOffset(offset)); 27498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2750cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_chain); 2751635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 27528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2753635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2754635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype. 2755635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project baseCell = baseObject; 27568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 27598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2760e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2761635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 27628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2763bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2764692e5dbf12901edacf14812a6fae25462920af42Steve Block goto *(&&skip_id_getter_self); 2765692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2766692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_self) { 2767692e5dbf12901edacf14812a6fae25462920af42Steve Block /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n) 2768692e5dbf12901edacf14812a6fae25462920af42Steve Block 2769692e5dbf12901edacf14812a6fae25462920af42Steve Block Cached property access: Attempts to get a cached property from the 2770692e5dbf12901edacf14812a6fae25462920af42Steve Block value base. If the cache misses, op_get_by_id_getter_self reverts to 2771692e5dbf12901edacf14812a6fae25462920af42Steve Block op_get_by_id. 2772692e5dbf12901edacf14812a6fae25462920af42Steve Block */ 2773692e5dbf12901edacf14812a6fae25462920af42Steve Block int base = vPC[2].u.operand; 2774692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue baseValue = callFrame->r(base).jsValue(); 2775692e5dbf12901edacf14812a6fae25462920af42Steve Block 2776692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseValue.isCell())) { 2777e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2778692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* structure = vPC[4].u.structure; 2779692e5dbf12901edacf14812a6fae25462920af42Steve Block 2780692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseCell->structure() == structure)) { 2781692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(baseCell->isObject()); 2782692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* baseObject = asObject(baseCell); 2783692e5dbf12901edacf14812a6fae25462920af42Steve Block int dst = vPC[1].u.operand; 2784692e5dbf12901edacf14812a6fae25462920af42Steve Block int offset = vPC[5].u.operand; 2785692e5dbf12901edacf14812a6fae25462920af42Steve Block 2786692e5dbf12901edacf14812a6fae25462920af42Steve Block if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) { 2787692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* getter = getterSetter->getter(); 2788692e5dbf12901edacf14812a6fae25462920af42Steve Block CallData callData; 2789692e5dbf12901edacf14812a6fae25462920af42Steve Block CallType callType = getter->getCallData(callData); 2790692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue result = call(callFrame, getter, callType, callData, baseObject, ArgList()); 2791692e5dbf12901edacf14812a6fae25462920af42Steve Block CHECK_FOR_EXCEPTION(); 27924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2793692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 27944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsUndefined(); 2795692e5dbf12901edacf14812a6fae25462920af42Steve Block 2796692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_getter_self); 2797692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2798692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2799692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2800e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2801692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2802692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2803bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2804692e5dbf12901edacf14812a6fae25462920af42Steve Block skip_id_getter_self: 2805692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2806bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2807dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block goto *(&&skip_id_custom_self); 2808dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2809dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_self) { 2810dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block /* op_get_by_id_custom_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n) 2811dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2812dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Cached property access: Attempts to use a cached named property getter 2813dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block from the value base. If the cache misses, op_get_by_id_custom_self reverts to 2814dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block op_get_by_id. 2815dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 2816dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int base = vPC[2].u.operand; 2817dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 2818dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2819dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseValue.isCell())) { 2820e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2821dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* structure = vPC[4].u.structure; 2822dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2823dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseCell->structure() == structure)) { 2824dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(baseCell->isObject()); 2825dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int dst = vPC[1].u.operand; 2826dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int property = vPC[3].u.operand; 2827e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 2828dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2829dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PropertySlot::GetValueFunc getter = vPC[5].u.getterFunc; 2830dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = getter(callFrame, baseValue, ident); 2831dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CHECK_FOR_EXCEPTION(); 28324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2833dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_self); 2834dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2835dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2836dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2837e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2838dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2839dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2840bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2841dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockskip_id_custom_self: 2842dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2843635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_id_generic) { 28448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n) 28458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Gets the property named by identifier 28478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property from the value base, and puts the result in register dst. 28488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 28498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 28508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 28518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[3].u.operand; 28528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2853e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 28540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 28558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project PropertySlot slot(baseValue); 28565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result = baseValue.get(callFrame, ident, slot); 2857635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 28588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 28594576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2860cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_id_generic); 2861635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 28628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2863bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2864692e5dbf12901edacf14812a6fae25462920af42Steve Block goto *(&&skip_id_getter_chain); 2865692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2866692e5dbf12901edacf14812a6fae25462920af42Steve Block DEFINE_OPCODE(op_get_by_id_getter_chain) { 2867692e5dbf12901edacf14812a6fae25462920af42Steve Block /* op_get_by_id_getter_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n) 2868692e5dbf12901edacf14812a6fae25462920af42Steve Block 2869692e5dbf12901edacf14812a6fae25462920af42Steve Block Cached property access: Attempts to get a cached property from the 2870692e5dbf12901edacf14812a6fae25462920af42Steve Block value base's prototype chain. If the cache misses, op_get_by_id_getter_chain 2871692e5dbf12901edacf14812a6fae25462920af42Steve Block reverts to op_get_by_id. 2872692e5dbf12901edacf14812a6fae25462920af42Steve Block */ 2873692e5dbf12901edacf14812a6fae25462920af42Steve Block int base = vPC[2].u.operand; 2874692e5dbf12901edacf14812a6fae25462920af42Steve Block JSValue baseValue = callFrame->r(base).jsValue(); 2875692e5dbf12901edacf14812a6fae25462920af42Steve Block 2876692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseValue.isCell())) { 2877e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2878692e5dbf12901edacf14812a6fae25462920af42Steve Block Structure* structure = vPC[4].u.structure; 2879692e5dbf12901edacf14812a6fae25462920af42Steve Block 2880692e5dbf12901edacf14812a6fae25462920af42Steve Block if (LIKELY(baseCell->structure() == structure)) { 2881692e5dbf12901edacf14812a6fae25462920af42Steve Block RefPtr<Structure>* it = vPC[5].u.structureChain->head(); 2882692e5dbf12901edacf14812a6fae25462920af42Steve Block size_t count = vPC[6].u.operand; 2883692e5dbf12901edacf14812a6fae25462920af42Steve Block RefPtr<Structure>* end = it + count; 2884692e5dbf12901edacf14812a6fae25462920af42Steve Block 2885692e5dbf12901edacf14812a6fae25462920af42Steve Block while (true) { 2886692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame)); 2887692e5dbf12901edacf14812a6fae25462920af42Steve Block 2888692e5dbf12901edacf14812a6fae25462920af42Steve Block if (UNLIKELY(baseObject->structure() != (*it).get())) 2889692e5dbf12901edacf14812a6fae25462920af42Steve Block break; 2890692e5dbf12901edacf14812a6fae25462920af42Steve Block 2891692e5dbf12901edacf14812a6fae25462920af42Steve Block if (++it == end) { 2892692e5dbf12901edacf14812a6fae25462920af42Steve Block int dst = vPC[1].u.operand; 2893692e5dbf12901edacf14812a6fae25462920af42Steve Block int offset = vPC[7].u.operand; 2894692e5dbf12901edacf14812a6fae25462920af42Steve Block if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) { 2895692e5dbf12901edacf14812a6fae25462920af42Steve Block JSObject* getter = getterSetter->getter(); 2896692e5dbf12901edacf14812a6fae25462920af42Steve Block CallData callData; 2897692e5dbf12901edacf14812a6fae25462920af42Steve Block CallType callType = getter->getCallData(callData); 2898dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList()); 2899692e5dbf12901edacf14812a6fae25462920af42Steve Block CHECK_FOR_EXCEPTION(); 29004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2901692e5dbf12901edacf14812a6fae25462920af42Steve Block } else 29024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsUndefined(); 2903692e5dbf12901edacf14812a6fae25462920af42Steve Block vPC += OPCODE_LENGTH(op_get_by_id_getter_chain); 2904692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2905692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2906692e5dbf12901edacf14812a6fae25462920af42Steve Block 2907692e5dbf12901edacf14812a6fae25462920af42Steve Block // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype. 2908692e5dbf12901edacf14812a6fae25462920af42Steve Block baseCell = baseObject; 2909692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2910692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2911692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2912e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2913692e5dbf12901edacf14812a6fae25462920af42Steve Block NEXT_INSTRUCTION(); 2914692e5dbf12901edacf14812a6fae25462920af42Steve Block } 2915bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2916692e5dbf12901edacf14812a6fae25462920af42Steve Block skip_id_getter_chain: 2917692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 2918bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2919dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block goto *(&&skip_id_custom_chain); 2920dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2921dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block DEFINE_OPCODE(op_get_by_id_custom_chain) { 2922dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block /* op_get_by_id_custom_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n) 2923dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2924dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Cached property access: Attempts to use a cached named property getter on the 2925dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block value base's prototype chain. If the cache misses, op_get_by_id_custom_chain 2926dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block reverts to op_get_by_id. 2927dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 2928dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int base = vPC[2].u.operand; 2929dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 2930dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2931dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseValue.isCell())) { 2932e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 2933dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block Structure* structure = vPC[4].u.structure; 2934dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2935dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (LIKELY(baseCell->structure() == structure)) { 2936dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RefPtr<Structure>* it = vPC[5].u.structureChain->head(); 2937dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block size_t count = vPC[6].u.operand; 2938dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RefPtr<Structure>* end = it + count; 2939dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2940dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block while (true) { 2941dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame)); 2942dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2943dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (UNLIKELY(baseObject->structure() != (*it).get())) 2944dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block break; 2945dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2946dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (++it == end) { 2947dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int dst = vPC[1].u.operand; 2948dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block int property = vPC[3].u.operand; 2949e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 2950dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2951dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block PropertySlot::GetValueFunc getter = vPC[7].u.getterFunc; 2952dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSValue result = getter(callFrame, baseObject, ident); 2953dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CHECK_FOR_EXCEPTION(); 29544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 2955dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block vPC += OPCODE_LENGTH(op_get_by_id_custom_chain); 2956dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2957dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2958dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 2959dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype. 2960dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block baseCell = baseObject; 2961dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2962dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2963dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2964e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2965dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block NEXT_INSTRUCTION(); 2966dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 2967bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#if USE(GCC_COMPUTED_GOTO_WORKAROUND) 2968dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block skip_id_custom_chain: 2969dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 2970635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_array_length) { 29718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n) 29728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Gets the length of the array in register base, 29748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and puts the result in register dst. If register base does not hold 29758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project an array, op_get_array_length reverts to op_get_by_id. 29768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 29778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 29790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 29808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (LIKELY(isJSArray(globalData, baseValue))) { 29818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 29824576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(asArray(baseValue)->length()); 2983cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_array_length); 2984635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 29858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 29868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2987e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 2988635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 29898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2990635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_string_length) { 29918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n) 29928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Gets the length of the string in register base, 29948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and puts the result in register dst. If register base does not hold 29958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project a string, op_get_string_length reverts to op_get_by_id. 29968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 29978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[2].u.operand; 29990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 30008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (LIKELY(isJSString(globalData, baseValue))) { 30018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int dst = vPC[1].u.operand; 30024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(asString(baseValue)->length()); 3003cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_string_length); 3004635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3007e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncacheGetByID(codeBlock, vPC); 3008635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3010635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id) { 3011e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b) 30128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Sets the property named by identifier 30148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property, belonging to register base, to register value. 30158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 30178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 3018e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 3019e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke The "direct" flag should only be set this put_by_id is to initialize 3020e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke an object literal. 30218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 30228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 30248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[2].u.operand; 30258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 3026e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int direct = vPC[8].u.operand; 30278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 3029635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier& ident = codeBlock->identifier(property); 3030a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PutPropertySlot slot(codeBlock->isStrictMode()); 3031e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (direct) { 3032e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); 3033e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT(slot.base() == baseValue); 3034e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } else 3035e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 3036635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 30378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot); 30398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3040cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id); 3041635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3043635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id_transition) { 3044e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b) 30458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to set a new property with a cached transition 30478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property named by identifier property, belonging to register base, 30488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register value. If the cache misses, op_put_by_id_transition 30498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_put_by_id_generic. 30508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 30528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 30538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 30548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 30550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 30568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3057635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 3058e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 3059635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* oldStructure = vPC[4].u.structure; 3060635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* newStructure = vPC[5].u.structure; 30618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3062635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == oldStructure)) { 30638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(baseCell->isObject()); 30648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(baseCell); 3065e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int direct = vPC[8].u.operand; 3066e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 3067e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (!direct) { 3068e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke RefPtr<Structure>* it = vPC[6].u.structureChain->head(); 3069e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 3070e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke JSValue proto = baseObject->structure()->prototypeForLookup(callFrame); 3071e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke while (!proto.isNull()) { 3072e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (UNLIKELY(asObject(proto)->structure() != (*it).get())) { 3073e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke uncachePutByID(codeBlock, vPC); 3074e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke NEXT_INSTRUCTION(); 3075e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } 3076e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ++it; 3077e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke proto = asObject(proto)->structure()->prototypeForLookup(callFrame); 30788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3080635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project baseObject->transitionTo(newStructure); 30818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 30838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned offset = vPC[7].u.operand; 3084e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(codeBlock->identifier(vPC[2].u.operand))) == offset); 30852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue()); 30868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3087cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id_transition); 3088635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 30918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3092e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncachePutByID(codeBlock, vPC); 3093635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 30948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3095635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id_replace) { 3096e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b) 30978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Cached property access: Attempts to set a pre-existing, cached 30998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property named by identifier property, belonging to register base, 31008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register value. If the cache misses, op_put_by_id_replace 31018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project reverts to op_put_by_id. 31028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 31048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 31058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 31068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 31070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 31088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseValue.isCell())) { 3110e14391e94c850b8bd03680c23b38978db68687a8John Reck JSCell* baseCell = baseValue.asCell(); 3111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Structure* structure = vPC[4].u.structure; 31128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (LIKELY(baseCell->structure() == structure)) { 31148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(baseCell->isObject()); 31158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSObject* baseObject = asObject(baseCell); 31168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 31178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned offset = vPC[5].u.operand; 31188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3119e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(codeBlock->identifier(vPC[2].u.operand))) == offset); 31202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue()); 31218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3122cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id_replace); 3123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 31248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 31268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3127e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block uncachePutByID(codeBlock, vPC); 3128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 31298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_id_generic) { 3131e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b) 31328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Generic property access: Sets the property named by identifier 31348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project property, belonging to register base, to register value. 31358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 31378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 31388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 31398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int base = vPC[1].u.operand; 31408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int property = vPC[2].u.operand; 31418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int value = vPC[3].u.operand; 3142e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int direct = vPC[8].u.operand; 31438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 3145e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 3146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PutPropertySlot slot(codeBlock->isStrictMode()); 3147e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (direct) { 3148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot); 3149e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke ASSERT(slot.base() == baseValue); 3150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke } else 3151e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot); 3152635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 31538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3154cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_id_generic); 3155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 31568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_del_by_id) { 31588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* del_by_id dst(r) base(r) property(id) 31598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register base to Object, deletes the property 31618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project named by identifier property from the object, and writes a 31628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boolean indicating success (if true) or failure (if false) 31638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register dst. 31648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3165cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3166cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3167cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 31688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 31690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); 3170e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 3171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool result = baseObj->deleteProperty(callFrame, ident); 3172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!result && codeBlock->isStrictMode()) { 3173a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch exceptionValue = createTypeError(callFrame, "Unable to delete property."); 3174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch goto vm_throw; 3175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 31774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 3178cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_del_by_id); 3179cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 3180cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 3181cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block DEFINE_OPCODE(op_get_by_pname) { 3182cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3183cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3184cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 3185cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int expected = vPC[4].u.operand; 3186cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int iter = vPC[5].u.operand; 3187cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int i = vPC[6].u.operand; 3188cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 3189cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue baseValue = callFrame->r(base).jsValue(); 3190cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 3191cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue subscript = callFrame->r(property).jsValue(); 3192cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue expectedSubscript = callFrame->r(expected).jsValue(); 3193cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int index = callFrame->r(i).i() - 1; 3194cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue result; 3195cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int offset = 0; 3196cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) { 31974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(asObject(baseValue)->getDirectOffset(offset)); 3198cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_pname); 3199cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 3200cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 3201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch { 3202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch Identifier propertyName(callFrame, subscript.toString(callFrame)); 3203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch result = baseValue.get(callFrame, propertyName); 3204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 3205cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block CHECK_FOR_EXCEPTION(); 32064576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 3207cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_pname); 3208635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 32098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3210bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen DEFINE_OPCODE(op_get_arguments_length) { 3211bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int dst = vPC[1].u.operand; 3212bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int argumentsRegister = vPC[2].u.operand; 3213bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int property = vPC[3].u.operand; 3214bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue arguments = callFrame->r(argumentsRegister).jsValue(); 3215bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (arguments) { 3216bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Identifier& ident = codeBlock->identifier(property); 3217bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen PropertySlot slot(arguments); 3218bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue result = arguments.get(callFrame, ident, slot); 3219bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen CHECK_FOR_EXCEPTION(); 32204576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 3221bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } else 32224576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsNumber(callFrame->argumentCount()); 3223bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 3224bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen vPC += OPCODE_LENGTH(op_get_arguments_length); 3225bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NEXT_INSTRUCTION(); 3226bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3227bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen DEFINE_OPCODE(op_get_argument_by_val) { 3228bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int dst = vPC[1].u.operand; 3229bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int argumentsRegister = vPC[2].u.operand; 3230bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int property = vPC[3].u.operand; 3231bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue arguments = callFrame->r(argumentsRegister).jsValue(); 3232bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen JSValue subscript = callFrame->r(property).jsValue(); 3233bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!arguments && subscript.isUInt32() && subscript.asUInt32() < callFrame->argumentCount()) { 3234bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen unsigned arg = subscript.asUInt32() + 1; 3235bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen unsigned numParameters = callFrame->codeBlock()->m_numParameters; 3236bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (arg < numParameters) 32374576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(arg - RegisterFile::CallFrameHeaderSize - numParameters); 3238bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen else 32394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(arg - RegisterFile::CallFrameHeaderSize - numParameters - callFrame->argumentCount() - 1); 3240bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen vPC += OPCODE_LENGTH(op_get_argument_by_val); 3241bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen NEXT_INSTRUCTION(); 3242bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3243bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!arguments) { 3244bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Arguments* arguments = new (globalData) Arguments(callFrame); 32454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(argumentsRegister) = JSValue(arguments); 32464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(unmodifiedArgumentsRegister(argumentsRegister)) = JSValue(arguments); 3247bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3248bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen // fallthrough 3249bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen } 3250635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_by_val) { 32518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* get_by_val dst(r) base(r) property(r) 32528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register base to Object, gets the property named 32548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by register property from the object, and puts the result 32558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in register dst. property is nominally converted to string 32568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project but numbers are treated more efficiently. 32578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3258cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3259cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3260cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 32618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 32630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue subscript = callFrame->r(property).jsValue(); 32648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue result; 32668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (LIKELY(subscript.isUInt32())) { 32680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint32_t i = subscript.asUInt32(); 32698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSArray(globalData, baseValue)) { 32708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSArray* jsArray = asArray(baseValue); 32718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (jsArray->canGetIndex(i)) 32728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = jsArray->getIndex(i); 32738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 32748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = jsArray->JSArray::get(callFrame, i); 32758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) 3276643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = asString(baseValue)->getIndex(callFrame, i); 32778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) 3278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project result = asByteArray(baseValue)->getIndex(callFrame, i); 32798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project result = baseValue.get(callFrame, i); 32818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, subscript.toString(callFrame)); 3283635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project result = baseValue.get(callFrame, property); 32848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 32858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3286635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 32874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = result; 3288cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_by_val); 3289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 32908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_val) { 32928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_by_val base(r) property(r) value(r) 32938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register value on register base as the property named 32958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by register property. Base is converted to object 32968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project first. register property is nominally converted to string 32978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project but numbers are treated more efficiently. 32988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 32998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 33008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 33018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3302cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 3303cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 3304cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int value = vPC[3].u.operand; 33058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue baseValue = callFrame->r(base).jsValue(); 33070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue subscript = callFrame->r(property).jsValue(); 33088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (LIKELY(subscript.isUInt32())) { 33100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint32_t i = subscript.asUInt32(); 33118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (isJSArray(globalData, baseValue)) { 33128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project JSArray* jsArray = asArray(baseValue); 33138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (jsArray->canSetIndex(i)) 33142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block jsArray->setIndex(*globalData, i, callFrame->r(value).jsValue()); 33158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 33160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch jsArray->JSArray::put(callFrame, i, callFrame->r(value).jsValue()); 33178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) { 3318635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSByteArray* jsByteArray = asByteArray(baseValue); 3319635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double dValue = 0; 33200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue jsValue = callFrame->r(value).jsValue(); 33210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (jsValue.isInt32()) 33220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch jsByteArray->setIndex(i, jsValue.asInt32()); 3323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else if (jsValue.getNumber(dValue)) 3324635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project jsByteArray->setIndex(i, dValue); 3325635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else 3326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project baseValue.put(callFrame, i, jsValue); 33278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else 33280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseValue.put(callFrame, i, callFrame->r(value).jsValue()); 33298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3330635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, subscript.toString(callFrame)); 33318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!globalData->exception) { // Don't put to an object if toString threw an exception. 3332a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch PutPropertySlot slot(codeBlock->isStrictMode()); 33330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot); 33348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 33358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 33368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 3338cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_val); 3339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 33408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3341635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_del_by_val) { 33428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* del_by_val dst(r) base(r) property(r) 33438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register base to Object, deletes the property 33458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project named by register property from the object, and writes a 33468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project boolean indicating success (if true) or failure (if false) 33478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to register dst. 33488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3349cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3350cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 3351cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[3].u.operand; 33528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw 33548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue subscript = callFrame->r(property).jsValue(); 3356a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool result; 33578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project uint32_t i; 3358635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (subscript.getUInt32(i)) 3359a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch result = baseObj->deleteProperty(callFrame, i); 33608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 3361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 3362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Identifier property(callFrame, subscript.toString(callFrame)); 3363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 3364a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch result = baseObj->deleteProperty(callFrame, property); 3365a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 3366a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!result && codeBlock->isStrictMode()) { 3367a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch exceptionValue = createTypeError(callFrame, "Unable to delete property."); 3368a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch goto vm_throw; 33698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3370635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 33714576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsBoolean(result); 3372cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_del_by_val); 3373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 33748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3375635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_by_index) { 33768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_by_index base(r) property(n) value(r) 33778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register value on register base as the property named 33798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by the immediate number property. Base is converted to 33808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object first. 33818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 33838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 33848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This opcode is mainly used to initialize array literals. 33868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3387cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 3388cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block unsigned property = vPC[2].u.operand; 3389cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int value = vPC[3].u.operand; 33908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue()); 33928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3393cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_by_index); 3394635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 33958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop) { 33978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop target(offset) 33988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps unconditionally to offset target from the current 34008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instruction. 34018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 34038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 34048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 34058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 34068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 34078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3408cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[1].u.operand; 34098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 34108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3413635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jmp) { 34148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jmp target(offset) 34158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps unconditionally to offset target from the current 34178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instruction. 34188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 34198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 34208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 34218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3422cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[1].u.operand; 34238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3425635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3427635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop_if_true) { 34288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop_if_true cond(r) target(offset) 34298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 34318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register cond converts to boolean as true. 34328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 34348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 34358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3436cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int cond = vPC[1].u.operand; 3437cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 34380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { 34398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 34408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 3441635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3444cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_loop_if_true); 3445635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3447643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DEFINE_OPCODE(op_loop_if_false) { 3448643ca7872b450ea4efacab6188849e5aac2ba161Steve Block /* loop_if_true cond(r) target(offset) 3449643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3450643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Jumps to offset target from the current instruction, if and 3451643ca7872b450ea4efacab6188849e5aac2ba161Steve Block only if register cond converts to boolean as false. 3452643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3453643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Additionally this loop instruction may terminate JS execution is 3454643ca7872b450ea4efacab6188849e5aac2ba161Steve Block the JS timeout is reached. 3455643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */ 3456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int cond = vPC[1].u.operand; 3457643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int target = vPC[2].u.operand; 3458643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { 3459643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += target; 3460643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CHECK_FOR_TIMEOUT(); 3461643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3462643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3463643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3464643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += OPCODE_LENGTH(op_loop_if_true); 3465643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3466643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3467635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jtrue) { 34688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jtrue cond(r) target(offset) 34698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 34718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register cond converts to boolean as true. 34728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3473cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int cond = vPC[1].u.operand; 3474cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 34750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (callFrame->r(cond).jsValue().toBoolean(callFrame)) { 34768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3477635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3480cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jtrue); 3481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3483635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jfalse) { 34848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jfalse cond(r) target(offset) 34858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 34868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 34878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register cond converts to boolean as false. 34888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3489cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int cond = vPC[1].u.operand; 3490cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 34910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) { 34928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3493635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 34958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3496cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jfalse); 3497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 34988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3499635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jeq_null) { 35008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jeq_null src(r) target(offset) 35018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 35038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register src is null. 35048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3505cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[1].u.operand; 3506cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 35070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcValue = callFrame->r(src).jsValue(); 35088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3509635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { 35108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3511635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3514cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jeq_null); 3515635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jneq_null) { 35188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jneq_null src(r) target(offset) 35198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to offset target from the current instruction, if and 35218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project only if register src is not null. 35228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3523cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[1].u.operand; 3524cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 35250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcValue = callFrame->r(src).jsValue(); 35268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3527643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) { 35288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3529635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3532cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jneq_null); 3533635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_jneq_ptr) { 35365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian /* jneq_ptr src(r) ptr(jsCell) target(offset) 35375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 35385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Jumps to offset target from the current instruction, if the value r is equal 35395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian to ptr, using pointer equality. 35405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 3541cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[1].u.operand; 3542cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue ptr = JSValue(vPC[2].u.jsCell); 3543cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 35440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue srcValue = callFrame->r(src).jsValue(); 35455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (srcValue != ptr) { 35465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC += target; 35475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 35485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 35495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3550cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jneq_ptr); 35515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 35525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop_if_less) { 35548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop_if_less src1(r) src2(r) target(offset) 35558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than register src2, as 35578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project with the ECMAScript '<' operator, and then jumps to offset 35588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project target from the current instruction, if and only if the 35598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result of the comparison is true. 35608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 35628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 35638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3564cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3565cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3566cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 35678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = jsLess(callFrame, src1, src2); 3569635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 35708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) { 35728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 35738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 3574635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 35768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3577cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_loop_if_less); 3578635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 35798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3580635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_loop_if_lesseq) { 35818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* loop_if_lesseq src1(r) src2(r) target(offset) 35828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than or equal to register 35848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src2, as with the ECMAScript '<=' operator, and then jumps to 35858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project offset target from the current instruction, if and only if the 35868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result of the comparison is true. 35878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Additionally this loop instruction may terminate JS execution is 35898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the JS timeout is reached. 35908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3591cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3592cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3593cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 35948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = jsLessEq(callFrame, src1, src2); 3596635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 35978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 35988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) { 35998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 36008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CHECK_FOR_TIMEOUT(); 3601635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3604cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_loop_if_lesseq); 3605635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3607635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jnless) { 36088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jnless src1(r) src2(r) target(offset) 36098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Checks whether register src1 is less than register src2, as 36118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project with the ECMAScript '<' operator, and then jumps to offset 36128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project target from the current instruction, if and only if the 36138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result of the comparison is false. 36148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3615cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3616cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3617cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 36188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = jsLess(callFrame, src1, src2); 3620635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 36218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 36228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result) { 36238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 3624635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 36268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3627cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jnless); 3628635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 36298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3630643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DEFINE_OPCODE(op_jless) { 3631643ca7872b450ea4efacab6188849e5aac2ba161Steve Block /* jless src1(r) src2(r) target(offset) 3632643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3633643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Checks whether register src1 is less than register src2, as 3634643ca7872b450ea4efacab6188849e5aac2ba161Steve Block with the ECMAScript '<' operator, and then jumps to offset 3635643ca7872b450ea4efacab6188849e5aac2ba161Steve Block target from the current instruction, if and only if the 3636643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result of the comparison is true. 3637643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */ 3638643ca7872b450ea4efacab6188849e5aac2ba161Steve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3639643ca7872b450ea4efacab6188849e5aac2ba161Steve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3640643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int target = vPC[3].u.operand; 3641643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3642643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool result = jsLess(callFrame, src1, src2); 3643643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CHECK_FOR_EXCEPTION(); 3644643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3645643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (result) { 3646643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += target; 3647643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3648643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 3649643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 3650643ca7872b450ea4efacab6188849e5aac2ba161Steve Block vPC += OPCODE_LENGTH(op_jless); 3651643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NEXT_INSTRUCTION(); 3652643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 36535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_jnlesseq) { 36545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian /* jnlesseq src1(r) src2(r) target(offset) 36555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 36565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Checks whether register src1 is less than or equal to 36575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian register src2, as with the ECMAScript '<=' operator, 36585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian and then jumps to offset target from the current instruction, 36595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if and only if theresult of the comparison is false. 36605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 3661cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 3662cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 3663cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[3].u.operand; 36645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 36655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool result = jsLessEq(callFrame, src1, src2); 36665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 36675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 36685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!result) { 36695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC += target; 36705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 36715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 36725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3673cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_jnlesseq); 36745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 36755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 367621939df44de1705786c545cd1bf519d47250322dBen Murdoch DEFINE_OPCODE(op_jlesseq) { 367721939df44de1705786c545cd1bf519d47250322dBen Murdoch /* jlesseq src1(r) src2(r) target(offset) 367821939df44de1705786c545cd1bf519d47250322dBen Murdoch 367921939df44de1705786c545cd1bf519d47250322dBen Murdoch Checks whether register src1 is less than or equal to 368021939df44de1705786c545cd1bf519d47250322dBen Murdoch register src2, as with the ECMAScript '<=' operator, 368121939df44de1705786c545cd1bf519d47250322dBen Murdoch and then jumps to offset target from the current instruction, 368221939df44de1705786c545cd1bf519d47250322dBen Murdoch if and only if the result of the comparison is true. 368321939df44de1705786c545cd1bf519d47250322dBen Murdoch */ 368421939df44de1705786c545cd1bf519d47250322dBen Murdoch JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue(); 368521939df44de1705786c545cd1bf519d47250322dBen Murdoch JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue(); 368621939df44de1705786c545cd1bf519d47250322dBen Murdoch int target = vPC[3].u.operand; 368721939df44de1705786c545cd1bf519d47250322dBen Murdoch 368821939df44de1705786c545cd1bf519d47250322dBen Murdoch bool result = jsLessEq(callFrame, src1, src2); 368921939df44de1705786c545cd1bf519d47250322dBen Murdoch CHECK_FOR_EXCEPTION(); 369021939df44de1705786c545cd1bf519d47250322dBen Murdoch 369121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (result) { 369221939df44de1705786c545cd1bf519d47250322dBen Murdoch vPC += target; 369321939df44de1705786c545cd1bf519d47250322dBen Murdoch NEXT_INSTRUCTION(); 369421939df44de1705786c545cd1bf519d47250322dBen Murdoch } 369521939df44de1705786c545cd1bf519d47250322dBen Murdoch 369621939df44de1705786c545cd1bf519d47250322dBen Murdoch vPC += OPCODE_LENGTH(op_jlesseq); 369721939df44de1705786c545cd1bf519d47250322dBen Murdoch NEXT_INSTRUCTION(); 369821939df44de1705786c545cd1bf519d47250322dBen Murdoch } 3699635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_switch_imm) { 37008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r) 37018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a range checked switch on the scrutinee value, using 37038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the tableIndex-th immediate switch jump table. If the scrutinee value 37048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is an immediate number in the range covered by the referenced jump 37058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project table, and the value at jumpTable[scrutinee value] is non-zero, then 37068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project that value is used as the jump offset, otherwise defaultOffset is used. 37078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3708cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int tableIndex = vPC[1].u.operand; 3709cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int defaultOffset = vPC[2].u.operand; 3710cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); 37110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (scrutinee.isInt32()) 3712e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset); 37138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 37148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian double value; 37158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int32_t intValue; 37168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value)) 3717e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += codeBlock->immediateSwitchJumpTable(tableIndex).offsetForValue(intValue, defaultOffset); 3718635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else 3719635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC += defaultOffset; 37208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3721635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3723635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_switch_char) { 37248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r) 37258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a range checked switch on the scrutinee value, using 37278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the tableIndex-th character switch jump table. If the scrutinee value 37288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is a single character string in the range covered by the referenced jump 37298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project table, and the value at jumpTable[scrutinee value] is non-zero, then 37308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project that value is used as the jump offset, otherwise defaultOffset is used. 37318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3732cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int tableIndex = vPC[1].u.operand; 3733cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int defaultOffset = vPC[2].u.operand; 3734cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); 3735635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!scrutinee.isString()) 37368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += defaultOffset; 37378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 3738f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick StringImpl* value = asString(scrutinee)->value(callFrame).impl(); 3739692e5dbf12901edacf14812a6fae25462920af42Steve Block if (value->length() != 1) 37408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += defaultOffset; 37418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3742e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += codeBlock->characterSwitchJumpTable(tableIndex).offsetForValue(value->characters()[0], defaultOffset); 37438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3744635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3746635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_switch_string) { 37478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r) 37488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Performs a sparse hashmap based switch on the value in the scrutinee 37508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register, using the tableIndex-th string switch jump table. If the 37518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scrutinee value is a string that exists as a key in the referenced 37528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jump table, then the value associated with the string is used as the 37538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project jump offset, otherwise defaultOffset is used. 37548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3755cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int tableIndex = vPC[1].u.operand; 3756cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int defaultOffset = vPC[2].u.operand; 3757cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue(); 3758635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!scrutinee.isString()) 37598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += defaultOffset; 37608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3761f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).impl(), defaultOffset); 3762635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3764635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_func) { 37658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_func dst(r) func(f) 37668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new Function instance from function func and 37688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the current scope chain using the original Function 37698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, using the rules for function declarations, and 37708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result in register dst. 37718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3772cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3773cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int func = vPC[2].u.operand; 3774bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen int shouldCheck = vPC[3].u.operand; 3775a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue()); 3776bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (!shouldCheck || !callFrame->r(dst).jsValue()) 37774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(codeBlock->functionDecl(func)->make(callFrame, callFrame->scopeChain())); 37788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3779cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_func); 3780635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 37818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3782635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_new_func_exp) { 37838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_func_exp dst(r) func(f) 37848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new Function instance from function func and 37868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the current scope chain using the original Function 37878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project constructor, using the rules for function expressions, and 37888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project puts the result in register dst. 37898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 3790cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 3791cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int funcIndex = vPC[2].u.operand; 3792a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3793a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue()); 3794e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block FunctionExecutable* function = codeBlock->functionExpr(funcIndex); 3795231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSFunction* func = function->make(callFrame, callFrame->scopeChain()); 3796231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3797231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block /* 3798231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block The Identifier in a FunctionExpression can be referenced from inside 3799231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block the FunctionExpression's FunctionBody to allow the function to call 3800231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block itself recursively. However, unlike in a FunctionDeclaration, the 3801231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Identifier in a FunctionExpression cannot be referenced from and 3802231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block does not affect the scope enclosing the FunctionExpression. 3803231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */ 3804231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!function->name().isNull()) { 3805231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete); 3806231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block func->scope().push(functionScopeObject); 3807231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 3808231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 38094576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(func); 38108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3811cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_new_func_exp); 3812635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 38138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3814635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_call_eval) { 3815e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* call_eval func(r) argCount(n) registerOffset(n) 38168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Call a function named "eval" with no explicit "this" value 38188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (which may therefore be the eval operator). If register 38198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project thisVal is the global object, and register func contains 38208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project that global object's original global eval function, then 38218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project perform the eval operator in local scope (interpreting 38228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the argument registers as for the "call" 38238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project opcode). Otherwise, act exactly as the "call" opcode would. 38248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 38258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3826e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 3827e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCount = vPC[2].u.operand; 3828e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 3829a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 3830a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch ASSERT(codeBlock->codeType() != FunctionCode || !codeBlock->needsFullScopeChain() || callFrame->r(codeBlock->activationRegister()).jsValue()); 38310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue funcVal = callFrame->r(func).jsValue(); 38328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3833635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* newCallFrame = callFrame->registers() + registerOffset; 3834635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount; 38355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue thisValue = argv[0].jsValue(); 3836231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject; 3837635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3838635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (thisValue == globalObject && funcVal == globalObject->evalFunction()) { 3839e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset); 38402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if ((exceptionValue = globalData->exception.get())) 38418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 3842e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = result; 38438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3844cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_call_eval); 3845635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 38468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3848635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // We didn't find the blessed version of eval, so process this 3849635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // instruction as a normal function call. 38508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // fall through to op_call 38518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3852635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_call) { 3853e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* call func(r) argCount(n) registerOffset(n) 38548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3855635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Perform a function call. 3856635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3857635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project registerOffset is the distance the callFrame pointer should move 3858635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project before the VM initializes the new call frame's header. 3859635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3860635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project dst is where op_ret should store its result. 38618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 38628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3863e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 3864e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCount = vPC[2].u.operand; 3865e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 38668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(func).jsValue(); 38688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallData callData; 3870545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch CallType callType = getCallData(v, callData); 38718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callType == CallTypeJS) { 38738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 3874967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 3875967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain); 3876967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!error)) { 3877967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch exceptionValue = error; 3878967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch goto vm_throw; 3879967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 38808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* previousCallFrame = callFrame; 3882967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); 3883967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 38848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!callFrame)) { 38858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame = previousCallFrame; 38868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = createStackOverflowError(callFrame); 38878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 38888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 38898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); 3891e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = newCodeBlock; 3892e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 3893635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC = newCodeBlock->instructions().begin(); 38948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 38968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 38978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 38988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3899635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 39008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callType == CallTypeHost) { 39038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 39048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 390506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!registerFile->grow(newCallFrame->registers())) { 390606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen exceptionValue = createStackOverflowError(callFrame); 390706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto vm_throw; 390806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 390906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 39105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scopeChain, callFrame, argCount, asObject(v)); 39118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue returnValue; 39138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 3914231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::HostCallRecord callRecord(m_sampler.get()); 3915545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch returnValue = JSValue::decode(callData.native.function(newCallFrame)); 39168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3917635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 39188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3919e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 39208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3921cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_call); 3922635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 39238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(callType == CallTypeNone); 39268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 39276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createNotAFunctionError(callFrame, v); 39288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 39298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 39305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_load_varargs) { 3931cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int argCountDst = vPC[1].u.operand; 3932cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int argsOffset = vPC[2].u.operand; 39335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 39340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue arguments = callFrame->r(argsOffset).jsValue(); 3935ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block uint32_t argCount = 0; 39365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!arguments) { 39375af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke argCount = (uint32_t)(callFrame->argumentCount()); 3938ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(!asFunction(callFrame->callee())->isHostFunction()); 3946e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount(); 3947e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int32_t inplaceArgs = min(static_cast<int32_t>(argCount), expectedParams); 3948e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke int32_t i = 0; 39495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* argStore = callFrame->registers() + argsOffset; 39505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 39515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // First step is to copy the "expected" parameters from their normal location relative to the callframe 39525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (; i < inplaceArgs; i++) 39535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argStore[i] = callFrame->registers()[i - RegisterFile::CallFrameHeaderSize - expectedParams]; 39545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Then we copy any additional arguments that may be further up the stack ('-1' to account for 'this') 3955e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke for (; i < static_cast<int32_t>(argCount); i++) 3956e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke argStore[i] = callFrame->registers()[i - RegisterFile::CallFrameHeaderSize - expectedParams - static_cast<int32_t>(argCount) - 1]; 39575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (!arguments.isUndefinedOrNull()) { 39585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!arguments.isObject()) { 39596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments); 39605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (asObject(arguments)->classInfo() == &Arguments::info) { 39635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Arguments* args = asArguments(arguments); 39645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argCount = args->numProvidedArguments(callFrame); 3965ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian args->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); 39735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (isJSArray(&callFrame->globalData(), arguments)) { 39745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSArray* array = asArray(arguments); 39755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argCount = array->length(); 3976ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount); 39845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else if (asObject(arguments)->inherits(&JSArray::info)) { 39855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSObject* argObject = asObject(arguments); 39865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); 3987ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block argCount = min<uint32_t>(argCount, Arguments::MaxArguments); 39885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; 39895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* newEnd = callFrame->registers() + sizeDelta; 39905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { 39915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 39925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 39935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Register* argsBuffer = callFrame->registers() + argsOffset; 3995ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block for (uint32_t i = 0; i < argCount; ++i) { 39965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian argsBuffer[i] = asObject(arguments)->get(callFrame, i); 39975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 39985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 39995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } else { 40006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments); 4001bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen goto vm_throw; 40025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 40054576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(argCountDst) = Register::withInt(argCount + 1); 4006cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_load_varargs); 40075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 40085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_call_varargs) { 4010e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* call_varargs func(r) argCountReg(r) baseRegisterOffset(n) 40115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Perform a function call with a dynamic set of arguments. 40135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian registerOffset is the distance the callFrame pointer should move 40155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian before the VM initializes the new call frame's header, excluding 40165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian space for arguments. 40175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian dst is where op_ret should store its result. 40195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 40205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4021e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 4022e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCountReg = vPC[2].u.operand; 4023e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 40245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(func).jsValue(); 40260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int argCount = callFrame->r(argCountReg).i(); 40275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian registerOffset += argCount; 40285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallData callData; 4029545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch CallType callType = getCallData(v, callData); 40305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (callType == CallTypeJS) { 40325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 4033967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 4034967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain); 4035967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!error)) { 4036967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch exceptionValue = error; 4037967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch goto vm_throw; 4038967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 4039967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 40405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallFrame* previousCallFrame = callFrame; 4041967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); 4042967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 40435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (UNLIKELY(!callFrame)) { 40445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian callFrame = previousCallFrame; 40455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = createStackOverflowError(callFrame); 40465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 40475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4048967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 40495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); 4050e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = newCodeBlock; 4051e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 40525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC = newCodeBlock->instructions().begin(); 40535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(OPCODE_STATS) 40555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian OpcodeStats::resetLastInstruction(); 40565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 40575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 40595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (callType == CallTypeHost) { 40625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ScopeChainNode* scopeChain = callFrame->scopeChain(); 40635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 406406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!registerFile->grow(newCallFrame->registers())) { 406506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen exceptionValue = createStackOverflowError(callFrame); 406606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto vm_throw; 406706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 40685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call_varargs), scopeChain, callFrame, argCount, asObject(v)); 40695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue returnValue; 40715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 4072231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::HostCallRecord callRecord(m_sampler.get()); 4073545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch returnValue = JSValue::decode(callData.native.function(newCallFrame)); 40745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian CHECK_FOR_EXCEPTION(); 40765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4077e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 40785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 4079cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_call_varargs); 40805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 40815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 40825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ASSERT(callType == CallTypeNone); 40845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 40856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createNotAFunctionError(callFrame, v); 40865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian goto vm_throw; 40875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4088635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_tear_off_activation) { 4089e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* tear_off_activation activation(r) arguments(r) 40908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4091e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Copy locals and named parameters from the register file to the heap. 4092e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Point the bindings in 'activation' and 'arguments' to this new backing 4093e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block store. (Note that 'arguments' may not have been created. If created, 4094e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 'arguments' already holds a copy of any extra / unnamed parameters.) 40958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4096e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears before op_ret in functions that require full scope chains. 40978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 40988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4099a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int activation = vPC[1].u.operand; 4100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int arguments = vPC[2].u.operand; 4101e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock->needsFullScopeChain()); 4102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue activationValue = callFrame->r(activation).jsValue(); 4103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (activationValue) { 4104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch asActivation(activationValue)->copyRegisters(); 4105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4106e14391e94c850b8bd03680c23b38978db68687a8John Reck if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) { 4107e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!codeBlock->isStrictMode()) 41082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block asArguments(argumentsValue)->setActivation(*globalData, asActivation(activationValue)); 4109e14391e94c850b8bd03680c23b38978db68687a8John Reck } 4110e14391e94c850b8bd03680c23b38978db68687a8John Reck } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) { 4111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!codeBlock->isStrictMode()) 4112e14391e94c850b8bd03680c23b38978db68687a8John Reck asArguments(argumentsValue)->copyRegisters(); 4113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 41148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4115cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_tear_off_activation); 4116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 41178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_tear_off_arguments) { 4119e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* tear_off_arguments arguments(r) 41208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4121e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Copy named parameters from the register file to the heap. Point the 4122e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block bindings in 'arguments' to this new backing store. (Note that 4123e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 'arguments' may not have been created. If created, 'arguments' already 4124e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block holds a copy of any extra / unnamed parameters.) 41258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4126e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears before op_ret in functions that don't require full 4127e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block scope chains, but do use 'arguments'. 41288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 41298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4130e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int src1 = vPC[1].u.operand; 4131e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(!codeBlock->needsFullScopeChain() && codeBlock->ownerExecutable()->usesArguments()); 41320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4133e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src1)).jsValue()) 4134e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block asArguments(arguments)->copyRegisters(); 41358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4136cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_tear_off_arguments); 4137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 41388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_ret) { 41408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* ret result(r) 41418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Return register result as the return value of the current 4143e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block function call, writing it into functionReturnValue. 4144e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block In addition, unwind one call frame and restore the scope 4145e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block chain, code block instruction pointer and register base 4146e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block to those of the calling function. 4147e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block */ 4148e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4149e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int result = vPC[1].u.operand; 4150e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (callFrame->codeBlock()->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue()) 4152e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block callFrame->scopeChain()->deref(); 4153e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4154e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block JSValue returnValue = callFrame->r(result).jsValue(); 4155e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4156e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke vPC = callFrame->returnVPC(); 4157e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block callFrame = callFrame->callerFrame(); 4158e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4159e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (callFrame->hasHostCallFrameFlag()) 4160e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return returnValue; 4161e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4162e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 4163e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4164e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 4165e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4166e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block NEXT_INSTRUCTION(); 4167e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 4168e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block DEFINE_OPCODE(op_call_put_result) { 4169e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* op_call_put_result result(r) 4170e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4171e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Move call result from functionReturnValue to caller's 4172e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block expected return value register. 4173e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block */ 4174e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 41754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(vPC[1].u.operand) = functionReturnValue; 4176e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4177e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC += OPCODE_LENGTH(op_call_put_result); 4178e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block NEXT_INSTRUCTION(); 4179e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 4180e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block DEFINE_OPCODE(op_ret_object_or_this) { 4181e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* ret result(r) 4182e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4183e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Return register result as the return value of the current 41848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function call, writing it into the caller's expected return 41858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value register. In addition, unwind one call frame and 41868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project restore the scope chain, code block instruction pointer and 41878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register base to those of the calling function. 41888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 41898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4190cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int result = vPC[1].u.operand; 41918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (codeBlock->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue()) 41938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->scopeChain()->deref(); 41948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue returnValue = callFrame->r(result).jsValue(); 41968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4197e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (UNLIKELY(!returnValue.isObject())) 4198e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block returnValue = callFrame->r(vPC[2].u.operand).jsValue(); 4199e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4200e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke vPC = callFrame->returnVPC(); 42018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame = callFrame->callerFrame(); 42025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callFrame->hasHostCallFrameFlag()) 42048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return returnValue; 42058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4206e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block functionReturnValue = returnValue; 4207e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4208e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block ASSERT(codeBlock == callFrame->codeBlock()); 42098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4210635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 42118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4212635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_enter) { 42138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* enter 42148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4215e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Initializes local variables to undefined. If the code block requires 4216e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block an activation, enter_with_activation is used instead. 42178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4218e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears only at the beginning of a code block. 42198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 42208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t i = 0; 4222635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project for (size_t count = codeBlock->m_numVars; i < count; ++i) 42234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(i) = jsUndefined(); 42248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4225cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_enter); 4226635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 42278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4228a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch DEFINE_OPCODE(op_create_activation) { 4229a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /* create_activation dst(r) 42308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4231a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch If the activation object for this callframe has not yet been created, 4232a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch this creates it and writes it back to dst. 42338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 42348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4235a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int activationReg = vPC[1].u.operand; 4236a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (!callFrame->r(activationReg).jsValue()) { 4237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable())); 4238a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callFrame->r(activationReg) = JSValue(activation); 4239a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); 4240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 4241a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch vPC += OPCODE_LENGTH(op_create_activation); 4242635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 42438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 42445af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DEFINE_OPCODE(op_get_callee) { 42455af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke /* op_get_callee callee(r) 42465af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42475af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Move callee into a register. 42485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke */ 42495af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(vPC[1].u.operand) = JSValue(callFrame->callee()); 42515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke vPC += OPCODE_LENGTH(op_get_callee); 42535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke NEXT_INSTRUCTION(); 42545af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 42555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke DEFINE_OPCODE(op_create_this) { 42565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke /* op_create_this this(r) proto(r) 42575af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42585af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Allocate an object as 'this', fr use in construction. 42595af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke This opcode should only be used at the beginning of a code 42615af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke block. 42625af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke */ 42635af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke int thisRegister = vPC[1].u.operand; 42655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke int protoRegister = vPC[2].u.operand; 42665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSFunction* constructor = asFunction(callFrame->callee()); 42685af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#if !ASSERT_DISABLED 42695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ConstructData constructData; 42705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS); 42715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#endif 42725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke Structure* structure; 42745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSValue proto = callFrame->r(protoRegister).jsValue(); 42755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (proto.isObject()) 42765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke structure = asObject(proto)->inheritorID(); 42775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke else 42785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke structure = constructor->scope().node()->globalObject->emptyObjectStructure(); 42794576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(thisRegister) = JSValue(new (&callFrame->globalData()) JSObject(structure)); 42805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 42815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke vPC += OPCODE_LENGTH(op_create_this); 42825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke NEXT_INSTRUCTION(); 42835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 4284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_convert_this) { 42858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* convert_this this(r) 42868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Takes the value in the 'this' register, converts it to a 42888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project value that is suitable for use as the 'this' value, and 42898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project stores it in the 'this' register. This opcode is emitted 42908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to avoid doing the conversion in the caller unnecessarily. 42918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 42928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project This opcode should only be used at the beginning of a code 42938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project block. 42948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 42958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4296cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int thisRegister = vPC[1].u.operand; 42970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue thisVal = callFrame->r(thisRegister).jsValue(); 4298635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (thisVal.needsThisConversion()) 42994576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toThisObject(callFrame)); 43008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4301cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_convert_this); 4302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 43038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4304a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch DEFINE_OPCODE(op_convert_this_strict) { 4305a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch /* convert_this_strict this(r) 4306a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4307a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch Takes the value in the 'this' register, and converts it to 4308a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch its "this" form if (and only if) "this" is an object with a 4309a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch custom this conversion 4310a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4311a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch This opcode should only be used at the beginning of a code 4312a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch block. 4313a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */ 4314a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4315a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch int thisRegister = vPC[1].u.operand; 4316a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch JSValue thisVal = callFrame->r(thisRegister).jsValue(); 4317a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (thisVal.isObject() && thisVal.needsThisConversion()) 43184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(thisRegister) = JSValue(thisVal.toStrictThisObject(callFrame)); 4319a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 4320a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch vPC += OPCODE_LENGTH(op_convert_this_strict); 4321a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch NEXT_INSTRUCTION(); 4322a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch } 4323bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen DEFINE_OPCODE(op_init_lazy_reg) { 4324bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen /* init_lazy_reg dst(r) 43258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4326bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Initialises dst(r) to JSValue(). 43278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4328e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block This opcode appears only at the beginning of a code block. 43295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 4330e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int dst = vPC[1].u.operand; 4331e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 43324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(); 4333bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen vPC += OPCODE_LENGTH(op_init_lazy_reg); 43345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 43355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 43365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_create_arguments) { 4337e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* create_arguments dst(r) 43388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Creates the 'arguments' object and places it in both the 43405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 'arguments' call frame slot and the local 'arguments' 43415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian register, if it has not already been initialised. 43425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */ 43438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4344e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int dst = vPC[1].u.operand; 4345e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 4346e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (!callFrame->r(dst).jsValue()) { 4347e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Arguments* arguments = new (globalData) Arguments(callFrame); 43484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = JSValue(arguments); 43494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(unmodifiedArgumentsRegister(dst)) = JSValue(arguments); 4350e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block } 4351cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_create_arguments); 4352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 43538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_construct) { 4355e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block /* construct func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r) 43568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4357635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Invoke register "func" as a constructor. For JS 43588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project functions, the calling convention is exactly as for the 43598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project "call" opcode, except that the "this" value is a newly 4360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project created Object. For native constructors, no "this" 4361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project value is passed. In either case, the argCount and registerOffset 43628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project registers are interpreted as for the "call" opcode. 43638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4364635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project Register proto must contain the prototype property of 4365635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project register func. This is to enable polymorphic inline 43668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project caching of this lookup. 43678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 43688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4369e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int func = vPC[1].u.operand; 4370e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argCount = vPC[2].u.operand; 4371e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int registerOffset = vPC[3].u.operand; 43728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(func).jsValue(); 43748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ConstructData constructData; 4376545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch ConstructType constructType = getConstructData(v, constructData); 43778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (constructType == ConstructTypeJS) { 43798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* callDataScopeChain = constructData.js.scopeChain; 43808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4381967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch JSObject* error = constructData.js.functionExecutable->compileForConstruct(callFrame, callDataScopeChain); 4382967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (UNLIKELY(!!error)) { 4383967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch exceptionValue = error; 4384967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch goto vm_throw; 4385967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 438606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen 4387967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CallFrame* previousCallFrame = callFrame; 4388967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct(); 4389967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount); 43908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (UNLIKELY(!callFrame)) { 43918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame = previousCallFrame; 43928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = createStackOverflowError(callFrame); 43938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 43948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 43958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 43965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScopeChain, previousCallFrame, argCount, asFunction(v)); 4397e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = newCodeBlock; 4398635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project vPC = newCodeBlock->instructions().begin(); 43998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(OPCODE_STATS) 44008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OpcodeStats::resetLastInstruction(); 44018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 44028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4403635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (constructType == ConstructTypeHost) { 44078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 44088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 440906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen if (!registerFile->grow(newCallFrame->registers())) { 441006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen exceptionValue = createStackOverflowError(callFrame); 441106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen goto vm_throw; 441206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen } 4413545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch newCallFrame->init(0, vPC + OPCODE_LENGTH(op_construct), scopeChain, callFrame, argCount, asObject(v)); 44148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue returnValue; 44168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 4417231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingTool::HostCallRecord callRecord(m_sampler.get()); 4418545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch returnValue = JSValue::decode(constructData.native.function(newCallFrame)); 44198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4420635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 4421545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch functionReturnValue = returnValue; 44228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4423cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_construct); 4424635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(constructType == ConstructTypeNone); 44288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = createNotAConstructorError(callFrame, v); 44308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto vm_throw; 44318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 44325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_strcat) { 4433bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen /* strcat dst(r) src(r) count(n) 4434bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 4435bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen Construct a new String instance using the original 4436bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen constructor, and puts the result in register dst. 4437bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen The string will be the result of concatenating count 4438bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen strings with values taken from registers starting at 4439bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen register src. 4440bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen */ 4441cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4442cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 4443cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int count = vPC[3].u.operand; 44445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count); 4446643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CHECK_FOR_EXCEPTION(); 4447cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_strcat); 44485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 44505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 44515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_to_primitive) { 4452cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4453cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int src = vPC[2].u.operand; 44545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44554576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame); 4456cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_to_primitive); 44575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 44585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 44595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4460635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_push_scope) { 44618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* push_scope scope(r) 44628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Converts register scope to object, and pushes it onto the top 4464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project of the current scope chain. The contents of the register scope 4465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project are replaced by the result of toObject conversion of the scope. 44668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4467cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int scope = vPC[1].u.operand; 44680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSValue v = callFrame->r(scope).jsValue(); 4469635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project JSObject* o = v.toObject(callFrame); 4470635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CHECK_FOR_EXCEPTION(); 44718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(scope) = JSValue(o); 44738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(callFrame->scopeChain()->push(o)); 44748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4475cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_push_scope); 4476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4478635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_pop_scope) { 44798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* pop_scope 44808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Removes the top item from the current scope chain. 44828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 44838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(callFrame->scopeChain()->pop()); 44848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4485cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_pop_scope); 4486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 44878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_get_pnames) { 4489cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset) 44908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Creates a property name list for register base and puts it 4492cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block in register dst, initializing i and size for iteration. If 4493cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block base is undefined or null, jumps to breakTarget. 44948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4495cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4496cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 4497cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int i = vPC[3].u.operand; 4498cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int size = vPC[4].u.operand; 4499cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int breakTarget = vPC[5].u.operand; 45008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4501cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue v = callFrame->r(base).jsValue(); 4502cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (v.isUndefinedOrNull()) { 4503cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += breakTarget; 4504cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 4505cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 4506cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 4507cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSObject* o = v.toObject(callFrame); 4508cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Structure* structure = o->structure(); 4509cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache(); 4510cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame)) 4511cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o); 4512cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 45134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = jsPropertyNameIterator; 45144576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(base) = JSValue(o); 45154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(i) = Register::withInt(0); 45164576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(size) = Register::withInt(jsPropertyNameIterator->size()); 4517cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_get_pnames); 4518635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4520635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_next_pname) { 4521cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset) 45228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4523cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block Copies the next name from the property name list in 4524cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block register iter to dst, then jumps to offset target. If there are no 4525cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block names left, invalidates the iterator and continues to the next 45268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project instruction. 45278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4528cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int dst = vPC[1].u.operand; 4529cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[2].u.operand; 4530cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int i = vPC[3].u.operand; 4531cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int size = vPC[4].u.operand; 4532cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int iter = vPC[5].u.operand; 4533cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[6].u.operand; 45348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator(); 4536cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block while (callFrame->r(i).i() != callFrame->r(size).i()) { 4537cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i()); 4538e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block CHECK_FOR_EXCEPTION(); 45394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(i) = Register::withInt(callFrame->r(i).i() + 1); 4540cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (key) { 4541cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block CHECK_FOR_TIMEOUT(); 45424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(dst) = key; 4543cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += target; 4544cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block NEXT_INSTRUCTION(); 4545cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 45468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 45478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4548cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_next_pname); 4549635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4551635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jmp_scopes) { 45528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jmp_scopes count(n) target(offset) 45538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Removes the a number of items from the current scope chain 45558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project specified by immediate number count, then jumps to offset 45568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project target. 45578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4558cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int count = vPC[1].u.operand; 4559cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 45608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* tmp = callFrame->scopeChain(); 45628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (count--) 45638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project tmp = tmp->pop(); 45648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(tmp); 45658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 4567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4569e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 45708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Appease GCC 45718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project goto *(&&skip_new_scope); 45728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4573635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_push_new_scope) { 45748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* new_scope dst(r) property(id) value(r) 45758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Constructs a new StaticScopeObject with property set to value. That scope 45778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project object is then pushed onto the ScopeChain. The scope object is then stored 45788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in dst for GC. 45798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 45808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callFrame->setScopeChain(createExceptionScope(callFrame, vPC)); 45818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4582cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_push_new_scope); 4583635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 45848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4585e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(COMPUTED_GOTO_INTERPRETER) 45868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project skip_new_scope: 45878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4588635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_catch) { 45898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* catch ex(r) 45908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Retrieves the VM's current exception and puts it in register 45928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ex. This is only valid after an exception has been raised, 45938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project and usually forms the beginning of an exception handler. 45948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 45958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(exceptionValue); 45968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!globalData->exception); 4597cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int ex = vPC[1].u.operand; 45984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang callFrame->uncheckedR(ex) = exceptionValue; 45995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian exceptionValue = JSValue(); 46008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4601cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_catch); 4602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4604635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_throw) { 46058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* throw ex(r) 46068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Throws register ex as an exception. This involves three 46088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project steps: first, it is set as the current exception in the 46098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project VM's internal state, then the stack is unwound until an 46108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exception handler or a native code boundary is found, and 46118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project then control resumes at the exception handler if any or 46128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else the script returns control to the nearest native caller. 46138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 46148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4615cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int ex = vPC[1].u.operand; 46160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch exceptionValue = callFrame->r(ex).jsValue(); 46178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin()); 4619e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!handler) 4620e14391e94c850b8bd03680c23b38978db68687a8John Reck return throwError(callFrame, exceptionValue); 46218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4622e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4623e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC = codeBlock->instructions().begin() + handler->target; 4624635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 46266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner DEFINE_OPCODE(op_throw_reference_error) { 46276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner /* op_throw_reference_error message(k) 46288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner Constructs a new reference Error instance using the 46306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner original constructor, using constant message as the 46316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner message string. The result is thrown. 46328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 46336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner UString message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame); 46346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner exceptionValue = JSValue(createReferenceError(callFrame, message)); 46356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner goto vm_throw; 46366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 4637635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_end) { 46388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* end result(r) 46398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Return register result as the value of a global or eval 46418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project program. Return control to the calling native code. 46428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 46438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4644e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block if (codeBlock->needsFullScopeChain()) { 46458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ScopeChainNode* scopeChain = callFrame->scopeChain(); 46468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(scopeChain->refCount > 1); 46478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project scopeChain->deref(); 46488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4649cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int result = vPC[1].u.operand; 46500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return callFrame->r(result).jsValue(); 46518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4652635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_getter) { 46538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_getter base(r) property(id) function(r) 46548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register function on register base as the getter named 46568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by identifier property. Base and function are assumed to be 46578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project objects as this op should only be used for getters defined 46588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in object literal form. 46598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 46618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 46628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4663cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 4664cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 4665cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int function = vPC[3].u.operand; 46668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(base).jsValue().isObject()); 46680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = asObject(callFrame->r(base).jsValue()); 4669e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 46700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(function).jsValue().isObject()); 46710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue())); 46728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4673cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_getter); 4674635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4676635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_put_setter) { 46778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* put_setter base(r) property(id) function(r) 46788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Sets register function on register base as the setter named 46808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project by identifier property. Base and function are assumed to be 46818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project objects as this op should only be used for setters defined 46828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project in object literal form. 46838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Unlike many opcodes, this one does not write any output to 46858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project the register file. 46868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4687cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int base = vPC[1].u.operand; 4688cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int property = vPC[2].u.operand; 4689cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int function = vPC[3].u.operand; 46908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(base).jsValue().isObject()); 46920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JSObject* baseObj = asObject(callFrame->r(base).jsValue()); 4693e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Identifier& ident = codeBlock->identifier(property); 46940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(callFrame->r(function).jsValue().isObject()); 4695231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0); 46968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4697cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_put_setter); 4698635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 46998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian DEFINE_OPCODE(op_method_check) { 47015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian vPC++; 47025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NEXT_INSTRUCTION(); 47035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 4704635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_jsr) { 47058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* jsr retAddrDst(r) target(offset) 47068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Places the address of the next instruction into the retAddrDst 47088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register and jumps to offset target from the current instruction. 47098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4710cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int retAddrDst = vPC[1].u.operand; 4711cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int target = vPC[2].u.operand; 4712cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr); 47138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vPC += target; 4715635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4717635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_sret) { 47188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* sret retAddrSrc(r) 47198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Jumps to the address stored in the retAddrSrc register. This 47218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project differs from op_jmp because the target address is stored in a 47228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project register, not as an immediate. 47238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4724cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int retAddrSrc = vPC[1].u.operand; 47250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch vPC = callFrame->r(retAddrSrc).vPC(); 4726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4728635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_debug) { 47298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* debug debugHookID(n) firstLine(n) lastLine(n) 47308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Notifies the debugger of the current state of execution. This opcode 47328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is only generated while the debugger is attached. 47338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 4734cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int debugHookID = vPC[1].u.operand; 4735cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int firstLine = vPC[2].u.operand; 4736cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int lastLine = vPC[3].u.operand; 47378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine); 47398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4740cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_debug); 4741635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4743635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_profile_will_call) { 47448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_profile_will_call function(r) 47458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Notifies the profiler of the beginning of a function call. This opcode 47478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is only generated if developer tools are enabled. 47488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 47498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int function = vPC[1].u.operand; 47508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*enabledProfilerReference) 47520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue()); 47538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4754cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_profile_will_call); 4755635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4757635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_OPCODE(op_profile_did_call) { 47588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project /* op_profile_did_call function(r) 47598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Notifies the profiler of the end of a function call. This opcode 47618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project is only generated if developer tools are enabled. 47628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 47638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int function = vPC[1].u.operand; 47648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*enabledProfilerReference) 47660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue()); 47678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4768cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block vPC += OPCODE_LENGTH(op_profile_did_call); 4769635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project vm_throw: { 47725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian globalData->exception = JSValue(); 47738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!tickCount) { 47748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The exceptionValue is a lie! (GCC produces bad code for reasons I 47758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // cannot fathom if we don't assign to the exceptionValue before branching) 47768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project exceptionValue = createInterruptedExecutionException(globalData); 47778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47784576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin()); 4779e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!handler) 4780e14391e94c850b8bd03680c23b38978db68687a8John Reck return throwError(callFrame, exceptionValue); 4781635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4782e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block codeBlock = callFrame->codeBlock(); 4783e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block vPC = codeBlock->instructions().begin() + handler->target; 4784635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NEXT_INSTRUCTION(); 47858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 47868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4787e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if !ENABLE(COMPUTED_GOTO_INTERPRETER) 47888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } // iterator loop ends 47898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 4790635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #undef NEXT_INSTRUCTION 4791635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #undef DEFINE_OPCODE 4792635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project #undef CHECK_FOR_EXCEPTION 47938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project #undef CHECK_FOR_TIMEOUT 4794e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif // ENABLE(INTERPRETER) 47958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 47968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 47975f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const 47988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 47998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function); 48008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!functionCallFrame) 48018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* codeBlock = functionCallFrame->codeBlock(); 4804635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (codeBlock->usesArguments()) { 4805635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(codeBlock->codeType() == FunctionCode); 4806e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block int argumentsRegister = codeBlock->argumentsRegister(); 4807ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister); 4808ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (JSValue arguments = functionCallFrame->uncheckedR(argumentsRegister).jsValue()) 4809ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return arguments; 4810ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch JSValue arguments = JSValue(new (callFrame) Arguments(functionCallFrame)); 4811ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch functionCallFrame->r(argumentsRegister) = arguments; 4812ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch functionCallFrame->r(realArgumentsRegister) = arguments; 4813ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return arguments; 48148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4816e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block Arguments* arguments = new (functionCallFrame) Arguments(functionCallFrame); 4817e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block arguments->copyRegisters(); 48188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return arguments; 48198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4821e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockJSValue Interpreter::retrieveCaller(CallFrame* callFrame, JSFunction* function) const 48228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function); 48248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!functionCallFrame) 48258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* callerFrame = functionCallFrame->callerFrame(); 48288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callerFrame->hasHostCallFrameFlag()) 48298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian JSValue caller = callerFrame->callee(); 48328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!caller) 48338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 48348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return caller; 48368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const 48398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian function = JSValue(); 48418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lineNumber = -1; 48428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sourceURL = UString(); 48438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CallFrame* callerFrame = callFrame->callerFrame(); 48458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (callerFrame->hasHostCallFrameFlag()) 48468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 48478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 48488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CodeBlock* callerCodeBlock = callerFrame->codeBlock(); 48498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!callerCodeBlock) 48508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 4851e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke unsigned bytecodeOffset = 0; 4852e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(INTERPRETER) 4853e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke if (!callerFrame->globalData().canUseJIT()) 48544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC()); 4855e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(JIT) 4856e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke else 48574576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC()); 4858e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 4859e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#else 48604576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC()); 4861e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif 48624576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1); 4863231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block sourceID = callerCodeBlock->ownerExecutable()->sourceID(); 4864231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block sourceURL = callerCodeBlock->ownerExecutable()->sourceURL(); 48658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project function = callerFrame->callee(); 48668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4868e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockCallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, JSFunction* function) 48698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 48708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (CallFrame* candidate = callFrame; candidate; candidate = candidate->callerFrame()->removeHostCallFrameFlag()) { 48718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (candidate->callee() == function) 48728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return candidate; 48738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 48748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 48758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 48768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4877231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::enableSampler() 4878231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4879231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(OPCODE_SAMPLING) 4880231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_sampler) { 4881231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampler.set(new SamplingTool(this)); 4882231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampler->setup(); 4883231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 4884231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4885231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4886231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::dumpSampleData(ExecState* exec) 4887231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4888231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(OPCODE_SAMPLING) 4889231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_sampler) 4890231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampler->dump(exec); 4891231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else 4892231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block UNUSED_PARAM(exec); 4893231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4894231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4895231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::startSampling() 4896231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4897231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(SAMPLING_THREAD) 4898231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_sampleEntryDepth) 4899231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingThread::start(); 4900231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4901231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampleEntryDepth++; 4902231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4903231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4904231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Interpreter::stopSampling() 4905231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4906231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(SAMPLING_THREAD) 4907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_sampleEntryDepth--; 4908231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_sampleEntryDepth) 4909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block SamplingThread::stop(); 4910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 4911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 4912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 49138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 4914