Changeset 34372 in webkit for trunk/JavaScriptCore/VM/CodeGenerator.cpp
- Timestamp:
- Jun 4, 2008, 10:36:55 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/CodeGenerator.cpp
r34319 r34372 40 40 /* 41 41 The layout of a register frame looks like this: 42 43 For 44 42 43 For 44 45 45 function f(x, y) { 46 46 var v1; … … 49 49 return (x) * (y); 50 50 } 51 51 52 52 assuming (x) and (y) generated temporaries t1 and t2, you would have 53 53 … … 58 58 ------------------------------------ 59 59 | params->|<-locals | temps-> 60 60 61 61 Because temporary registers are allocated in a stack-like fashion, we 62 62 can reclaim them with a simple popping algorithm. The same goes for labels. 63 63 (We never reclaim parameter or local registers, because parameters and 64 64 locals are DontDelete.) 65 65 66 66 The register layout before a function call looks like this: 67 67 68 68 For 69 69 70 70 function f(x, y) 71 71 { 72 72 } 73 73 74 74 f(1); 75 75 76 76 > <------------------------------ 77 77 < > reserved: call frame | 1 | <-- value held … … 79 79 < > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index 80 80 > <------------------------------ 81 | params->|<-locals | temps-> 82 81 | params->|<-locals | temps-> 82 83 83 The call instruction fills in the "call frame" registers. It also pads 84 84 missing arguments at the end of the call: 85 85 86 86 > <----------------------------------- 87 87 < > reserved: call frame | 1 | ? | <-- value held ("?" stands for "undefined") … … 90 90 > <----------------------------------- 91 91 | params->|<-locals | temps-> 92 92 93 93 After filling in missing arguments, the call instruction sets up the new 94 94 stack frame to overlap the end of the old stack frame: … … 100 100 |----------------------------------> < 101 101 | | params->|<-locals | temps-> 102 102 103 103 That way, arguments are "copied" into the callee's stack frame for free. 104 104 105 105 If the caller supplies too many arguments, this trick doesn't work. The 106 106 extra arguments protrude into space reserved for locals and temporaries. … … 111 111 This copying strategy ensures that all named values will be at the indices 112 112 expected by the callee. 113 114 113 */ 115 114 … … 133 132 if (m_shouldEmitDebugHooks) 134 133 m_codeBlock->needsFullScopeChain = true; 135 134 136 135 m_scopeNode->emitCode(*this); 137 136 … … 196 195 197 196 JSGlobalObject* globalObject = scopeChain.globalObject(); 198 197 199 198 ExecState* exec = globalObject->globalExec(); 200 199 … … 207 206 emitNewFunction(addVar(funcDecl->m_ident, false), funcDecl); 208 207 } 209 208 210 209 for (size_t i = 0; i < varStack.size(); ++i) { 211 210 if (!globalObject->hasProperty(exec, varStack[i].first)) … … 245 244 FuncDeclNode* funcDecl = functionStack[i].get(); 246 245 const Identifier& ident = funcDecl->m_ident; 247 246 248 247 m_functions.add(ident.ustring().rep()); 249 248 emitNewFunction(addVar(ident, false), funcDecl); … … 255 254 if (ident == m_propertyNames->arguments) 256 255 continue; 257 256 258 257 RegisterID* r0; 259 258 if (addVar(ident, r0, varStack[i].second & DeclarationStacks::IsConstant)) … … 306 305 result = &(m_locals[localsIndex(m_nextParameter)]); 307 306 } 308 307 309 308 // To maintain the calling convention, we have to allocate unique space for 310 309 // each parameter, even if the parameter doesn't make it into the symbol table. … … 336 335 if (m_codeType == EvalCode) 337 336 return 0; 338 337 339 338 SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); 340 339 ASSERT(!entry.isEmpty()); 341 340 342 341 return &m_locals[localsIndex(entry.getIndex())]; 343 342 } … … 430 429 if (result.second) // new entry 431 430 m_codeBlock->identifiers.append(rep); 432 431 433 432 return result.first->second; 434 433 } … … 439 438 if (result.second) // new entry 440 439 m_codeBlock->jsValues.append(v); 441 440 442 441 return result.first->second; 443 442 } … … 752 751 for (; iter != end; ++iter, ++depth) { 753 752 JSObject* currentScope = *iter; 754 if (!currentScope->isVariableObject()) 753 if (!currentScope->isVariableObject()) 755 754 break; 756 755 JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope); … … 798 797 return emitGetScopedVar(dst, depth, index); 799 798 } 800 799 801 800 RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index) 802 801 { … … 807 806 return dst; 808 807 } 809 808 810 809 RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value) 811 810 { … … 824 823 return dst; 825 824 } 826 825 827 826 RegisterID* CodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property) 828 827 { … … 965 964 RefPtr<RegisterID> refFunc = func; 966 965 RefPtr<RegisterID> refBase = base; 967 966 968 967 // Reserve space for call frame. 969 968 Vector<RefPtr<RegisterID>, Machine::CallFrameHeaderSize> callFrame; … … 1107 1106 return 0; 1108 1107 } 1109 1108 1110 1109 for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) { 1111 1110 JumpContext* scope = &m_jumpContextStack[i]; … … 1129 1128 return 0; 1130 1129 } 1131 1130 1132 1131 for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) { 1133 1132 JumpContext* scope = &m_jumpContextStack[i]; … … 1152 1151 1153 1152 if (nNormalScopes) { 1154 // We need to remove a number of dynamic scopes to get to the next 1153 // We need to remove a number of dynamic scopes to get to the next 1155 1154 // finally block 1156 1155 instructions().append(machine().getOpcode(op_jmp_scopes)); 1157 1156 instructions().append(nNormalScopes); 1158 1157 1159 1158 // If topScope == bottomScope then there isn't actually a finally block 1160 1159 // left to emit, so make the jmp_scopes jump directly to the target label … … 1164 1163 } 1165 1164 1166 // Otherwise we just use jmp_scopes to pop a group of scopes and go 1165 // Otherwise we just use jmp_scopes to pop a group of scopes and go 1167 1166 // to the next instruction 1168 1167 RefPtr<LabelID> nextInsn = newLabel(); … … 1226 1225 return targetRegister; 1227 1226 } 1228 1227 1229 1228 void CodeGenerator::emitThrow(RegisterID* exception) 1230 1229 {
Note:
See TracChangeset
for help on using the changeset viewer.