Changeset 31783
- Timestamp:
- 04/10/08 13:27:40 (2 years ago)
- Location:
- branches/squirrelfish/JavaScriptCore
- Files:
-
- 7 modified
-
ChangeLog (modified) (1 diff)
-
VM/CodeBlock.h (modified) (1 diff)
-
VM/Machine.cpp (modified) (8 diffs)
-
VM/Machine.h (modified) (2 diffs)
-
kjs/function.cpp (modified) (3 diffs)
-
kjs/list.cpp (modified) (1 diff)
-
kjs/list.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/squirrelfish/JavaScriptCore/ChangeLog
r31774 r31783 1 2008-04-10 Geoffrey Garen <ggaren@apple.com> 2 3 Reviewed by Oliver Hunt and Sam Weinig. 4 5 Re-entrant execution of function code (global code -> built-in function 6 -> JS function): 7 8 Miraculously, sunspider --squirrelfish does not seem to complain. 9 10 A re-entrant function call is the same as a normal function call with 11 one exception: the re-entrant call leaves everything except for 12 CallerCodeBlock in the call frame header uninitialized, since the call 13 doesn't need to return to JS code. (It sets CallerCodeBlock to 0, to 14 indicate that the call shouldn't return to JS code.) 15 16 Also fixed a few issues along the way: 17 18 - Fixed two bugs in the read-write List implementation that caused 19 m_size and m_buffer to go stale. 20 21 - Changed native call code to update "r" *before* setting the return 22 value, since the call may in turn call JS code, which changes the value 23 of "r". 24 25 - Migrated initialization of "r" outside of Machine::privateExecute, 26 because global code and function code initialize "r" differently. 27 28 - Migrated a codegen warning from Machine::privateExecute to the wiki. 29 30 - Removed unnecessary "r" parameter from slideRegisterWindowForCall 31 32 * VM/Machine.cpp: 33 (KJS::slideRegisterWindowForCall): 34 (KJS::scopeChainForCall): 35 (KJS::Machine::execute): 36 (KJS::Machine::privateExecute): 37 * VM/Machine.h: 38 * kjs/function.cpp: 39 (KJS::FunctionImp::callAsFunction): 40 * kjs/list.cpp: 41 (KJS::List::getSlice): 42 * kjs/list.h: 43 (KJS::List::clear): 44 1 45 2008-04-10 Maciej Stachowiak <mjs@apple.com> 2 46 -
branches/squirrelfish/JavaScriptCore/VM/CodeBlock.h
r31701 r31783 31 31 #define CodeBlock_h 32 32 33 #include "Instruction.h" 34 #include "nodes.h" 35 #include "ustring.h" 33 36 #include <wtf/RefPtr.h> 34 37 #include <wtf/Vector.h> 35 #include "nodes.h"36 #include "Instruction.h"37 #include "UString.h"38 38 39 39 namespace KJS { -
branches/squirrelfish/JavaScriptCore/VM/Machine.cpp
r31773 r31783 296 296 } 297 297 298 ALWAYS_INLINE Register* slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, Register** registerBase, int registerOffset, int argv, int argc, Register* r) 299 { 298 ALWAYS_INLINE Register* slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, Register** registerBase, int registerOffset, int argv, int argc) 299 { 300 Register* r; 300 301 registerOffset += argv + argc + newCodeBlock->numVars; 302 301 303 if (argc == newCodeBlock->numParameters) { // correct number of arguments 302 304 size_t size = registerOffset + newCodeBlock->numTemporaries; … … 327 329 } 328 330 329 ALWAYS_INLINE ScopeChain* scopeChainForCall(CodeBlock* newCodeBlock, ScopeChain* callDataScopeChain, FunctionBodyNode* functionBody, Register* callFrame, Register** registerBase, Register* r)331 ALWAYS_INLINE ScopeChain* scopeChainForCall(CodeBlock* newCodeBlock, ScopeChain* callDataScopeChain, FunctionBodyNode* functionBody, Register* callFrame, Register** registerBase, Register* r) 330 332 { 331 333 ScopeChain* scopeChain; … … 413 415 registerFile->addGlobalSlots(codeBlock->numVars); 414 416 registerFile->grow(codeBlock->numTemporaries); 415 416 JSValue* result = privateExecute(Normal, exec, registerFile, scopeChain, codeBlock, exception); 417 Register* r = (*registerFile->basePointer()); 418 419 JSValue* result = privateExecute(Normal, exec, registerFile, r, scopeChain, codeBlock, exception); 417 420 418 421 registerFileStack->popRegisterFile(); … … 420 423 } 421 424 422 JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, ExecState* exec, RegisterFileStack* registerFileStack, ScopeChain* scopeChain, JSValue** exception)425 JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, const List& args, JSObject* thisObj, ExecState* exec, RegisterFileStack* registerFileStack, ScopeChain* scopeChain, JSValue** exception) 423 426 { 424 427 RegisterFile* registerFile = registerFileStack->current(); 425 CodeBlock* codeBlock = &functionBodyNode->code(*scopeChain); 426 registerFile->grow(registerFile->size() + CallFrameHeaderSize + codeBlock->numParameters + codeBlock->numVars + codeBlock->numTemporaries); 427 // put return info in place 428 // use 0 codeBlock to indicate termination 429 // put args in place 430 431 return privateExecute(Normal, exec, registerFile, scopeChain, codeBlock, exception); 432 } 433 434 JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFile* registerFile, ScopeChain* scopeChain, CodeBlock* codeBlock, JSValue** exception) 428 429 int argv = CallFrameHeaderSize; 430 int argc = args.size() + 1; // implicit "this" parameter 431 432 size_t oldSize = registerFile->size(); 433 registerFile->grow(oldSize + CallFrameHeaderSize + argc); 434 435 Register** registerBase = registerFile->basePointer(); 436 int registerOffset = oldSize; 437 Register* callFrame = (*registerBase) + registerOffset; 438 439 // put return info in place, using 0 codeBlock to indicate built-in caller 440 callFrame[CallerCodeBlock].u.codeBlock = 0; 441 442 // put args in place, including "this" 443 Register* dst = callFrame + CallFrameHeaderSize; 444 (*dst).u.jsValue = thisObj; 445 446 List::const_iterator end = args.end(); 447 for (List::const_iterator it = args.begin(); it != end; ++it) 448 (*++dst).u.jsValue = *it; 449 450 CodeBlock* newCodeBlock = &functionBodyNode->code(*scopeChain); 451 Register* r = slideRegisterWindowForCall(newCodeBlock, registerFile, registerBase, registerOffset, argv, argc); 452 scopeChain = scopeChainForCall(newCodeBlock, scopeChain, functionBodyNode, callFrame, registerBase, r); 453 return privateExecute(Normal, exec, registerFile, r, scopeChain, newCodeBlock, exception); 454 } 455 456 JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFile* registerFile, Register* r, ScopeChain* scopeChain, CodeBlock* codeBlock, JSValue** exception) 435 457 { 436 458 // One-time initialization of our address tables. We have to put this code … … 454 476 455 477 Register** registerBase = registerFile->basePointer(); 456 Register* r = (*registerBase);457 478 Instruction* vPC = codeBlock->instructions.begin(); 458 479 Instruction* exceptionTarget = 0; … … 950 971 951 972 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, r0, argv, 0); 952 953 // WARNING: If code generation wants to optimize resolves to parent scopes,954 // it needs to be aware that, for functions that require activations,955 // the scope chain is off by one, since the activation hasn't been pushed yet.956 973 CodeBlock* newCodeBlock = &callData.js.functionBody->code(*scopeChain); 957 974 958 r = slideRegisterWindowForCall(newCodeBlock, registerFile, registerBase, registerOffset, argv, argc , r);975 r = slideRegisterWindowForCall(newCodeBlock, registerFile, registerBase, registerOffset, argv, argc); 959 976 scopeChain = scopeChainForCall(newCodeBlock, callData.js.scopeChain, callData.js.functionBody, callFrame, registerBase, r); 960 977 k = newCodeBlock->jsValues.data(); … … 976 993 List args(&r[argv + 1].u.jsValue, argc - 1); 977 994 978 r[r0].u.jsValue = static_cast<JSObject*>(v)->callAsFunction(exec, thisObj, args);995 JSValue* returnValue = static_cast<JSObject*>(v)->callAsFunction(exec, thisObj, args); 979 996 980 997 r = (*registerBase) + registerOffset; 981 998 r[r0].u.jsValue = returnValue; 999 982 1000 ++vPC; 983 1001 NEXT_OPCODE; … … 1054 1072 1055 1073 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, r0, argv, 1); 1056 1057 // WARNING: If code generation wants to optimize resolves to parent scopes,1058 // it needs to be aware that, for functions that require activations,1059 // the scope chain is off by one, since the activation hasn't been pushed yet.1060 1074 CodeBlock* newCodeBlock = &callData.js.functionBody->code(*scopeChain); 1061 1075 1062 r = slideRegisterWindowForCall(newCodeBlock, registerFile, registerBase, registerOffset, argv, argc , r);1076 r = slideRegisterWindowForCall(newCodeBlock, registerFile, registerBase, registerOffset, argv, argc); 1063 1077 scopeChain = scopeChainForCall(newCodeBlock, callData.js.scopeChain, callData.js.functionBody, callFrame, registerBase, r); 1064 1078 k = newCodeBlock->jsValues.data(); -
branches/squirrelfish/JavaScriptCore/VM/Machine.h
r31773 r31783 76 76 77 77 JSValue* execute(ProgramNode*, ExecState*, RegisterFileStack*, ScopeChain*, JSValue** exception); 78 JSValue* execute(FunctionBodyNode*, ExecState*, RegisterFileStack*, ScopeChain*, JSValue** exception);78 JSValue* execute(FunctionBodyNode*, const List& args, JSObject* thisObj, ExecState*, RegisterFileStack*, ScopeChain*, JSValue** exception); 79 79 80 80 private: … … 84 84 NEVER_INLINE Instruction* throwException(CodeBlock*&, JSValue**&, ScopeChain*&, Register**, Register*&, const Instruction*); 85 85 86 JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, ScopeChain* = 0, CodeBlock* = 0, JSValue** exception = 0);86 JSValue* privateExecute(ExecutionFlag, ExecState* = 0, RegisterFile* = 0, Register* = 0, ScopeChain* = 0, CodeBlock* = 0, JSValue** exception = 0); 87 87 88 88 void dumpCallFrame(const CodeBlock*, const ScopeChain*, RegisterFile*, const Register*); -
branches/squirrelfish/JavaScriptCore/kjs/function.cpp
r31576 r31783 29 29 #include "Activation.h" 30 30 #include "ExecState.h" 31 #include "ExecStateInlines.h" 31 32 #include "JSGlobalObject.h" 33 #include "Machine.h" 32 34 #include "Parser.h" 33 35 #include "PropertyNameArray.h" … … 40 42 #include "operations.h" 41 43 #include "scope_chain_mark.h" 42 #include "ExecStateInlines.h"43 44 #include <errno.h> 44 45 #include <stdio.h> … … 73 74 } 74 75 75 JSValue* FunctionImp::callAsFunction(ExecState*, JSObject*, const List&) 76 { 77 ASSERT_NOT_REACHED(); 78 return 0; 76 JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) 77 { 78 JSValue* exception; 79 JSValue* result = machine().execute(body.get(), args, thisObj, exec, &exec->dynamicGlobalObject()->registerFileStack(), &_scope, &exception); 80 if (!result) 81 exec->setException(exception); 82 return result; 79 83 } 80 84 -
branches/squirrelfish/JavaScriptCore/kjs/list.cpp
r29067 r31783 28 28 void List::getSlice(int startIndex, List& result) const 29 29 { 30 ASSERT(!result.m_isReadOnly); 31 30 32 const_iterator start = min(begin() + startIndex, end()); 31 33 result.m_vector.appendRange(start, end()); 34 result.m_size = result.m_vector.size(); 32 35 } 33 36 -
branches/squirrelfish/JavaScriptCore/kjs/list.h
r31538 r31783 86 86 { 87 87 m_vector.clear(); 88 m_buffer = 0;89 88 m_size = 0; 90 89 }