summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/bytecompiler
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/bytecompiler')
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.cpp27
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h20
-rw-r--r--JavaScriptCore/bytecompiler/NodesCodegen.cpp64
3 files changed, 50 insertions, 61 deletions
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 7538314..1fa5aa4 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -443,7 +443,6 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
emitOpcode(op_get_callee);
instructions().append(func->index());
// Load prototype.
- emitGetByIdExceptionInfo(op_create_this);
emitGetById(funcProto.get(), func.get(), globalData()->propertyNames->prototype);
emitOpcode(op_create_this);
@@ -1158,6 +1157,12 @@ bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& inde
return true;
}
+void BytecodeGenerator::emitCheckHasInstance(RegisterID* base)
+{
+ emitOpcode(op_check_has_instance);
+ instructions().append(base->index());
+}
+
RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
{
emitOpcode(op_instanceof);
@@ -2050,13 +2055,16 @@ RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* star
return targetRegister;
}
-RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, bool isReferenceError, JSValue message)
+void BytecodeGenerator::emitThrowReferenceError(const UString& message)
{
- emitOpcode(op_new_error);
- instructions().append(dst->index());
- instructions().append(isReferenceError);
- instructions().append(addConstantValue(message)->index());
- return dst;
+ emitOpcode(op_throw_reference_error);
+ instructions().append(addConstantValue(jsString(globalData(), message))->index());
+}
+
+void BytecodeGenerator::emitThrowSyntaxError(const UString& message)
+{
+ emitOpcode(op_throw_syntax_error);
+ instructions().append(addConstantValue(jsString(globalData(), message))->index());
}
PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
@@ -2211,9 +2219,8 @@ RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
// that from an arbitrary node. However, calling emitExpressionInfo without any useful data
// is still good enough to get us an accurate line number.
emitExpressionInfo(0, 0, 0);
- RegisterID* exception = emitNewError(newTemporary(), false, jsString(globalData(), "Expression too deep"));
- emitThrow(exception);
- return exception;
+ emitThrowSyntaxError("Expression too deep");
+ return newTemporary();
}
void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index b189565..499d232 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -230,8 +230,10 @@ namespace JSC {
LineInfo info = { instructions().size(), n->lineNo() };
m_codeBlock->addLineInfo(info);
}
- if (m_emitNodeDepth >= s_maxEmitNodeDepth)
+ if (m_emitNodeDepth >= s_maxEmitNodeDepth) {
emitThrowExpressionTooDeepException();
+ return;
+ }
++m_emitNodeDepth;
n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
--m_emitNodeDepth;
@@ -266,17 +268,6 @@ namespace JSC {
m_codeBlock->addExpressionInfo(info);
}
- void emitGetByIdExceptionInfo(OpcodeID opcodeID)
- {
- // Only op_construct and op_instanceof need exception info for
- // a preceding op_get_by_id.
- ASSERT(opcodeID == op_create_this || opcodeID == op_instanceof);
- GetByIdExceptionInfo info;
- info.bytecodeOffset = instructions().size();
- info.isOpCreateThis = (opcodeID == op_create_this);
- m_codeBlock->addGetByIdExceptionInfo(info);
- }
-
ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
{
return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain() || rightHasAssignments) && !rightIsPure;
@@ -320,6 +311,7 @@ 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);
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()); }
@@ -380,7 +372,9 @@ namespace JSC {
emitUnaryNoDstOp(op_throw, exc);
}
- RegisterID* emitNewError(RegisterID* dst, bool isReferenceError, JSValue message);
+ void emitThrowReferenceError(const UString& message);
+ void emitThrowSyntaxError(const UString& message);
+
void emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value);
RegisterID* emitPushScope(RegisterID* scope);
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 47129d5..a850c96 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -76,34 +76,18 @@ namespace JSC {
// ------------------------------ ThrowableExpressionData --------------------------------
-static void substitute(UString& string, const UString& substring)
-{
- size_t position = string.find("%s");
- ASSERT(position != notFound);
- string = makeUString(string.substringSharingImpl(0, position), substring, string.substringSharingImpl(position + 2));
-}
-
-RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* message)
+RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const UString& message)
{
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), isReferenceError, jsString(generator.globalData(), message));
- generator.emitThrow(exception);
- return exception;
+ generator.emitThrowReferenceError(message);
+ return generator.newTemporary();
}
-RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* messageTemplate, const UString& label)
+RegisterID* ThrowableExpressionData::emitThrowSyntaxError(BytecodeGenerator& generator, const UString& message)
{
- UString message = messageTemplate;
- substitute(message, label);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), isReferenceError, jsString(generator.globalData(), message));
- generator.emitThrow(exception);
- return exception;
-}
-
-inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* messageTemplate, const Identifier& label)
-{
- return emitThrowError(generator, isReferenceError, messageTemplate, label.ustring());
+ generator.emitThrowSyntaxError(message);
+ return generator.newTemporary();
}
// ------------------------------ NullNode -------------------------------------
@@ -148,7 +132,7 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
{
RefPtr<RegExp> regExp = generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), m_flags.ustring());
if (!regExp->isValid())
- return emitThrowError(generator, false, "Invalid regular expression: %s", regExp->errorMessage());
+ return emitThrowSyntaxError(generator, makeUString("Invalid regular expression: ", regExp->errorMessage()));
if (dst == generator.ignoredResult())
return 0;
return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
@@ -661,7 +645,7 @@ RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterI
RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- return emitThrowError(generator, true, m_operator == OpPlusPlus
+ return emitThrowReferenceError(generator, m_operator == OpPlusPlus
? "Postfix ++ operator applied to value that is not a reference."
: "Postfix -- operator applied to value that is not a reference.");
}
@@ -826,7 +810,7 @@ RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- return emitThrowError(generator, true, m_operator == OpPlusPlus
+ return emitThrowReferenceError(generator, m_operator == OpPlusPlus
? "Prefix ++ operator applied to value that is not a reference."
: "Prefix -- operator applied to value that is not a reference.");
}
@@ -1032,7 +1016,9 @@ RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterI
RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitGetByIdExceptionInfo(op_instanceof);
+ generator.emitCheckHasInstance(src2.get());
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
@@ -1269,7 +1255,7 @@ RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, Regist
RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- return emitThrowError(generator, true, "Left side of assignment is not a reference.");
+ return emitThrowReferenceError(generator, "Left side of assignment is not a reference.");
}
// ------------------------------ AssignBracketNode -----------------------------------
@@ -1579,7 +1565,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
if (!m_lexpr->isLocation())
- return emitThrowError(generator, true, "Left side of for-in statement is not a reference.");
+ return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
@@ -1656,10 +1642,11 @@ RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
LabelScope* scope = generator.continueTarget(m_ident);
- if (!scope)
- return m_ident.isEmpty()
- ? emitThrowError(generator, false, "Invalid continue statement.")
- : emitThrowError(generator, false, "Undefined label: '%s'.", m_ident);
+ if (!scope) {
+ if (m_ident.isEmpty())
+ return emitThrowSyntaxError(generator, "Invalid continue statement.");
+ return emitThrowSyntaxError(generator, makeUString("Undefined label: '", m_ident.ustring(), "'."));
+ }
generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
return dst;
@@ -1674,10 +1661,11 @@ RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
LabelScope* scope = generator.breakTarget(m_ident);
- if (!scope)
- return m_ident.isEmpty()
- ? emitThrowError(generator, false, "Invalid break statement.")
- : emitThrowError(generator, false, "Undefined label: '%s'.", m_ident);
+ if (!scope) {
+ if (m_ident.isEmpty())
+ return emitThrowSyntaxError(generator, "Invalid break statement.");
+ return emitThrowSyntaxError(generator, makeUString("Undefined label: '", m_ident.ustring(), "'."));
+ }
generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
return dst;
@@ -1689,7 +1677,7 @@ RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
{
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (generator.codeType() != FunctionCode)
- return emitThrowError(generator, false, "Invalid return statement.");
+ return emitThrowSyntaxError(generator, "Invalid return statement.");
if (dst == generator.ignoredResult())
dst = 0;
@@ -1895,7 +1883,7 @@ RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (generator.breakTarget(m_name))
- return emitThrowError(generator, false, "Duplicate label: %s.", m_name);
+ return emitThrowSyntaxError(generator, makeUString("Duplicate label: ", m_name.ustring(), "."));
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
RegisterID* r0 = generator.emitNode(dst, m_statement);