From d441d6f39bb846989d95bcf5caf387b42414718d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 13 Sep 2013 12:51:20 +0200 Subject: Import Qt5x2 branch of QtWebkit for Qt 5.2 Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen --- .../JavaScriptCore/bytecompiler/NodesCodegen.cpp | 835 ++++++++++++--------- 1 file changed, 465 insertions(+), 370 deletions(-) (limited to 'Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp') diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp index 71b6c7cac..40f703c08 100644 --- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) -* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved. +* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * Copyright (C) 2007 Eric Seidel @@ -74,49 +74,49 @@ namespace JSC { because the assignment node, "x =", passes r[x] as dst to the number node, "1". */ +void ExpressionNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode) +{ + RegisterID* result = generator.emitNode(this); + if (fallThroughMode == FallThroughMeansTrue) + generator.emitJumpIfFalse(result, falseTarget); + else + generator.emitJumpIfTrue(result, trueTarget); +} + // ------------------------------ ThrowableExpressionData -------------------------------- RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message) { - generator.emitExpressionInfo(divot(), startOffset(), endOffset()); + generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); generator.emitThrowReferenceError(message); return generator.newTemporary(); } -// ------------------------------ NullNode ------------------------------------- +// ------------------------------ ConstantNode ---------------------------------- -RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) +void ConstantNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, FallThroughMode fallThroughMode) { - if (dst == generator.ignoredResult()) - return 0; - return generator.emitLoad(dst, jsNull()); -} - -// ------------------------------ BooleanNode ---------------------------------- + TriState value = jsValue(generator).pureToBoolean(); + if (value == MixedTriState) + ExpressionNode::emitBytecodeInConditionContext(generator, trueTarget, falseTarget, fallThroughMode); + else if (value == TrueTriState && fallThroughMode == FallThroughMeansFalse) + generator.emitJump(trueTarget); + else if (value == FalseTriState && fallThroughMode == FallThroughMeansTrue) + generator.emitJump(falseTarget); -RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - if (dst == generator.ignoredResult()) - return 0; - return generator.emitLoad(dst, m_value); + // All other cases are unconditional fall-throughs, like "if (true)". } -// ------------------------------ NumberNode ----------------------------------- - -RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) +RegisterID* ConstantNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { if (dst == generator.ignoredResult()) return 0; - return generator.emitLoad(dst, m_value); + return generator.emitLoad(dst, jsValue(generator)); } -// ------------------------------ StringNode ----------------------------------- - -RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) +JSValue StringNode::jsValue(BytecodeGenerator& generator) const { - if (dst == generator.ignoredResult()) - return 0; - return generator.emitLoad(dst, m_value); + return generator.addStringConstant(m_value); } // ------------------------------ RegExpNode ----------------------------------- @@ -125,7 +125,7 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d { if (dst == generator.ignoredResult()) return 0; - return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.globalData(), m_pattern.string(), regExpFlags(m_flags.string()))); + return generator.emitNewRegExp(generator.finalDestination(dst), RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string()))); } // ------------------------------ ThisNode ------------------------------------- @@ -141,7 +141,7 @@ RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst bool ResolveNode::isPure(BytecodeGenerator& generator) const { - return generator.resolve(m_ident).isRegister(); + return generator.resolve(m_ident).isStatic(); } RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) @@ -153,7 +153,8 @@ RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* return generator.moveToDestinationIfNeeded(dst, local); } - generator.emitExpressionInfo(m_startOffset + m_ident.length(), m_ident.length(), 0); + unsigned divot = m_startOffset + m_ident.length(); + generator.emitExpressionInfo(divot, m_ident.length(), 0, m_divotLine, m_divotLineStart); return generator.emitResolve(generator.finalDestination(dst), resolveResult, m_ident); } @@ -201,7 +202,7 @@ bool ArrayNode::isSimpleArray() const return true; } -ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNumber, int columnNumber) const +ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPosition) const { ASSERT(!m_elision && !m_optional); ElementNode* ptr = m_element; @@ -209,13 +210,13 @@ ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNu return 0; JSTokenLocation location; location.line = lineNumber; - location.column = columnNumber; - ArgumentListNode* head = new (globalData) ArgumentListNode(location, ptr->value()); + location.startOffset = startPosition; + ArgumentListNode* head = new (vm) ArgumentListNode(location, ptr->value()); ArgumentListNode* tail = head; ptr = ptr->next(); for (; ptr; ptr = ptr->next()) { ASSERT(!ptr->elision()); - tail = new (globalData) ArgumentListNode(location, tail, ptr->value()); + tail = new (vm) ArgumentListNode(location, tail, ptr->value()); } return head; } @@ -324,13 +325,13 @@ RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, Regi && generator.willResolveToArguments(static_cast(m_base)->identifier()) && !generator.symbolTable().slowArguments()) { RegisterID* property = generator.emitNode(m_subscript); - generator.emitExpressionInfo(divot(), startOffset(), endOffset()); + generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property); } RefPtr base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator)); RegisterID* property = generator.emitNode(m_subscript); - generator.emitExpressionInfo(divot(), startOffset(), endOffset()); + generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property); } @@ -344,13 +345,13 @@ RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, Register ResolveNode* resolveNode = static_cast(m_base); if (!generator.willResolveToArguments(resolveNode->identifier())) goto nonArgumentsPath; - generator.emitExpressionInfo(divot(), startOffset(), endOffset()); + generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments()); } nonArgumentsPath: RegisterID* base = generator.emitNode(m_base); - generator.emitExpressionInfo(divot(), startOffset(), endOffset()); + generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); return generator.emitGetById(generator.finalDestination(dst), base, m_ident); } @@ -373,7 +374,7 @@ RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* expectedFunction = NoExpectedFunction; RefPtr func = generator.emitNode(m_expr); CallArguments callArguments(generator, m_args); - return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset()); + return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } inline CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argumentsNode) @@ -408,9 +409,9 @@ RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, Reg { RefPtr func = generator.tempDestination(dst); CallArguments callArguments(generator, m_args); - generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0); + generator.emitExpressionInfo(divot() - divotStartOffset() + 4, 4, 0, divotLine(), divotLineStart()); generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), generator.resolve(generator.propertyNames().eval), generator.propertyNames().eval); - return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset()); + return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } // ------------------------------ FunctionCallValueNode ---------------------------------- @@ -420,7 +421,7 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re RefPtr func = generator.emitNode(m_expr); CallArguments callArguments(generator, m_args); generator.emitLoad(callArguments.thisRegister(), jsUndefined()); - return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset()); + return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } // ------------------------------ FunctionCallResolveNode ---------------------------------- @@ -436,16 +437,24 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, generator.emitLoad(callArguments.thisRegister(), jsUndefined()); // This passes NoExpectedFunction because we expect that if the function is in a // local variable, then it's not one of our built-in constructors. - return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), func.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset()); + return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), func.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); + } + + if (resolveResult.isStatic()) { + RefPtr func = generator.newTemporary(); + CallArguments callArguments(generator, m_args); + generator.emitGetStaticVar(func.get(), resolveResult, m_ident); + generator.emitLoad(callArguments.thisRegister(), jsUndefined()); + return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } RefPtr func = generator.newTemporary(); CallArguments callArguments(generator, m_args); - int identifierStart = divot() - startOffset(); + int identifierStart = divot() - divotStartOffset(); - generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0); + generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0, divotLine(), divotLineStart()); generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), resolveResult, m_ident); - return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset()); + return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } // ------------------------------ FunctionCallBracketNode ---------------------------------- @@ -454,11 +463,11 @@ RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, { RefPtr base = generator.emitNode(m_base); RegisterID* property = generator.emitNode(m_subscript); - generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); + generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart()); RefPtr function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property); CallArguments callArguments(generator, m_args); generator.emitMove(callArguments.thisRegister(), base.get()); - return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset()); + return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } // ------------------------------ FunctionCallDotNode ---------------------------------- @@ -468,9 +477,9 @@ RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, Regi RefPtr function = generator.tempDestination(dst); CallArguments callArguments(generator, m_args); generator.emitNode(callArguments.thisRegister(), m_base); - generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); + generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart()); generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident); - return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset()); + return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart()); } RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) @@ -478,7 +487,7 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RefPtr