diff options
Diffstat (limited to 'JavaScriptCore/bytecompiler')
-rw-r--r-- | JavaScriptCore/bytecompiler/BytecodeGenerator.cpp | 27 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/BytecodeGenerator.h | 20 | ||||
-rw-r--r-- | JavaScriptCore/bytecompiler/NodesCodegen.cpp | 64 |
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); |