X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..ba379fdc102753d6be2c4d937058fe40257329fe:/bytecompiler/BytecodeGenerator.cpp?ds=sidebyside diff --git a/bytecompiler/BytecodeGenerator.cpp b/bytecompiler/BytecodeGenerator.cpp index cd89c1e..683372e 100644 --- a/bytecompiler/BytecodeGenerator.cpp +++ b/bytecompiler/BytecodeGenerator.cpp @@ -31,6 +31,7 @@ #include "BytecodeGenerator.h" #include "BatchedTransitionOptimizer.h" +#include "PrototypeFunction.h" #include "JSFunction.h" #include "Interpreter.h" #include "UString.h" @@ -195,17 +196,10 @@ bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, R return result.second; } -void BytecodeGenerator::allocateConstants(size_t count) +void BytecodeGenerator::preserveLastVar() { - m_codeBlock->m_numConstants = count; - if (!count) - return; - - m_nextConstantIndex = m_calleeRegisters.size(); - - for (size_t i = 0; i < count; ++i) - newRegister(); - m_lastConstant = &m_calleeRegisters.last(); + if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0) + m_lastVar = &m_calleeRegisters.last(); } BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock) @@ -221,6 +215,8 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d , m_baseScopeDepth(0) , m_codeType(GlobalCode) , m_nextGlobalIndex(-1) + , m_nextConstantOffset(0) + , m_globalConstantIndex(0) , m_globalData(&scopeChain.globalObject()->globalExec()->globalData()) , m_lastOpcodeID(op_end) , m_emitNodeDepth(0) @@ -260,7 +256,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d m_nextGlobalIndex -= symbolTable->size(); for (size_t i = 0; i < functionStack.size(); ++i) { - FuncDeclNode* funcDecl = functionStack[i].get(); + FuncDeclNode* funcDecl = functionStack[i]; globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property. emitNewFunction(addGlobalVar(funcDecl->m_ident, false), funcDecl); } @@ -270,13 +266,13 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d if (!globalObject->hasProperty(exec, varStack[i].first)) newVars.append(addGlobalVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant)); - allocateConstants(programNode->neededConstants()); + preserveLastVar(); for (size_t i = 0; i < newVars.size(); ++i) emitLoad(newVars[i], jsUndefined()); } else { for (size_t i = 0; i < functionStack.size(); ++i) { - FuncDeclNode* funcDecl = functionStack[i].get(); + FuncDeclNode* funcDecl = functionStack[i]; globalObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, scopeChain.node()), DontDelete); } for (size_t i = 0; i < varStack.size(); ++i) { @@ -288,7 +284,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d globalObject->putWithAttributes(exec, varStack[i].first, jsUndefined(), attributes); } - allocateConstants(programNode->neededConstants()); + preserveLastVar(); } } @@ -303,6 +299,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug , m_dynamicScopeDepth(0) , m_baseScopeDepth(0) , m_codeType(FunctionCode) + , m_nextConstantOffset(0) + , m_globalConstantIndex(0) , m_globalData(&scopeChain.globalObject()->globalExec()->globalData()) , m_lastOpcodeID(op_end) , m_emitNodeDepth(0) @@ -329,12 +327,19 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug } else emitOpcode(op_enter); - if (usesArguments) - emitOpcode(op_create_arguments); + if (usesArguments) { + emitOpcode(op_init_arguments); + + // The debugger currently retrieves the arguments object from an activation rather than pulling + // it from a call frame. In the long-term it should stop doing that (), + // but for now we force eager creation of the arguments object when debugging. + if (m_shouldEmitDebugHooks) + emitOpcode(op_create_arguments); + } const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack(); for (size_t i = 0; i < functionStack.size(); ++i) { - FuncDeclNode* funcDecl = functionStack[i].get(); + FuncDeclNode* funcDecl = functionStack[i]; const Identifier& ident = funcDecl->m_ident; m_functions.add(ident.ustring().rep()); emitNewFunction(addVar(ident, false), funcDecl); @@ -362,7 +367,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug for (size_t i = 0; i < parameterCount; ++i) addParameter(parameters[i]); - allocateConstants(functionBody->neededConstants()); + preserveLastVar(); } BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock) @@ -377,6 +382,8 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge , m_dynamicScopeDepth(0) , m_baseScopeDepth(codeBlock->baseScopeDepth()) , m_codeType(EvalCode) + , m_nextConstantOffset(0) + , m_globalConstantIndex(0) , m_globalData(&scopeChain.globalObject()->globalExec()->globalData()) , m_lastOpcodeID(op_end) , m_emitNodeDepth(0) @@ -390,7 +397,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge codeBlock->setGlobalData(m_globalData); m_codeBlock->m_numParameters = 1; // Allocate space for "this" - allocateConstants(evalNode->neededConstants()); + preserveLastVar(); } RegisterID* BytecodeGenerator::addParameter(const Identifier& ident) @@ -424,6 +431,36 @@ RegisterID* BytecodeGenerator::registerFor(const Identifier& ident) if (entry.isNull()) return 0; + if (ident == propertyNames().arguments) + createArgumentsIfNecessary(); + + return ®isterFor(entry.getIndex()); +} + +bool BytecodeGenerator::willResolveToArguments(const Identifier& ident) +{ + if (ident != propertyNames().arguments) + return false; + + if (!shouldOptimizeLocals()) + return false; + + SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); + if (entry.isNull()) + return false; + + if (m_codeBlock->usesArguments() && m_codeType == FunctionCode) + return true; + + return false; +} + +RegisterID* BytecodeGenerator::uncheckedRegisterForArguments() +{ + ASSERT(willResolveToArguments(propertyNames().arguments)); + + SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.ustring().rep()); + ASSERT(!entry.isNull()); return ®isterFor(entry.getIndex()); } @@ -648,6 +685,21 @@ PassRefPtr