summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecompiler
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecompiler')
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp66
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h4
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp15
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 ----------------------------