summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/bytecompiler/NodesCodegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/bytecompiler/NodesCodegen.cpp')
-rw-r--r--JavaScriptCore/bytecompiler/NodesCodegen.cpp193
1 files changed, 118 insertions, 75 deletions
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index aaf2dd1..765230e 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -81,27 +81,27 @@ static void substitute(UString& string, const UString& substring)
string = makeString(string.substr(0, position), substring, string.substr(position + 2));
}
-RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
+RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* message)
{
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
+ RegisterID* exception = generator.emitNewError(generator.newTemporary(), isReferenceError, jsString(generator.globalData(), message));
generator.emitThrow(exception);
return exception;
}
-RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label)
+RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* messageTemplate, const UString& label)
{
UString message = messageTemplate;
substitute(message, label);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
+ RegisterID* exception = generator.emitNewError(generator.newTemporary(), isReferenceError, jsString(generator.globalData(), message));
generator.emitThrow(exception);
return exception;
}
-inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label)
+inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* messageTemplate, const Identifier& label)
{
- return emitThrowError(generator, type, messageTemplate, label.ustring());
+ return emitThrowError(generator, isReferenceError, messageTemplate, label.ustring());
}
// ------------------------------ NullNode -------------------------------------
@@ -146,10 +146,10 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
{
RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring());
if (!regExp->isValid())
- return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
+ return emitThrowError(generator, false, "Invalid regular expression: %s", regExp->errorMessage());
if (dst == generator.ignoredResult())
return 0;
- return generator.emitLoad(generator.finalDestination(dst), regExp.get());
+ return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
}
// ------------------------------ ThisNode -------------------------------------
@@ -316,7 +316,23 @@ RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, Registe
RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> func = generator.emitNode(m_expr);
- return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), callArguments, divot(), startOffset(), endOffset());
+}
+
+CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode)
+ : m_argumentsNode(argumentsNode)
+{
+ if (generator.shouldEmitProfileHooks())
+ m_profileHookRegister = generator.newTemporary();
+ m_argv.append(generator.newTemporary());
+ if (argumentsNode) {
+ for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) {
+ m_argv.append(generator.newTemporary());
+ // op_call requires the arguments to be a sequential range of registers
+ ASSERT(m_argv[m_argv.size() - 1]->index() == m_argv[m_argv.size() - 2]->index() + 1);
+ }
+ }
}
// ------------------------------ EvalFunctionCallNode ----------------------------------
@@ -324,10 +340,10 @@ RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> func = generator.tempDestination(dst);
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ CallArguments callArguments(generator, m_args);
generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
- generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
- return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ generator.emitResolveWithBase(callArguments.thisRegister(), func.get(), generator.propertyNames().eval);
+ return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
}
// ------------------------------ FunctionCallValueNode ----------------------------------
@@ -335,8 +351,9 @@ RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, Reg
RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> func = generator.emitNode(m_expr);
- RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
- return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ generator.emitLoad(callArguments.thisRegister(), jsNull());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
}
// ------------------------------ FunctionCallResolveNode ----------------------------------
@@ -344,25 +361,28 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re
RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
- RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
- return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ generator.emitLoad(callArguments.thisRegister(), jsNull());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), local.get(), callArguments, divot(), startOffset(), endOffset());
}
int index = 0;
size_t depth = 0;
JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
+ bool requiresDynamicChecks = false;
+ if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
- RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
- return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ generator.emitLoad(callArguments.thisRegister(), jsNull());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
}
RefPtr<RegisterID> func = generator.newTemporary();
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ CallArguments callArguments(generator, m_args);
int identifierStart = divot() - startOffset();
generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
- generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident);
- return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ generator.emitResolveWithBase(callArguments.thisRegister(), func.get(), m_ident);
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
}
// ------------------------------ FunctionCallBracketNode ----------------------------------
@@ -373,8 +393,9 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator,
RegisterID* property = generator.emitNode(m_subscript);
generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
- return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ generator.emitMove(callArguments.thisRegister(), base.get());
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), callArguments, divot(), startOffset(), endOffset());
}
// ------------------------------ FunctionCallDotNode ----------------------------------
@@ -382,12 +403,12 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator,
RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> function = generator.tempDestination(dst);
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- generator.emitNode(thisRegister.get(), m_base);
+ CallArguments callArguments(generator, m_args);
+ generator.emitNode(callArguments.thisRegister(), m_base);
generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
generator.emitMethodCheck();
- generator.emitGetById(function.get(), thisRegister.get(), m_ident);
- return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
+ return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), callArguments, divot(), startOffset(), endOffset());
}
RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
@@ -397,31 +418,39 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<RegisterID> base = generator.emitNode(m_base);
generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
- RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
+ RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
{
- RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- ArgumentListNode* oldList = m_args->m_listNode;
if (m_args->m_listNode && m_args->m_listNode->m_expr) {
- generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+ ArgumentListNode* oldList = m_args->m_listNode;
m_args->m_listNode = m_args->m_listNode->m_next;
- } else
- generator.emitLoad(thisRegister.get(), jsNull());
- generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- generator.emitJump(end.get());
- m_args->m_listNode = oldList;
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ CallArguments callArguments(generator, m_args);
+ generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
+ generator.emitJump(end.get());
+
+ m_args->m_listNode = oldList;
+
+ } else {
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ CallArguments callArguments(generator, m_args);
+ generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
+ generator.emitJump(end.get());
+ }
}
generator.emitLabel(realCall.get());
{
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
- generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ generator.emitMove(callArguments.thisRegister(), base.get());
+ generator.emitCall(finalDestinationOrIgnored.get(), function.get(), callArguments, divot(), startOffset(), endOffset());
}
generator.emitLabel(end.get());
- return finalDestination.get();
+ return finalDestinationOrIgnored.get();
}
-
+
static bool areTrivialApplyArguments(ArgumentsNode* args)
{
return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
@@ -440,25 +469,34 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
RefPtr<RegisterID> base = generator.emitNode(m_base);
generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
- RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
+ RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
{
if (mayBeCall) {
- RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- ArgumentListNode* oldList = m_args->m_listNode;
if (m_args->m_listNode && m_args->m_listNode->m_expr) {
- generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
- m_args->m_listNode = m_args->m_listNode->m_next;
- if (m_args->m_listNode) {
- ASSERT(m_args->m_listNode->m_expr->isSimpleArray());
- ASSERT(!m_args->m_listNode->m_next);
- m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr)->toArgumentList(generator.globalData());
+ ArgumentListNode* oldList = m_args->m_listNode;
+ if (m_args->m_listNode->m_next) {
+ ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
+ ASSERT(!m_args->m_listNode->m_next->m_next);
+ m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.globalData());
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ CallArguments callArguments(generator, m_args);
+ generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
+ } else {
+ m_args->m_listNode = m_args->m_listNode->m_next;
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ CallArguments callArguments(generator, m_args);
+ generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
}
- } else
- generator.emitLoad(thisRegister.get(), jsNull());
- generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- m_args->m_listNode = oldList;
+ m_args->m_listNode = oldList;
+ } else {
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ CallArguments callArguments(generator, m_args);
+ generator.emitLoad(callArguments.thisRegister(), jsNull());
+ generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), callArguments, divot(), startOffset(), endOffset());
+ }
} else {
ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
@@ -480,17 +518,18 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
generator.emitNode(args->m_expr);
generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get());
- generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
+ generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
}
generator.emitJump(end.get());
}
generator.emitLabel(realCall.get());
{
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
- generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ CallArguments callArguments(generator, m_args);
+ generator.emitMove(callArguments.thisRegister(), base.get());
+ generator.emitCall(finalDestinationOrIgnored.get(), function.get(), callArguments, divot(), startOffset(), endOffset());
}
generator.emitLabel(end.get());
- return finalDestination.get();
+ return finalDestinationOrIgnored.get();
}
// ------------------------------ PostfixResolveNode ----------------------------------
@@ -524,7 +563,8 @@ RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, Regis
int index = 0;
size_t depth = 0;
JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+ bool requiresDynamicChecks = false;
+ if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
RegisterID* oldValue;
if (dst == generator.ignoredResult()) {
@@ -602,7 +642,7 @@ RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterI
RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus
+ return emitThrowError(generator, true, m_operator == OpPlusPlus
? "Postfix ++ operator applied to value that is not a reference."
: "Postfix -- operator applied to value that is not a reference.");
}
@@ -710,7 +750,8 @@ RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
int index = 0;
size_t depth = 0;
JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
+ bool requiresDynamicChecks = false;
+ if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
emitPreIncOrDec(generator, propDst.get(), m_operator);
generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
@@ -766,7 +807,7 @@ RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus
+ return emitThrowError(generator, true, m_operator == OpPlusPlus
? "Prefix ++ operator applied to value that is not a reference."
: "Prefix -- operator applied to value that is not a reference.");
}
@@ -1132,7 +1173,8 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re
int index = 0;
size_t depth = 0;
JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+ bool requiresDynamicChecks = false;
+ if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
generator.emitPutScopedVar(depth, index, result, globalObject);
@@ -1161,7 +1203,8 @@ RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
int index = 0;
size_t depth = 0;
JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+ bool requiresDynamicChecks = false;
+ if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
if (dst == generator.ignoredResult())
dst = 0;
RegisterID* value = generator.emitNode(dst, m_right);
@@ -1207,7 +1250,7 @@ RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, Regist
RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
+ return emitThrowError(generator, true, "Left side of assignment is not a reference.");
}
// ------------------------------ AssignBracketNode -----------------------------------
@@ -1512,7 +1555,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
if (!m_lexpr->isLocation())
- return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
+ return emitThrowError(generator, true, "Left side of for-in statement is not a reference.");
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
@@ -1591,8 +1634,8 @@ RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
if (!scope)
return m_ident.isEmpty()
- ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
- : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
+ ? emitThrowError(generator, false, "Invalid continue statement.")
+ : emitThrowError(generator, false, "Undefined label: '%s'.", m_ident);
generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
return dst;
@@ -1609,8 +1652,8 @@ RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
if (!scope)
return m_ident.isEmpty()
- ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
- : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
+ ? emitThrowError(generator, false, "Invalid break statement.")
+ : emitThrowError(generator, false, "Undefined label: '%s'.", m_ident);
generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
return dst;
@@ -1622,7 +1665,7 @@ RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
{
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (generator.codeType() != FunctionCode)
- return emitThrowError(generator, SyntaxError, "Invalid return statement.");
+ return emitThrowError(generator, false, "Invalid return statement.");
if (dst == generator.ignoredResult())
dst = 0;
@@ -1828,7 +1871,7 @@ RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (generator.breakTarget(m_name))
- return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
+ return emitThrowError(generator, false, "Duplicate label: %s.", m_name);
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
RegisterID* r0 = generator.emitNode(dst, m_statement);
@@ -1974,7 +2017,7 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe
return 0;
}
- RegisterID* r0 = generator.emitLoad(0, jsUndefined());
+ RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
generator.emitReturn(r0);
return 0;