diff options
Diffstat (limited to 'Source/JavaScriptCore/bytecompiler')
-rw-r--r-- | Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp | 66 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp | 15 |
3 files changed, 50 insertions, 35 deletions
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index e7a80fe2c..13a2defff 100644 --- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -304,8 +304,6 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, JSScope* scope, S // FIXME: Move code that modifies the global object to Interpreter::execute. - codeBlock->m_numCapturedVars = codeBlock->m_numVars; - if (compilationKind == OptimizingCompilation) return; @@ -392,6 +390,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc m_codeBlock->setActivationRegister(m_activationRegister->index()); } + symbolTable->setCaptureStart(m_codeBlock->m_numVars); + if (functionBody->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks) { // May reify arguments object. RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code. RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'. @@ -423,32 +423,33 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc } } - bool mayReifyArgumentsObject = codeBlock->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks; + bool shouldCaptureAllTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval(); + bool capturesAnyArgumentByName = false; - if (functionBody->hasCapturedVariables()) { + Vector<RegisterID*> capturedArguments; + if (functionBody->hasCapturedVariables() || shouldCaptureAllTheThings) { FunctionParameters& parameters = *functionBody->parameters(); + capturedArguments.resize(parameters.size()); for (size_t i = 0; i < parameters.size(); ++i) { - if (!functionBody->captures(parameters[i])) + capturedArguments[i] = 0; + if (!functionBody->captures(parameters[i]) && !shouldCaptureAllTheThings) continue; capturesAnyArgumentByName = true; - break; + capturedArguments[i] = addVar(); } } - if (mayReifyArgumentsObject || capturesAnyArgumentByName) { - symbolTable->setCaptureMode(SharedSymbolTable::AllOfTheThings); - symbolTable->setCaptureStart(-CallFrame::offsetFor(symbolTable->parameterCountIncludingThis())); - } else { - symbolTable->setCaptureMode(SharedSymbolTable::SomeOfTheThings); - symbolTable->setCaptureStart(m_codeBlock->m_numVars); - } - - if (mayReifyArgumentsObject && capturesAnyArgumentByName) { + if (capturesAnyArgumentByName && !codeBlock->isStrictMode()) { size_t parameterCount = symbolTable->parameterCount(); OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]); for (size_t i = 0; i < parameterCount; ++i) { + if (!capturedArguments[i]) { + ASSERT(slowArguments[i].status == SlowArgument::Normal); + slowArguments[i].index = CallFrame::argumentOffset(i); + continue; + } slowArguments[i].status = SlowArgument::Captured; - slowArguments[i].indexIfCaptured = CallFrame::argumentOffset(i); + slowArguments[i].index = capturedArguments[i]->index(); } symbolTable->setSlowArguments(slowArguments.release()); } @@ -491,7 +492,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc instructions().append(m_activationRegister->index()); } - codeBlock->m_numCapturedVars = codeBlock->m_numVars; + symbolTable->setCaptureEnd(codeBlock->m_numVars); m_firstLazyFunction = codeBlock->m_numVars; for (size_t i = 0; i < functionStack.size(); ++i) { @@ -518,10 +519,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc addVar(ident, varStack[i].second & DeclarationStacks::IsConstant); } - if (m_shouldEmitDebugHooks || codeBlock->usesEval()) - codeBlock->m_numCapturedVars = codeBlock->m_numVars; - - symbolTable->setCaptureEnd(codeBlock->m_numCapturedVars); + if (shouldCaptureAllTheThings) + symbolTable->setCaptureEnd(codeBlock->m_numVars); FunctionParameters& parameters = *functionBody->parameters(); m_parameters.grow(parameters.size() + 1); // reserve space for "this" @@ -531,9 +530,16 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc m_thisRegister.setIndex(nextParameterIndex--); m_codeBlock->addParameter(); - for (size_t i = 0; i < parameters.size(); ++i) - addParameter(parameters[i], nextParameterIndex--); - + for (size_t i = 0; i < parameters.size(); ++i, --nextParameterIndex) { + int index = nextParameterIndex; + if (capturedArguments.size() && capturedArguments[i]) { + ASSERT((functionBody->hasCapturedVariables() && functionBody->captures(parameters[i])) || shouldCaptureAllTheThings); + index = capturedArguments[i]->index(); + RegisterID original(nextParameterIndex); + emitMove(capturedArguments[i], &original); + } + addParameter(parameters[i], index); + } preserveLastVar(); // We declare the callee's name last because it should lose to a var, function, and/or parameter declaration. @@ -603,7 +609,6 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, JSScope* scope, SharedS for (size_t i = 0; i < numVariables; ++i) variables.append(*varStack[i].first); codeBlock->adoptVariables(variables); - codeBlock->m_numCapturedVars = codeBlock->m_numVars; preserveLastVar(); } @@ -1457,18 +1462,21 @@ ResolveResult BytecodeGenerator::resolveConstDecl(const Identifier& property) return ResolveResult::dynamicResolve(scopeDepth()); } -void BytecodeGenerator::emitCheckHasInstance(RegisterID* base) -{ +void BytecodeGenerator::emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target) +{ + size_t begin = instructions().size(); emitOpcode(op_check_has_instance); + instructions().append(dst->index()); + instructions().append(value->index()); instructions().append(base->index()); + instructions().append(target->bind(begin, instructions().size())); } -RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype) +RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype) { emitOpcode(op_instanceof); instructions().append(dst->index()); instructions().append(value->index()); - instructions().append(base->index()); instructions().append(basePrototype->index()); return dst; } diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 398719749..1bf1d8f26 100644 --- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -455,8 +455,8 @@ namespace JSC { RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst); RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst); - void emitCheckHasInstance(RegisterID* base); - RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype); + void emitCheckHasInstance(RegisterID* dst, RegisterID* value, RegisterID* base, Label* target); + RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* basePrototype); RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); } RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); } diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp index e4d35471f..823dadf14 100644 --- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -320,7 +320,9 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - if (m_base->isResolveNode() && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier())) { + if (m_base->isResolveNode() + && generator.willResolveToArguments(static_cast<ResolveNode*>(m_base)->identifier()) + && !generator.symbolTable().slowArguments()) { RegisterID* property = generator.emitNode(m_subscript); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property); @@ -1086,15 +1088,20 @@ RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterI { RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); RefPtr<RegisterID> src2 = generator.emitNode(m_expr2); + RefPtr<RegisterID> prototype = generator.newTemporary(); + RefPtr<RegisterID> dstReg = generator.finalDestination(dst, src1.get()); + RefPtr<Label> target = generator.newLabel(); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - generator.emitCheckHasInstance(src2.get()); + generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get()); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype); + generator.emitGetById(prototype.get(), src2.get(), generator.globalData()->propertyNames->prototype); generator.emitExpressionInfo(divot(), startOffset(), endOffset()); - return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype); + RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), prototype.get()); + generator.emitLabel(target.get()); + return result; } // ------------------------------ LogicalOpNode ---------------------------- |