Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/WebKit/JavaScriptCore/VM/Machine.cpp

Issue 10670: Do another merge using nifty new merge script (CL for that coming soon). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 } 573 }
574 574
575 static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, C odeBlock* codeBlock, const Instruction* vPC, JSValue* value, JSValue*& exception Data) 575 static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, C odeBlock* codeBlock, const Instruction* vPC, JSValue* value, JSValue*& exception Data)
576 { 576 {
577 if (value->isObject()) 577 if (value->isObject())
578 return false; 578 return false;
579 exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instance of" : "in" , value, vPC, codeBlock); 579 exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instance of" : "in" , value, vPC, codeBlock);
580 return true; 580 return true;
581 } 581 }
582 582
583 NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, int argv, int argc, JSV alue*& exceptionValue) 583 NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, RegisterFile* regi sterFile, Register* argv, int argc, int registerOffset, JSValue*& exceptionValue )
584 { 584 {
585 if (argc < 2) 585 if (argc < 2)
586 return jsUndefined(); 586 return jsUndefined();
587 587
588 JSValue* program = callFrame[argv + 1].jsValue(callFrame); 588 JSValue* program = argv[1].jsValue(callFrame);
589 589
590 if (!program->isString()) 590 if (!program->isString())
591 return program; 591 return program;
592 592
593 UString programSource = asString(program)->value(); 593 UString programSource = asString(program)->value();
594 594
595 ScopeChainNode* scopeChain = callFrame->scopeChain();
595 CodeBlock* codeBlock = callFrame->codeBlock(); 596 CodeBlock* codeBlock = callFrame->codeBlock();
596 RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programS ource, scopeChain, exceptionValue); 597 RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programS ource, scopeChain, exceptionValue);
597 598
598 JSValue* result = jsUndefined(); 599 JSValue* result = jsUndefined();
599 if (evalNode) 600 if (evalNode)
600 result = callFrame->globalData().machine->execute(evalNode.get(), callFr ame, thisObj, callFrame->registers() - registerFile->start() + argv + 1 + Regist erFile::CallFrameHeaderSize, scopeChain, &exceptionValue); 601 result = callFrame->globalData().machine->execute(evalNode.get(), callFr ame, callFrame->thisValue()->toThisObject(callFrame), callFrame->registers() - r egisterFile->start() + registerOffset, scopeChain, &exceptionValue);
601 602
602 return result; 603 return result;
603 } 604 }
604 605
605 Machine::Machine() 606 Machine::Machine()
606 : m_sampler(0) 607 : m_sampler(0)
607 #if ENABLE(CTI) 608 #if ENABLE(CTI)
608 , m_ctiArrayLengthTrampoline(0) 609 , m_ctiArrayLengthTrampoline(0)
609 , m_ctiStringLengthTrampoline(0) 610 , m_ctiStringLengthTrampoline(0)
610 , m_jitCodeBuffer(new JITCodeBuffer(1024 * 1024)) 611 , m_jitCodeBuffer(new JITCodeBuffer(1024 * 1024))
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 649
649 Machine::~Machine() 650 Machine::~Machine()
650 { 651 {
651 #if ENABLE(CTI) 652 #if ENABLE(CTI)
652 CTI::freeCTIMachineTrampolines(this); 653 CTI::freeCTIMachineTrampolines(this);
653 #endif 654 #endif
654 } 655 }
655 656
656 #ifndef NDEBUG 657 #ifndef NDEBUG
657 658
658 void Machine::dumpCallFrame(const RegisterFile* registerFile, CallFrame* callFra me) 659 void Machine::dumpCallFrame(CallFrame* callFrame)
659 { 660 {
660 JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject(); 661 callFrame->codeBlock()->dump(callFrame);
661 662 dumpRegisters(callFrame);
662 CodeBlock* codeBlock = callFrame->codeBlock();
663 codeBlock->dump(globalObject->globalExec());
664
665 dumpRegisters(registerFile, callFrame);
666 } 663 }
667 664
668 void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra me) 665 void Machine::dumpRegisters(CallFrame* callFrame)
669 { 666 {
670 printf("Register frame: \n\n"); 667 printf("Register frame: \n\n");
671 printf("----------------------------------------------------\n"); 668 printf("----------------------------------------------------\n");
672 printf(" use | address | value \n"); 669 printf(" use | address | value \n");
673 printf("----------------------------------------------------\n"); 670 printf("----------------------------------------------------\n");
674 671
675 CodeBlock* codeBlock = callFrame->codeBlock(); 672 CodeBlock* codeBlock = callFrame->codeBlock();
673 RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globa lData()->machine->registerFile();
676 const Register* it; 674 const Register* it;
677 const Register* end; 675 const Register* end;
678 676
679 if (codeBlock->codeType == GlobalCode) { 677 if (codeBlock->codeType == GlobalCode) {
680 it = registerFile->lastGlobal(); 678 it = registerFile->lastGlobal();
681 end = it + registerFile->numGlobals(); 679 end = it + registerFile->numGlobals();
682 while (it != end) { 680 while (it != end) {
683 printf("[global var] | %10p | %10p \n", it, (*it).v()) ; 681 printf("[global var] | %10p | %10p \n", it, (*it).v()) ;
684 ++it; 682 ++it;
685 } 683 }
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 1014
1017 m_registerFile.shrink(oldEnd); 1015 m_registerFile.shrink(oldEnd);
1018 return result; 1016 return result;
1019 } 1017 }
1020 1018
1021 JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th isObj, ScopeChainNode* scopeChain, JSValue** exception) 1019 JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th isObj, ScopeChainNode* scopeChain, JSValue** exception)
1022 { 1020 {
1023 return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNod e->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scope Chain, exception); 1021 return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNod e->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scope Chain, exception);
1024 } 1022 }
1025 1023
1026 JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th isObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception) 1024 JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th isObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue** exception )
1027 { 1025 {
1028 ASSERT(!scopeChain->globalData->exception); 1026 ASSERT(!scopeChain->globalData->exception);
1029 1027
1030 if (m_reentryDepth >= MaxReentryDepth) { 1028 if (m_reentryDepth >= MaxReentryDepth) {
1031 *exception = createStackOverflowError(callFrame); 1029 *exception = createStackOverflowError(callFrame);
1032 return jsNull(); 1030 return jsNull();
1033 } 1031 }
1034 1032
1035 DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData( ).dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain ->globalObject()); 1033 DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData( ).dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain ->globalObject());
1036 1034
(...skipping 25 matching lines...) Expand all
1062 const DeclarationStacks::FunctionStack& functionStack = codeBlock->owner Node->functionStack(); 1060 const DeclarationStacks::FunctionStack& functionStack = codeBlock->owner Node->functionStack();
1063 DeclarationStacks::FunctionStack::const_iterator functionStackEnd = func tionStack.end(); 1061 DeclarationStacks::FunctionStack::const_iterator functionStackEnd = func tionStack.end();
1064 for (DeclarationStacks::FunctionStack::const_iterator it = functionStack .begin(); it != functionStackEnd; ++it) { 1062 for (DeclarationStacks::FunctionStack::const_iterator it = functionStack .begin(); it != functionStackEnd; ++it) {
1065 PutPropertySlot slot; 1063 PutPropertySlot slot;
1066 variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(c allFrame, scopeChain), slot); 1064 variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(c allFrame, scopeChain), slot);
1067 } 1065 }
1068 1066
1069 } 1067 }
1070 1068
1071 Register* oldEnd = m_registerFile.end(); 1069 Register* oldEnd = m_registerFile.end();
1072 Register* newEnd = m_registerFile.start() + registerOffset + codeBlock->numC alleeRegisters; 1070 Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock ->numCalleeRegisters;
1073 if (!m_registerFile.grow(newEnd)) { 1071 if (!m_registerFile.grow(newEnd)) {
1074 *exception = createStackOverflowError(callFrame); 1072 *exception = createStackOverflowError(callFrame);
1075 return jsNull(); 1073 return jsNull();
1076 } 1074 }
1077 1075
1078 CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + registe rOffset); 1076 CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalR egisterOffset);
1079 1077
1080 // a 0 codeBlock indicates a built-in caller 1078 // a 0 codeBlock indicates a built-in caller
1081 newCallFrame[codeBlock->thisRegister] = thisObj; 1079 newCallFrame[codeBlock->thisRegister] = thisObj;
1082 newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag (), 0, 0, 0); 1080 newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag (), 0, 0, 0);
1083 1081
1084 if (codeBlock->needsFullScopeChain) 1082 if (codeBlock->needsFullScopeChain)
1085 scopeChain->ref(); 1083 scopeChain->ref();
1086 1084
1087 Profiler** profiler = Profiler::enabledProfilerReference(); 1085 Profiler** profiler = Profiler::enabledProfilerReference();
1088 if (*profiler) 1086 if (*profiler)
(...skipping 2168 matching lines...) Expand 10 before | Expand all | Expand 10 after
3257 */ 3255 */
3258 int dst = (++vPC)->u.operand; 3256 int dst = (++vPC)->u.operand;
3259 int func = (++vPC)->u.operand; 3257 int func = (++vPC)->u.operand;
3260 3258
3261 callFrame[dst] = callFrame->codeBlock()->functionExpressions[func]->make Function(callFrame, callFrame->scopeChain()); 3259 callFrame[dst] = callFrame->codeBlock()->functionExpressions[func]->make Function(callFrame, callFrame->scopeChain());
3262 3260
3263 ++vPC; 3261 ++vPC;
3264 NEXT_OPCODE; 3262 NEXT_OPCODE;
3265 } 3263 }
3266 BEGIN_OPCODE(op_call_eval) { 3264 BEGIN_OPCODE(op_call_eval) {
3267 /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n) 3265 /* call_eval dst(r) func(r) argCount(n) registerOffset(n)
3268 3266
3269 Call a function named "eval" with no explicit "this" value 3267 Call a function named "eval" with no explicit "this" value
3270 (which may therefore be the eval operator). If register 3268 (which may therefore be the eval operator). If register
3271 thisVal is the global object, and register func contains 3269 thisVal is the global object, and register func contains
3272 that global object's original global eval function, then 3270 that global object's original global eval function, then
3273 perform the eval operator in local scope (interpreting 3271 perform the eval operator in local scope (interpreting
3274 the argument registers as for the "call" 3272 the argument registers as for the "call"
3275 opcode). Otherwise, act exactly as the "call" opcode would. 3273 opcode). Otherwise, act exactly as the "call" opcode would.
3276 */ 3274 */
3277 3275
3278 int dst = vPC[1].u.operand; 3276 int dst = vPC[1].u.operand;
3279 int func = vPC[2].u.operand; 3277 int func = vPC[2].u.operand;
3280 int thisVal = vPC[3].u.operand; 3278 int argCount = vPC[3].u.operand;
3281 int firstArg = vPC[4].u.operand; 3279 int registerOffset = vPC[4].u.operand;
3282 int argCount = vPC[5].u.operand;
3283 3280
3284 JSValue* funcVal = callFrame[func].jsValue(callFrame); 3281 JSValue* funcVal = callFrame[func].jsValue(callFrame);
3285 JSValue* baseVal = callFrame[thisVal].jsValue(callFrame);
3286 3282
3287 ScopeChainNode* scopeChain = callFrame->scopeChain(); 3283 Register* newCallFrame = callFrame->registers() + registerOffset;
3288 if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->glob alObject()->evalFunction()) { 3284 Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argC ount;
3289 JSObject* thisObject = asObject(callFrame[callFrame->codeBlock()->th isRegister].jsValue(callFrame)); 3285 JSValue* thisValue = argv[0].jsValue(callFrame);
3290 JSValue* result = callEval(callFrame, thisObject, scopeChain, regist erFile, firstArg, argCount, exceptionValue); 3286 JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
3287
3288 if (thisValue == globalObject && funcVal == globalObject->evalFunction() ) {
3289 JSValue* result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
3291 if (exceptionValue) 3290 if (exceptionValue)
3292 goto vm_throw; 3291 goto vm_throw;
3293
3294 callFrame[dst] = result; 3292 callFrame[dst] = result;
3295 3293
3296 vPC += 7; 3294 vPC += 5;
3297 NEXT_OPCODE; 3295 NEXT_OPCODE;
3298 } 3296 }
3299 3297
3300 // We didn't find the blessed version of eval, so reset vPC and process 3298 // We didn't find the blessed version of eval, so process this
3301 // this instruction as a normal function call, supplying the proper 'thi s' 3299 // instruction as a normal function call.
3302 // value.
3303 callFrame[thisVal] = baseVal->toThisObject(callFrame);
3304 3300
3305 #if HAVE(COMPUTED_GOTO) 3301 #if HAVE(COMPUTED_GOTO)
3306 // Hack around gcc performance quirk by performing an indirect goto 3302 // Hack around gcc performance quirk by performing an indirect goto
3307 // in order to set the vPC -- attempting to do so directly results in a 3303 // in order to set the vPC -- attempting to do so directly results in a
3308 // significant regression. 3304 // significant regression.
3309 goto *op_call_indirect; // indirect goto -> op_call 3305 goto *op_call_indirect; // indirect goto -> op_call
3310 #endif 3306 #endif
3311 // fall through to op_call 3307 // fall through to op_call
3312 } 3308 }
3313 BEGIN_OPCODE(op_call) { 3309 BEGIN_OPCODE(op_call) {
3314 /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset (n) 3310 /* call dst(r) func(r) argCount(n) registerOffset(n)
3315 3311
3316 Perform a function call. Specifically, call register func 3312 Perform a function call.
3317 with a "this" value of register thisVal, and put the result 3313
3318 in register dst. 3314 registerOffset is the distance the callFrame pointer should move
3319 3315 before the VM initializes the new call frame's header.
3320 The arguments start at register firstArg and go up to 3316
3321 argCount, but the "this" value is considered an implicit 3317 dst is where op_ret should store its result.
3322 first argument, so the argCount should be one greater than
3323 the number of explicit arguments passed, and the register
3324 after firstArg should contain the actual first
3325 argument. This opcode will copy from the thisVal register
3326 to the firstArg register, unless the register index of
3327 thisVal is the special missing this object marker, which is
3328 2^31-1; in that case, the global object will be used as the
3329 "this" value.
3330
3331 If func is a native code function, then this opcode calls
3332 it and returns the value immediately.
3333
3334 But if it is a JS function, then the current scope chain
3335 and code block is set to the function's, and we slide the
3336 register window so that the arguments would form the first
3337 few local registers of the called function's register
3338 window. In addition, a call frame header is written
3339 immediately before the arguments; see the call frame
3340 documentation for an explanation of how many registers a
3341 call frame takes and what they contain. That many registers
3342 before the firstArg register will be overwritten by the
3343 call. In addition, any registers higher than firstArg +
3344 argCount may be overwritten. Once this setup is complete,
3345 execution continues from the called function's first
3346 argument, and does not return until a "ret" opcode is
3347 encountered.
3348 */ 3318 */
3349 3319
3350 int dst = vPC[1].u.operand; 3320 int dst = vPC[1].u.operand;
3351 int func = vPC[2].u.operand; 3321 int func = vPC[2].u.operand;
3352 int thisVal = vPC[3].u.operand; 3322 int argCount = vPC[3].u.operand;
3353 int firstArg = vPC[4].u.operand; 3323 int registerOffset = vPC[4].u.operand;
3354 int argCount = vPC[5].u.operand;
3355 int registerOffset = vPC[6].u.operand;
3356 3324
3357 JSValue* v = callFrame[func].jsValue(callFrame); 3325 JSValue* v = callFrame[func].jsValue(callFrame);
3358 3326
3359 CallData callData; 3327 CallData callData;
3360 CallType callType = v->getCallData(callData); 3328 CallType callType = v->getCallData(callData);
3361 3329
3362 if (callType == CallTypeJS) { 3330 if (callType == CallTypeJS) {
3363 ScopeChainNode* callDataScopeChain = callData.js.scopeChain; 3331 ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
3364 FunctionBodyNode* functionBodyNode = callData.js.functionBody; 3332 FunctionBodyNode* functionBodyNode = callData.js.functionBody;
3365 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeC hain); 3333 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeC hain);
3366 3334
3367 callFrame[firstArg] = thisVal == missingThisObjectMarker() ? callFra me->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
3368
3369 CallFrame* previousCallFrame = callFrame; 3335 CallFrame* previousCallFrame = callFrame;
3370 3336
3371 callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, c allFrame, registerOffset, argCount); 3337 callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, c allFrame, registerOffset, argCount);
3372 if (UNLIKELY(!callFrame)) { 3338 if (UNLIKELY(!callFrame)) {
3373 callFrame = previousCallFrame; 3339 callFrame = previousCallFrame;
3374 exceptionValue = createStackOverflowError(callFrame); 3340 exceptionValue = createStackOverflowError(callFrame);
3375 goto vm_throw; 3341 goto vm_throw;
3376 } 3342 }
3377 3343
3378 callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousC allFrame, dst, argCount, asFunction(v)); 3344 callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousC allFrame, dst, argCount, asFunction(v));
3379 vPC = newCodeBlock->instructions.begin(); 3345 vPC = newCodeBlock->instructions.begin();
3380 3346
3381 #if ENABLE(OPCODE_STATS) 3347 #if ENABLE(OPCODE_STATS)
3382 OpcodeStats::resetLastInstruction(); 3348 OpcodeStats::resetLastInstruction();
3383 #endif 3349 #endif
3384 3350
3385 NEXT_OPCODE; 3351 NEXT_OPCODE;
3386 } 3352 }
3387 3353
3388 if (callType == CallTypeHost) { 3354 if (callType == CallTypeHost) {
3389 JSValue* thisValue = thisVal == missingThisObjectMarker() ? callFram e->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
3390 ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
3391
3392 ScopeChainNode* scopeChain = callFrame->scopeChain(); 3355 ScopeChainNode* scopeChain = callFrame->scopeChain();
3393 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 3356 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
3394 newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0); 3357 newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0);
3358
3359 Register* thisRegister = newCallFrame->registers() - RegisterFile::C allFrameHeaderSize - argCount;
3360 ArgList args(thisRegister + 1, argCount - 1);
3361
3362 // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
3363 JSValue* thisValue = thisRegister->jsValue(callFrame);
3364 if (thisValue == jsNull())
3365 thisValue = callFrame->globalThisValue();
3395 3366
3396 JSValue* returnValue; 3367 JSValue* returnValue;
3397 { 3368 {
3398 SamplingTool::HostCallRecord callRecord(m_sampler); 3369 SamplingTool::HostCallRecord callRecord(m_sampler);
3399 returnValue = callData.native.function(newCallFrame, asObject(v) , thisValue, args); 3370 returnValue = callData.native.function(newCallFrame, asObject(v) , thisValue, args);
3400 } 3371 }
3401 VM_CHECK_EXCEPTION(); 3372 VM_CHECK_EXCEPTION();
3402 3373
3403 callFrame[dst] = returnValue; 3374 callFrame[dst] = returnValue;
3404 3375
3405 vPC += 7; 3376 vPC += 5;
3406 NEXT_OPCODE; 3377 NEXT_OPCODE;
3407 } 3378 }
3408 3379
3409 ASSERT(callType == CallTypeNone); 3380 ASSERT(callType == CallTypeNone);
3410 3381
3411 exceptionValue = createNotAFunctionError(callFrame, v, vPC, callFrame->c odeBlock()); 3382 exceptionValue = createNotAFunctionError(callFrame, v, vPC, callFrame->c odeBlock());
3412 goto vm_throw; 3383 goto vm_throw;
3413 } 3384 }
3414 BEGIN_OPCODE(op_tear_off_activation) { 3385 BEGIN_OPCODE(op_tear_off_activation) {
3415 /* tear_off_activation activation(r) 3386 /* tear_off_activation activation(r)
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
3565 */ 3536 */
3566 3537
3567 Arguments* arguments = new (globalData) Arguments(callFrame); 3538 Arguments* arguments = new (globalData) Arguments(callFrame);
3568 callFrame->setCalleeArguments(arguments); 3539 callFrame->setCalleeArguments(arguments);
3569 callFrame[RegisterFile::ArgumentsRegister] = arguments; 3540 callFrame[RegisterFile::ArgumentsRegister] = arguments;
3570 3541
3571 ++vPC; 3542 ++vPC;
3572 NEXT_OPCODE; 3543 NEXT_OPCODE;
3573 } 3544 }
3574 BEGIN_OPCODE(op_construct) { 3545 BEGIN_OPCODE(op_construct) {
3575 /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) reg isterOffset(n) 3546 /* construct dst(r) func(r) argCount(n) registerOffset(n) proto(r) thisR egister(r)
3576 3547
3577 Invoke register "constr" as a constructor. For JS 3548 Invoke register "func" as a constructor. For JS
3578 functions, the calling convention is exactly as for the 3549 functions, the calling convention is exactly as for the
3579 "call" opcode, except that the "this" value is a newly 3550 "call" opcode, except that the "this" value is a newly
3580 created Object. For native constructors, a null "this" 3551 created Object. For native constructors, no "this"
3581 value is passed. In either case, the firstArg and argCount 3552 value is passed. In either case, the argCount and registerOffset
3582 registers are interpreted as for the "call" opcode. 3553 registers are interpreted as for the "call" opcode.
3583 3554
3584 Register constrProto must contain the prototype property of 3555 Register proto must contain the prototype property of
3585 register constsr. This is to enable polymorphic inline 3556 register func. This is to enable polymorphic inline
3586 caching of this lookup. 3557 caching of this lookup.
3587 */ 3558 */
3588 3559
3589 int dst = vPC[1].u.operand; 3560 int dst = vPC[1].u.operand;
3590 int constr = vPC[2].u.operand; 3561 int func = vPC[2].u.operand;
3591 int constrProto = vPC[3].u.operand; 3562 int argCount = vPC[3].u.operand;
3592 int firstArg = vPC[4].u.operand; 3563 int registerOffset = vPC[4].u.operand;
3593 int argCount = vPC[5].u.operand; 3564 int proto = vPC[5].u.operand;
3594 int registerOffset = vPC[6].u.operand; 3565 int thisRegister = vPC[6].u.operand;
3595 3566
3596 JSValue* v = callFrame[constr].jsValue(callFrame); 3567 JSValue* v = callFrame[func].jsValue(callFrame);
3597 3568
3598 ConstructData constructData; 3569 ConstructData constructData;
3599 ConstructType constructType = v->getConstructData(constructData); 3570 ConstructType constructType = v->getConstructData(constructData);
3600 3571
3601 if (constructType == ConstructTypeJS) { 3572 if (constructType == ConstructTypeJS) {
3602 ScopeChainNode* callDataScopeChain = constructData.js.scopeChain; 3573 ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
3603 FunctionBodyNode* functionBodyNode = constructData.js.functionBody; 3574 FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
3604 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeC hain); 3575 CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeC hain);
3605 3576
3606 StructureID* structure; 3577 StructureID* structure;
3607 JSValue* prototype = callFrame[constrProto].jsValue(callFrame); 3578 JSValue* prototype = callFrame[proto].jsValue(callFrame);
3608 if (prototype->isObject()) 3579 if (prototype->isObject())
3609 structure = asObject(prototype)->inheritorID(); 3580 structure = asObject(prototype)->inheritorID();
3610 else 3581 else
3611 structure = callDataScopeChain->globalObject()->emptyObjectStruc ture(); 3582 structure = callDataScopeChain->globalObject()->emptyObjectStruc ture();
3612 JSObject* newObject = new (globalData) JSObject(structure); 3583 JSObject* newObject = new (globalData) JSObject(structure);
3613 3584
3614 callFrame[firstArg] = newObject; // "this" value 3585 callFrame[thisRegister] = newObject; // "this" value
3615 3586
3616 CallFrame* previousCallFrame = callFrame; 3587 CallFrame* previousCallFrame = callFrame;
3617 3588
3618 callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, c allFrame, registerOffset, argCount); 3589 callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, c allFrame, registerOffset, argCount);
3619 if (UNLIKELY(!callFrame)) { 3590 if (UNLIKELY(!callFrame)) {
3620 callFrame = previousCallFrame; 3591 callFrame = previousCallFrame;
3621 exceptionValue = createStackOverflowError(callFrame); 3592 exceptionValue = createStackOverflowError(callFrame);
3622 goto vm_throw; 3593 goto vm_throw;
3623 } 3594 }
3624 3595
3625 callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousC allFrame, dst, argCount, asFunction(v)); 3596 callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousC allFrame, dst, argCount, asFunction(v));
3626 vPC = newCodeBlock->instructions.begin(); 3597 vPC = newCodeBlock->instructions.begin();
3627 3598
3628 #if ENABLE(OPCODE_STATS) 3599 #if ENABLE(OPCODE_STATS)
3629 OpcodeStats::resetLastInstruction(); 3600 OpcodeStats::resetLastInstruction();
3630 #endif 3601 #endif
3631 3602
3632 NEXT_OPCODE; 3603 NEXT_OPCODE;
3633 } 3604 }
3634 3605
3635 if (constructType == ConstructTypeHost) { 3606 if (constructType == ConstructTypeHost) {
3636 ArgList args(callFrame->registers() + firstArg + 1, argCount - 1); 3607 ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1 );
3637 3608
3638 ScopeChainNode* scopeChain = callFrame->scopeChain(); 3609 ScopeChainNode* scopeChain = callFrame->scopeChain();
3639 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset); 3610 CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
3640 newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0); 3611 newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
3641 3612
3642 JSValue* returnValue; 3613 JSValue* returnValue;
3643 { 3614 {
3644 SamplingTool::HostCallRecord callRecord(m_sampler); 3615 SamplingTool::HostCallRecord callRecord(m_sampler);
3645 returnValue = constructData.native.function(newCallFrame, asObje ct(v), args); 3616 returnValue = constructData.native.function(newCallFrame, asObje ct(v), args);
3646 } 3617 }
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
4318 #define CTI_STACK_HACK() (void)0 4289 #define CTI_STACK_HACK() (void)0
4319 #define CTI_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&CTI_RETURN_ADDRESS_ SLOT, address); 4290 #define CTI_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&CTI_RETURN_ADDRESS_ SLOT, address);
4320 #define CTI_RETURN_ADDRESS CTI_RETURN_ADDRESS_SLOT 4291 #define CTI_RETURN_ADDRESS CTI_RETURN_ADDRESS_SLOT
4321 4292
4322 #endif 4293 #endif
4323 4294
4324 // The reason this is not inlined is to avoid having to do a PIC branch 4295 // The reason this is not inlined is to avoid having to do a PIC branch
4325 // to get the address of the ctiVMThrowTrampoline function. It's also 4296 // to get the address of the ctiVMThrowTrampoline function. It's also
4326 // good to keep the code size down by leaving as much of the exception 4297 // good to keep the code size down by leaving as much of the exception
4327 // handling code out of line as possible. 4298 // handling code out of line as possible.
4328 static NEVER_INLINE void setUpThrowTrampolineReturnAddress(JSGlobalData* globalD ata, void*& returnAddress) 4299 static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
4329 { 4300 {
4330 ASSERT(globalData->exception); 4301 ASSERT(globalData->exception);
4331 globalData->throwReturnAddress = returnAddress; 4302 globalData->exceptionLocation = exceptionLocation;
4332 ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampo line)); 4303 ctiSetReturnAddress(&returnAddressSlot, reinterpret_cast<void*>(ctiVMThrowTr ampoline));
4304 }
4305
4306 static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ata* globalData, void* exceptionLocation, void*& returnAddressSlot)
4307 {
4308 globalData->exception = createStackOverflowError(callFrame);
4309 returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
4333 } 4310 }
4334 4311
4335 #define VM_THROW_EXCEPTION() \ 4312 #define VM_THROW_EXCEPTION() \
4336 do { \ 4313 do { \
4337 VM_THROW_EXCEPTION_AT_END(); \ 4314 VM_THROW_EXCEPTION_AT_END(); \
4338 return 0; \ 4315 return 0; \
4339 } while (0) 4316 } while (0)
4340 #define VM_THROW_EXCEPTION_2() \ 4317 #define VM_THROW_EXCEPTION_2() \
4341 do { \ 4318 do { \
4342 VM_THROW_EXCEPTION_AT_END(); \ 4319 VM_THROW_EXCEPTION_AT_END(); \
4343 VoidPtrPairValue pair = {{ 0, 0 }}; \ 4320 VoidPtrPairValue pair = {{ 0, 0 }}; \
4344 return pair.i; \ 4321 return pair.i; \
4345 } while (0) 4322 } while (0)
4346 #define VM_THROW_EXCEPTION_AT_END() \ 4323 #define VM_THROW_EXCEPTION_AT_END() \
4347 setUpThrowTrampolineReturnAddress(ARG_globalData, CTI_RETURN_ADDRESS) 4324 returnToThrowTrampoline(ARG_globalData, CTI_RETURN_ADDRESS, CTI_RETURN_ADDRE SS)
4348 4325
4349 #define VM_CHECK_EXCEPTION() \ 4326 #define VM_CHECK_EXCEPTION() \
4350 do { \ 4327 do { \
4351 if (UNLIKELY(ARG_globalData->exception != noValue())) \ 4328 if (UNLIKELY(ARG_globalData->exception != noValue())) \
4352 VM_THROW_EXCEPTION(); \ 4329 VM_THROW_EXCEPTION(); \
4353 } while (0) 4330 } while (0)
4354 #define VM_CHECK_EXCEPTION_AT_END() \ 4331 #define VM_CHECK_EXCEPTION_AT_END() \
4355 do { \ 4332 do { \
4356 if (UNLIKELY(ARG_globalData->exception != noValue())) \ 4333 if (UNLIKELY(ARG_globalData->exception != noValue())) \
4357 VM_THROW_EXCEPTION_AT_END(); \ 4334 VM_THROW_EXCEPTION_AT_END(); \
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4445 void Machine::cti_timeout_check(CTI_ARGS) 4422 void Machine::cti_timeout_check(CTI_ARGS)
4446 { 4423 {
4447 CTI_STACK_HACK(); 4424 CTI_STACK_HACK();
4448 4425
4449 if (ARG_globalData->machine->checkTimeout(ARG_callFrame->dynamicGlobalObject ())) { 4426 if (ARG_globalData->machine->checkTimeout(ARG_callFrame->dynamicGlobalObject ())) {
4450 ARG_globalData->exception = createInterruptedExecutionException(ARG_glob alData); 4427 ARG_globalData->exception = createInterruptedExecutionException(ARG_glob alData);
4451 VM_THROW_EXCEPTION_AT_END(); 4428 VM_THROW_EXCEPTION_AT_END();
4452 } 4429 }
4453 } 4430 }
4454 4431
4455 NEVER_INLINE void Machine::throwStackOverflowPreviousFrame(CallFrame* callFrame, JSGlobalData* globalData, void*& returnAddress)
4456 {
4457 globalData->exception = createStackOverflowError(callFrame->callerFrame());
4458 globalData->throwReturnAddress = callFrame->returnPC();
4459 ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampo line));
4460 }
4461
4462 void Machine::cti_register_file_check(CTI_ARGS) 4432 void Machine::cti_register_file_check(CTI_ARGS)
4463 { 4433 {
4464 CTI_STACK_HACK(); 4434 CTI_STACK_HACK();
4465 4435
4466 if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock() ->numCalleeRegisters))) 4436 if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock() ->numCalleeRegisters)))
4467 return; 4437 return;
4468 4438
4469 ARG_setCallFrame(ARG_callFrame->callerFrame()); 4439 // Rewind to the previous call frame because op_call already optimistically
4470 throwStackOverflowPreviousFrame(ARG_callFrame, ARG_globalData, CTI_RETURN_AD DRESS); 4440 // moved the call frame forward.
4441 CallFrame* oldCallFrame = ARG_callFrame->callerFrame();
4442 ARG_setCallFrame(oldCallFrame);
4443 throwStackOverflowError(oldCallFrame, ARG_globalData, oldCallFrame->returnPC (), CTI_RETURN_ADDRESS);
4471 } 4444 }
4472 4445
4473 int Machine::cti_op_loop_if_less(CTI_ARGS) 4446 int Machine::cti_op_loop_if_less(CTI_ARGS)
4474 { 4447 {
4475 CTI_STACK_HACK(); 4448 CTI_STACK_HACK();
4476 4449
4477 JSValue* src1 = ARG_src1; 4450 JSValue* src1 = ARG_src1;
4478 JSValue* src2 = ARG_src2; 4451 JSValue* src2 = ARG_src2;
4479 CallFrame* callFrame = ARG_callFrame; 4452 CallFrame* callFrame = ARG_callFrame;
4480 4453
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
4737 for (size_t i = 0; i < numParameters; ++i) 4710 for (size_t i = 0; i < numParameters; ++i)
4738 argv[i + argCount] = argv[i]; 4711 argv[i + argCount] = argv[i];
4739 4712
4740 callFrame = CallFrame::create(r); 4713 callFrame = CallFrame::create(r);
4741 callFrame->setCallerFrame(oldCallFrame); 4714 callFrame->setCallerFrame(oldCallFrame);
4742 } else { 4715 } else {
4743 size_t omittedArgCount = newCodeBlock->numParameters - argCount; 4716 size_t omittedArgCount = newCodeBlock->numParameters - argCount;
4744 Register* r = callFrame->registers() + omittedArgCount; 4717 Register* r = callFrame->registers() + omittedArgCount;
4745 Register* newEnd = r + newCodeBlock->numCalleeRegisters; 4718 Register* newEnd = r + newCodeBlock->numCalleeRegisters;
4746 if (!ARG_registerFile->grow(newEnd)) { 4719 if (!ARG_registerFile->grow(newEnd)) {
4747 ARG_globalData->exception = createStackOverflowError(oldCallFrame); 4720 // Rewind to the previous call frame because op_call already optimis tically
4748 VM_THROW_EXCEPTION_2(); 4721 // moved the call frame forward.
4722 ARG_setCallFrame(oldCallFrame);
4723 throwStackOverflowError(oldCallFrame, ARG_globalData, CTI_RETURN_ADD RESS, CTI_RETURN_ADDRESS);
4724 VoidPtrPairValue pair = {{ 0, 0 }};
4725 return pair.i;
4749 } 4726 }
4750 4727
4751 Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount ; 4728 Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount ;
4752 for (size_t i = 0; i < omittedArgCount; ++i) 4729 for (size_t i = 0; i < omittedArgCount; ++i)
4753 argv[i] = jsUndefined(); 4730 argv[i] = jsUndefined();
4754 4731
4755 callFrame = CallFrame::create(r); 4732 callFrame = CallFrame::create(r);
4756 callFrame->setCallerFrame(oldCallFrame); 4733 callFrame->setCallerFrame(oldCallFrame);
4757 } 4734 }
4758 4735
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4803 callFrame->init(0, ARG_instr4 + 1, previousCallFrame->scopeChain(), prev iousCallFrame, 0, argCount, 0); 4780 callFrame->init(0, ARG_instr4 + 1, previousCallFrame->scopeChain(), prev iousCallFrame, 0, argCount, 0);
4804 ARG_setCallFrame(callFrame); 4781 ARG_setCallFrame(callFrame);
4805 4782
4806 Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHea derSize - argCount; 4783 Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHea derSize - argCount;
4807 ArgList argList(argv + 1, argCount - 1); 4784 ArgList argList(argv + 1, argCount - 1);
4808 4785
4809 JSValue* returnValue; 4786 JSValue* returnValue;
4810 { 4787 {
4811 SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); 4788 SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
4812 4789
4813 // All host methods should be calling toThisObject, but this is not presently the case. 4790 // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
4814 JSValue* thisValue = argv[0].jsValue(callFrame); 4791 JSValue* thisValue = argv[0].jsValue(callFrame);
4815 if (thisValue == jsNull()) 4792 if (thisValue == jsNull())
4816 thisValue = callFrame->globalThisValue(); 4793 thisValue = callFrame->globalThisValue();
4817 4794
4818 returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList); 4795 returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList);
4819 } 4796 }
4820 ARG_setCallFrame(previousCallFrame); 4797 ARG_setCallFrame(previousCallFrame);
4821 VM_CHECK_EXCEPTION(); 4798 VM_CHECK_EXCEPTION();
4822 4799
4823 return returnValue; 4800 return returnValue;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 JSObject* Machine::cti_op_construct_JSConstruct(CTI_ARGS) 4904 JSObject* Machine::cti_op_construct_JSConstruct(CTI_ARGS)
4928 { 4905 {
4929 CTI_STACK_HACK(); 4906 CTI_STACK_HACK();
4930 4907
4931 #ifndef NDEBUG 4908 #ifndef NDEBUG
4932 ConstructData constructData; 4909 ConstructData constructData;
4933 ASSERT(asFunction(ARG_src1)->getConstructData(constructData) == ConstructTyp eJS); 4910 ASSERT(asFunction(ARG_src1)->getConstructData(constructData) == ConstructTyp eJS);
4934 #endif 4911 #endif
4935 4912
4936 StructureID* structure; 4913 StructureID* structure;
4937 if (ARG_src5->isObject()) 4914 if (ARG_src4->isObject())
4938 structure = asObject(ARG_src5)->inheritorID(); 4915 structure = asObject(ARG_src4)->inheritorID();
4939 else 4916 else
4940 structure = asFunction(ARG_src1)->m_scopeChain.node()->globalObject()->e mptyObjectStructure(); 4917 structure = asFunction(ARG_src1)->m_scopeChain.node()->globalObject()->e mptyObjectStructure();
4941 return new (ARG_globalData) JSObject(structure); 4918 return new (ARG_globalData) JSObject(structure);
4942 } 4919 }
4943 4920
4944 JSValue* Machine::cti_op_construct_NotJSConstruct(CTI_ARGS) 4921 JSValue* Machine::cti_op_construct_NotJSConstruct(CTI_ARGS)
4945 { 4922 {
4946 CTI_STACK_HACK(); 4923 CTI_STACK_HACK();
4947 4924
4948 CallFrame* callFrame = ARG_callFrame; 4925 CallFrame* callFrame = ARG_callFrame;
4949 4926
4950 JSValue* constrVal = ARG_src1; 4927 JSValue* constrVal = ARG_src1;
4951 int argCount = ARG_int3; 4928 int argCount = ARG_int3;
4952 int firstArg = ARG_int6; 4929 int thisRegister = ARG_int5;
4953 4930
4954 ConstructData constructData; 4931 ConstructData constructData;
4955 ConstructType constructType = constrVal->getConstructData(constructData); 4932 ConstructType constructType = constrVal->getConstructData(constructData);
4956 4933
4957 if (constructType == ConstructTypeHost) { 4934 if (constructType == ConstructTypeHost) {
4958 ArgList argList(callFrame->registers() + firstArg + 1, argCount - 1); 4935 ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1) ;
4959 4936
4960 JSValue* returnValue; 4937 JSValue* returnValue;
4961 { 4938 {
4962 SamplingTool::HostCallRecord callRecord(CTI_SAMPLER); 4939 SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
4963 returnValue = constructData.native.function(callFrame, asObject(cons trVal), argList); 4940 returnValue = constructData.native.function(callFrame, asObject(cons trVal), argList);
4964 } 4941 }
4965 VM_CHECK_EXCEPTION(); 4942 VM_CHECK_EXCEPTION();
4966 4943
4967 return returnValue; 4944 return returnValue;
4968 } 4945 }
4969 4946
4970 ASSERT(constructType == ConstructTypeNone); 4947 ASSERT(constructType == ConstructTypeNone);
4971 4948
4972 ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr4, callFrame->codeBlock()); 4949 ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr6, callFrame->codeBlock());
4973 VM_THROW_EXCEPTION(); 4950 VM_THROW_EXCEPTION();
4974 } 4951 }
4975 4952
4976 JSValue* Machine::cti_op_get_by_val(CTI_ARGS) 4953 JSValue* Machine::cti_op_get_by_val(CTI_ARGS)
4977 { 4954 {
4978 CTI_STACK_HACK(); 4955 CTI_STACK_HACK();
4979 4956
4980 CallFrame* callFrame = ARG_callFrame; 4957 CallFrame* callFrame = ARG_callFrame;
4981 Machine* machine = ARG_globalData->machine; 4958 Machine* machine = ARG_globalData->machine;
4982 4959
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
5561 VM_CHECK_EXCEPTION_AT_END(); 5538 VM_CHECK_EXCEPTION_AT_END();
5562 return result; 5539 return result;
5563 } 5540 }
5564 5541
5565 JSValue* Machine::cti_op_call_eval(CTI_ARGS) 5542 JSValue* Machine::cti_op_call_eval(CTI_ARGS)
5566 { 5543 {
5567 CTI_STACK_HACK(); 5544 CTI_STACK_HACK();
5568 5545
5569 CallFrame* callFrame = ARG_callFrame; 5546 CallFrame* callFrame = ARG_callFrame;
5570 RegisterFile* registerFile = ARG_registerFile; 5547 RegisterFile* registerFile = ARG_registerFile;
5571 CodeBlock* codeBlock = callFrame->codeBlock();
5572 ScopeChainNode* scopeChain = callFrame->scopeChain();
5573 5548
5574 Machine* machine = ARG_globalData->machine; 5549 Machine* machine = ARG_globalData->machine;
5575 5550
5576 JSValue* funcVal = ARG_src1; 5551 JSValue* funcVal = ARG_src1;
5577 int registerOffset = ARG_int2; 5552 int registerOffset = ARG_int2;
5578 int argCount = ARG_int3; 5553 int argCount = ARG_int3;
5579 JSValue* baseVal = ARG_src5;
5580 5554
5581 if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalOb ject()->evalFunction()) { 5555 Register* newCallFrame = callFrame->registers() + registerOffset;
5582 JSObject* thisObject = callFrame[codeBlock->thisRegister].jsValue(callFr ame)->toThisObject(callFrame); 5556 Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount ;
5557 JSValue* thisValue = argv[0].jsValue(callFrame);
5558 JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
5559
5560 if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
5583 JSValue* exceptionValue = noValue(); 5561 JSValue* exceptionValue = noValue();
5584 JSValue* result = machine->callEval(callFrame, thisObject, scopeChain, r egisterFile, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argC ount, exceptionValue); 5562 JSValue* result = machine->callEval(callFrame, registerFile, argv, argCo unt, registerOffset, exceptionValue);
5585 if (UNLIKELY(exceptionValue != noValue())) { 5563 if (UNLIKELY(exceptionValue != noValue())) {
5586 ARG_globalData->exception = exceptionValue; 5564 ARG_globalData->exception = exceptionValue;
5587 VM_THROW_EXCEPTION_AT_END(); 5565 VM_THROW_EXCEPTION_AT_END();
5588 } 5566 }
5589 return result; 5567 return result;
5590 } 5568 }
5591 5569
5592 return JSImmediate::impossibleValue(); 5570 return JSImmediate::impossibleValue();
5593 } 5571 }
5594 5572
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
5937 5915
5938 ARG_globalData->machine->debug(callFrame, static_cast<DebugHookID>(debugHook ID), firstLine, lastLine); 5916 ARG_globalData->machine->debug(callFrame, static_cast<DebugHookID>(debugHook ID), firstLine, lastLine);
5939 } 5917 }
5940 5918
5941 JSValue* Machine::cti_vm_throw(CTI_ARGS) 5919 JSValue* Machine::cti_vm_throw(CTI_ARGS)
5942 { 5920 {
5943 CTI_STACK_HACK(); 5921 CTI_STACK_HACK();
5944 5922
5945 CallFrame* callFrame = ARG_callFrame; 5923 CallFrame* callFrame = ARG_callFrame;
5946 CodeBlock* codeBlock = callFrame->codeBlock(); 5924 CodeBlock* codeBlock = callFrame->codeBlock();
5925 JSGlobalData* globalData = ARG_globalData;
5947 5926
5948 ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(ARG_globalData->throwRetur nAddress)); 5927 ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(globalData->exceptionLocat ion));
5949 unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(ARG_globalData->th rowReturnAddress); 5928 unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(globalData->except ionLocation);
5950 5929
5951 JSValue* exceptionValue = ARG_globalData->exception; 5930 JSValue* exceptionValue = globalData->exception;
5952 ASSERT(exceptionValue); 5931 ASSERT(exceptionValue);
5953 ARG_globalData->exception = noValue(); 5932 globalData->exception = noValue();
5954 5933
5955 Instruction* handlerVPC = ARG_globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false); 5934 Instruction* handlerVPC = globalData->machine->throwException(callFrame, exc eptionValue, codeBlock->instructions.begin() + vPCIndex, false);
5956 5935
5957 if (!handlerVPC) { 5936 if (!handlerVPC) {
5958 *ARG_exception = exceptionValue; 5937 *ARG_exception = exceptionValue;
5959 return JSImmediate::nullImmediate(); 5938 return JSImmediate::nullImmediate();
5960 } 5939 }
5961 5940
5962 ARG_setCallFrame(callFrame); 5941 ARG_setCallFrame(callFrame);
5963 void* catchRoutine = callFrame->codeBlock()->nativeExceptionCodeForHandlerVP C(handlerVPC); 5942 void* catchRoutine = callFrame->codeBlock()->nativeExceptionCodeForHandlerVP C(handlerVPC);
5964 ASSERT(catchRoutine); 5943 ASSERT(catchRoutine);
5965 CTI_SET_RETURN_ADDRESS(catchRoutine); 5944 CTI_SET_RETURN_ADDRESS(catchRoutine);
5966 return exceptionValue; 5945 return exceptionValue;
5967 } 5946 }
5968 5947
5969 #undef CTI_RETURN_ADDRESS 5948 #undef CTI_RETURN_ADDRESS
5970 #undef CTI_SET_RETURN_ADDRESS 5949 #undef CTI_SET_RETURN_ADDRESS
5971 #undef CTI_STACK_HACK 5950 #undef CTI_STACK_HACK
5972 #undef VM_CHECK_EXCEPTION 5951 #undef VM_CHECK_EXCEPTION
5973 #undef VM_CHECK_EXCEPTION_AT_END 5952 #undef VM_CHECK_EXCEPTION_AT_END
5974 #undef VM_CHECK_EXCEPTION_VOID 5953 #undef VM_CHECK_EXCEPTION_VOID
5975 #undef VM_THROW_EXCEPTION 5954 #undef VM_THROW_EXCEPTION
5976 #undef VM_THROW_EXCEPTION_2 5955 #undef VM_THROW_EXCEPTION_2
5977 #undef VM_THROW_EXCEPTION_AT_END 5956 #undef VM_THROW_EXCEPTION_AT_END
5978 5957
5979 #endif // ENABLE(CTI) 5958 #endif // ENABLE(CTI)
5980 5959
5981 } // namespace JSC 5960 } // namespace JSC
OLDNEW
« no previous file with comments | « third_party/WebKit/JavaScriptCore/VM/Machine.h ('k') | third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698