From 41386e9cb918eed93b3f13648cbef387e371e451 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Wed, 20 May 2015 09:56:07 +0000 Subject: webkitgtk-2.4.9 --- .../JavaScriptCore/bytecompiler/NodesCodegen.cpp | 1782 ++++++-------------- 1 file changed, 476 insertions(+), 1306 deletions(-) (limited to 'Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp') diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp index 477fa5c73..1ffd4f311 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, 2013, 2015 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 @@ -28,25 +28,23 @@ #include "Nodes.h" #include "NodeConstructors.h" -#include "BuiltinNames.h" #include "BytecodeGenerator.h" #include "CallFrame.h" #include "Debugger.h" #include "JIT.h" #include "JSFunction.h" #include "JSGlobalObject.h" +#include "JSNameScope.h" #include "JSONObject.h" #include "LabelScope.h" #include "Lexer.h" -#include "JSCInlines.h" -#include "JSTemplateRegistryKey.h" +#include "Operations.h" #include "Parser.h" #include "PropertyNameArray.h" #include "RegExpCache.h" #include "RegExpObject.h" #include "SamplingTool.h" #include "StackAlignment.h" -#include "TemplateRegistryKey.h" #include #include #include @@ -123,15 +121,6 @@ JSValue StringNode::jsValue(BytecodeGenerator& generator) const return generator.addStringConstant(m_value); } -// ------------------------------ NumberNode ---------------------------------- - -RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - if (dst == generator.ignoredResult()) - return nullptr; - return generator.emitLoad(dst, jsValue(generator), isIntegerNode() ? SourceCodeRepresentation::Integer : SourceCodeRepresentation::Double); -} - // ------------------------------ RegExpNode ----------------------------------- RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) @@ -145,188 +134,31 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived) - generator.emitTDZCheck(generator.thisRegister()); - if (dst == generator.ignoredResult()) return 0; - - RegisterID* result = generator.moveToDestinationIfNeeded(dst, generator.thisRegister()); - static const unsigned thisLength = 4; - generator.emitProfileType(generator.thisRegister(), position(), JSTextPosition(-1, position().offset + thisLength, -1)); - return result; -} - -// ------------------------------ SuperNode ------------------------------------- - -RegisterID* SuperNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - if (dst == generator.ignoredResult()) - return 0; - - RegisterID callee; - callee.setIndex(JSStack::Callee); - - RefPtr homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); - RefPtr protoParent = generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto); - return generator.emitGetById(generator.finalDestination(dst), protoParent.get(), generator.propertyNames().constructor); -} - -static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator) -{ - RegisterID callee; - callee.setIndex(JSStack::Callee); - - RefPtr homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); - return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto); -} - -// ------------------------------ NewTargetNode ---------------------------------- - -RegisterID* NewTargetNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - if (dst == generator.ignoredResult()) - return nullptr; - - return generator.moveToDestinationIfNeeded(dst, generator.newTarget()); + return generator.moveToDestinationIfNeeded(dst, generator.thisRegister()); } // ------------------------------ ResolveNode ---------------------------------- bool ResolveNode::isPure(BytecodeGenerator& generator) const { - return generator.variable(m_ident).offset().isStack(); + return generator.local(m_ident).get(); } RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - Variable var = generator.variable(m_ident); - if (RegisterID* local = var.local()) { - generator.emitTDZCheckIfNecessary(var, local, nullptr); + if (Local local = generator.local(m_ident)) { if (dst == generator.ignoredResult()) - return nullptr; - - generator.emitProfileType(local, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1)); - return generator.moveToDestinationIfNeeded(dst, local); + return 0; + return generator.moveToDestinationIfNeeded(dst, local.get()); } JSTextPosition divot = m_start + m_ident.length(); generator.emitExpressionInfo(divot, m_start, divot); - RefPtr scope = generator.emitResolveScope(dst, var); - RegisterID* finalDest = generator.finalDestination(dst); - RegisterID* result = generator.emitGetFromScope(finalDest, scope.get(), var, ThrowIfNotFound); - generator.emitTDZCheckIfNecessary(var, finalDest, nullptr); - generator.emitProfileType(finalDest, var, m_position, JSTextPosition(-1, m_position.offset + m_ident.length(), -1)); - return result; -} - -#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX) -// ------------------------------ TemplateStringNode ----------------------------------- - -RegisterID* TemplateStringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - if (dst == generator.ignoredResult()) - return nullptr; - return generator.emitLoad(dst, JSValue(generator.addStringConstant(cooked()))); -} - -// ------------------------------ TemplateLiteralNode ----------------------------------- - -RegisterID* TemplateLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - if (!m_templateExpressions) { - TemplateStringNode* templateString = m_templateStrings->value(); - ASSERT_WITH_MESSAGE(!m_templateStrings->next(), "Only one template element exists because there's no expression in a given template literal."); - return generator.emitNode(dst, templateString); - } - - Vector, 16> temporaryRegisters; - - TemplateStringListNode* templateString = m_templateStrings; - TemplateExpressionListNode* templateExpression = m_templateExpressions; - for (; templateExpression; templateExpression = templateExpression->next(), templateString = templateString->next()) { - // Evaluate TemplateString. - if (!templateString->value()->cooked().isEmpty()) { - temporaryRegisters.append(generator.newTemporary()); - generator.emitNode(temporaryRegisters.last().get(), templateString->value()); - } - - // Evaluate Expression. - temporaryRegisters.append(generator.newTemporary()); - generator.emitNode(temporaryRegisters.last().get(), templateExpression->value()); - generator.emitToString(temporaryRegisters.last().get(), temporaryRegisters.last().get()); - } - - // Evaluate tail TemplateString. - if (!templateString->value()->cooked().isEmpty()) { - temporaryRegisters.append(generator.newTemporary()); - generator.emitNode(temporaryRegisters.last().get(), templateString->value()); - } - - return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size()); -} - -// ------------------------------ TaggedTemplateNode ----------------------------------- - -RegisterID* TaggedTemplateNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - ExpectedFunction expectedFunction = NoExpectedFunction; - RefPtr tag = nullptr; - RefPtr base = nullptr; - if (!m_tag->isLocation()) { - tag = generator.newTemporary(); - tag = generator.emitNode(tag.get(), m_tag); - } else if (m_tag->isResolveNode()) { - ResolveNode* resolve = static_cast(m_tag); - const Identifier& identifier = resolve->identifier(); - expectedFunction = generator.expectedFunctionForIdentifier(identifier); - - Variable var = generator.variable(identifier); - if (RegisterID* local = var.local()) - tag = generator.emitMove(generator.newTemporary(), local); - else { - tag = generator.newTemporary(); - base = generator.newTemporary(); - - JSTextPosition newDivot = divotStart() + identifier.length(); - generator.emitExpressionInfo(newDivot, divotStart(), newDivot); - generator.moveToDestinationIfNeeded(base.get(), generator.emitResolveScope(base.get(), var)); - generator.emitGetFromScope(tag.get(), base.get(), var, ThrowIfNotFound); - } - } else if (m_tag->isBracketAccessorNode()) { - BracketAccessorNode* bracket = static_cast(m_tag); - base = generator.newTemporary(); - base = generator.emitNode(base.get(), bracket->base()); - RefPtr property = generator.emitNode(bracket->subscript()); - tag = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get()); - } else { - ASSERT(m_tag->isDotAccessorNode()); - DotAccessorNode* dot = static_cast(m_tag); - base = generator.newTemporary(); - base = generator.emitNode(base.get(), dot->base()); - tag = generator.emitGetById(generator.newTemporary(), base.get(), dot->identifier()); - } - - RefPtr templateObject = generator.emitGetTemplateObject(generator.newTemporary(), this); - - unsigned expressionsCount = 0; - for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next()) - ++expressionsCount; - - CallArguments callArguments(generator, nullptr, 1 + expressionsCount); - if (base) - generator.emitMove(callArguments.thisRegister(), base.get()); - else - generator.emitLoad(callArguments.thisRegister(), jsUndefined()); - - unsigned argumentIndex = 0; - generator.emitMove(callArguments.argumentRegister(argumentIndex++), templateObject.get()); - for (TemplateExpressionListNode* templateExpression = m_templateLiteral->templateExpressions(); templateExpression; templateExpression = templateExpression->next()) - generator.emitNode(callArguments.argumentRegister(argumentIndex++), templateExpression->value()); - - return generator.emitCall(generator.finalDestination(dst, tag.get()), tag.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd()); + RefPtr scope = generator.emitResolveScope(generator.tempDestination(dst), m_ident); + return generator.emitGetFromScope(generator.finalDestination(dst), scope.get(), m_ident, ThrowIfNotFound); } -#endif // ------------------------------ ArrayNode ------------------------------------ @@ -399,7 +231,7 @@ bool ArrayNode::isSimpleArray() const return true; } -ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNumber, int startPosition) const +ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPosition) const { ASSERT(!m_elision && !m_optional); ElementNode* ptr = m_element; @@ -408,12 +240,12 @@ ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNu JSTokenLocation location; location.line = lineNumber; location.startOffset = startPosition; - ArgumentListNode* head = new (parserArena) ArgumentListNode(location, ptr->value()); + ArgumentListNode* head = new (vm) ArgumentListNode(location, ptr->value()); ArgumentListNode* tail = head; ptr = ptr->next(); for (; ptr; ptr = ptr->next()) { ASSERT(!ptr->elision()); - tail = new (parserArena) ArgumentListNode(location, tail, ptr->value()); + tail = new (vm) ArgumentListNode(location, tail, ptr->value()); } return head; } @@ -422,59 +254,49 @@ ArgumentListNode* ArrayNode::toArgumentList(ParserArena& parserArena, int lineNu RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - if (!m_list) { - if (dst == generator.ignoredResult()) - return 0; - return generator.emitNewObject(generator.finalDestination(dst)); - } - RefPtr newObj = generator.emitNewObject(generator.tempDestination(dst)); - generator.emitNode(newObj.get(), m_list); - return generator.moveToDestinationIfNeeded(dst, newObj.get()); + if (!m_list) { + if (dst == generator.ignoredResult()) + return 0; + return generator.emitNewObject(generator.finalDestination(dst)); + } + return generator.emitNode(dst, m_list); } // ------------------------------ PropertyListNode ----------------------------- -static inline void emitPutHomeObject(BytecodeGenerator& generator, RegisterID* function, RegisterID* homeObject) -{ - generator.emitPutById(function, generator.propertyNames().homeObjectPrivateName, homeObject); -} - RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { + RefPtr newObj = generator.tempDestination(dst); + + generator.emitNewObject(newObj.get()); + // Fast case: this loop just handles regular value properties. PropertyListNode* p = this; - for (; p && (p->m_node->m_type & PropertyNode::Constant); p = p->m_next) - emitPutConstantProperty(generator, dst, *p->m_node); + for (; p && p->m_node->m_type == PropertyNode::Constant; p = p->m_next) { + if (p->m_node->m_name) { + generator.emitDirectPutById(newObj.get(), *p->m_node->name(), generator.emitNode(p->m_node->m_assign)); + continue; + } + RefPtr propertyName = generator.emitNode(p->m_node->m_expression); + generator.emitDirectPutByVal(newObj.get(), propertyName.get(), generator.emitNode(p->m_node->m_assign)); + } // Were there any get/set properties? if (p) { - // Build a list of getter/setter pairs to try to put them at the same time. If we encounter - // a computed property, just emit everything as that may override previous values. - bool hasComputedProperty = false; - typedef std::pair GetterSetterPair; - typedef HashMap GetterSetterMap; + typedef HashMap GetterSetterMap; GetterSetterMap map; // Build a map, pairing get/set values together. for (PropertyListNode* q = p; q; q = q->m_next) { PropertyNode* node = q->m_node; - if (node->m_type & PropertyNode::Computed) { - hasComputedProperty = true; - break; - } - if (node->m_type & PropertyNode::Constant) + if (node->m_type == PropertyNode::Constant) continue; - // Duplicates are possible. - GetterSetterPair pair(node, static_cast(nullptr)); + GetterSetterPair pair(node, static_cast(0)); GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair); - if (!result.isNewEntry) { - if (result.iterator->value.first->m_type == node->m_type) - result.iterator->value.first = node; - else - result.iterator->value.second = node; - } + if (!result.isNewEntry) + result.iterator->value.second = node; } // Iterate over the remaining properties in the list. @@ -482,28 +304,20 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe PropertyNode* node = p->m_node; // Handle regular values. - if (node->m_type & PropertyNode::Constant) { - emitPutConstantProperty(generator, dst, *node); + if (node->m_type == PropertyNode::Constant) { + if (node->name()) { + generator.emitDirectPutById(newObj.get(), *node->name(), generator.emitNode(node->m_assign)); + continue; + } + RefPtr propertyName = generator.emitNode(p->m_node->m_expression); + generator.emitDirectPutByVal(newObj.get(), propertyName.get(), generator.emitNode(p->m_node->m_assign)); continue; } - + RegisterID* value = generator.emitNode(node->m_assign); - bool isClassProperty = node->needsSuperBinding(); - if (isClassProperty) - emitPutHomeObject(generator, value, dst); - - ASSERT(node->m_type & (PropertyNode::Getter | PropertyNode::Setter)); - - // This is a get/set property which may be overridden by a computed property later. - if (hasComputedProperty) { - if (node->m_type & PropertyNode::Getter) - generator.emitPutGetterById(dst, *node->name(), value); - else - generator.emitPutSetterById(dst, *node->name(), value); - continue; - } - // This is a get/set property pair. + // This is a get/set property, find its entry in the map. + ASSERT(node->m_type == PropertyNode::Getter || node->m_type == PropertyNode::Setter); GetterSetterMap::iterator it = map.find(node->name()->impl()); ASSERT(it != map.end()); GetterSetterPair& pair = it->value; @@ -511,123 +325,75 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe // Was this already generated as a part of its partner? if (pair.second == node) continue; - + // Generate the paired node now. RefPtr getterReg; RefPtr setterReg; - RegisterID* secondReg = nullptr; - if (node->m_type & PropertyNode::Getter) { + if (node->m_type == PropertyNode::Getter) { getterReg = value; if (pair.second) { - ASSERT(pair.second->m_type & PropertyNode::Setter); + ASSERT(pair.second->m_type == PropertyNode::Setter); setterReg = generator.emitNode(pair.second->m_assign); - secondReg = setterReg.get(); } else { setterReg = generator.newTemporary(); generator.emitLoad(setterReg.get(), jsUndefined()); } } else { - ASSERT(node->m_type & PropertyNode::Setter); + ASSERT(node->m_type == PropertyNode::Setter); setterReg = value; if (pair.second) { - ASSERT(pair.second->m_type & PropertyNode::Getter); + ASSERT(pair.second->m_type == PropertyNode::Getter); getterReg = generator.emitNode(pair.second->m_assign); - secondReg = getterReg.get(); } else { getterReg = generator.newTemporary(); generator.emitLoad(getterReg.get(), jsUndefined()); } } - ASSERT(!pair.second || isClassProperty == pair.second->needsSuperBinding()); - if (isClassProperty && pair.second) - emitPutHomeObject(generator, secondReg, dst); - - if (isClassProperty) { - RefPtr propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node->name()); - generator.emitCallDefineProperty(dst, propertyNameRegister.get(), - nullptr, getterReg.get(), setterReg.get(), BytecodeGenerator::PropertyConfigurable, m_position); - } else - generator.emitPutGetterSetter(dst, *node->name(), getterReg.get(), setterReg.get()); + generator.emitPutGetterSetter(newObj.get(), *node->name(), getterReg.get(), setterReg.get()); } } - return dst; -} - -void PropertyListNode::emitPutConstantProperty(BytecodeGenerator& generator, RegisterID* newObj, PropertyNode& node) -{ - RefPtr value = generator.emitNode(node.m_assign); - if (node.needsSuperBinding()) { - emitPutHomeObject(generator, value.get(), newObj); - - RefPtr propertyNameRegister; - if (node.name()) - propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name()); - else - propertyNameRegister = generator.emitNode(node.m_expression); - - generator.emitCallDefineProperty(newObj, propertyNameRegister.get(), - value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position); - return; - } - if (const auto* identifier = node.name()) { - Optional optionalIndex = parseIndex(*identifier); - if (!optionalIndex) { - generator.emitDirectPutById(newObj, *identifier, value.get(), node.putType()); - return; - } - - RefPtr index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value())); - generator.emitDirectPutByVal(newObj, index.get(), value.get()); - return; - } - RefPtr propertyName = generator.emitNode(node.m_expression); - generator.emitDirectPutByVal(newObj, propertyName.get(), value.get()); + return generator.moveToDestinationIfNeeded(dst, newObj.get()); } // ------------------------------ BracketAccessorNode -------------------------------- RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - if (m_base->isSuperNode()) { - // FIXME: Should we generate the profiler info? - if (m_subscript->isString()) { - const Identifier& id = static_cast(m_subscript)->value(); - return generator.emitGetById(generator.finalDestination(dst), emitSuperBaseForCallee(generator), id); - } - return generator.emitGetByVal(generator.finalDestination(dst), emitSuperBaseForCallee(generator), generator.emitNode(m_subscript)); - } - - RegisterID* ret; - RegisterID* finalDest = generator.finalDestination(dst); - - if (m_subscript->isString()) { - RefPtr base = generator.emitNode(m_base); - ret = generator.emitGetById(finalDest, base.get(), static_cast(m_subscript)->value()); - } else { - RefPtr base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator)); + if (m_base->isResolveNode() + && generator.willResolveToArguments(static_cast(m_base)->identifier()) + && !generator.symbolTable().slowArguments()) { RegisterID* property = generator.emitNode(m_subscript); - ret = generator.emitGetByVal(finalDest, base.get(), property); + generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); + 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(), divotStart(), divotEnd()); - - generator.emitProfileType(finalDest, divotStart(), divotEnd()); - return ret; + return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property); } // ------------------------------ DotAccessorNode -------------------------------- RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - RefPtr base = m_base->isSuperNode() ? emitSuperBaseForCallee(generator) : generator.emitNode(m_base); + if (m_ident == generator.propertyNames().length) { + if (!m_base->isResolveNode()) + goto nonArgumentsPath; + ResolveNode* resolveNode = static_cast(m_base); + if (!generator.willResolveToArguments(resolveNode->identifier())) + goto nonArgumentsPath; + generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); + return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments()); + } + +nonArgumentsPath: + RegisterID* base = generator.emitNode(m_base); generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); - RegisterID* finalDest = generator.finalDestination(dst); - RegisterID* ret = generator.emitGetById(finalDest, base.get(), m_ident); - generator.emitProfileType(finalDest, divotStart(), divotEnd()); - return ret; + return generator.emitGetById(generator.finalDestination(dst), base, m_ident); } // ------------------------------ ArgumentListNode ----------------------------- @@ -650,7 +416,6 @@ RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* RefPtr func = generator.emitNode(m_expr); RefPtr returnValue = generator.finalDestination(dst, func.get()); CallArguments callArguments(generator, m_args); - generator.emitMove(callArguments.thisRegister(), func.get()); return generator.emitConstruct(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd()); } @@ -683,9 +448,8 @@ CallArguments::CallArguments(BytecodeGenerator& generator, ArgumentsNode* argume RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - Variable var = generator.variable(generator.propertyNames().eval); - if (RegisterID* local = var.local()) { - RefPtr func = generator.emitMove(generator.tempDestination(dst), local); + if (Local local = generator.local(generator.propertyNames().eval)) { + RefPtr func = generator.emitMove(generator.tempDestination(dst), local.get()); CallArguments callArguments(generator, m_args); generator.emitLoad(callArguments.thisRegister(), jsUndefined()); return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd()); @@ -695,10 +459,8 @@ RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, Reg CallArguments callArguments(generator, m_args); JSTextPosition newDivot = divotStart() + 4; generator.emitExpressionInfo(newDivot, divotStart(), newDivot); - generator.moveToDestinationIfNeeded( - callArguments.thisRegister(), - generator.emitResolveScope(callArguments.thisRegister(), var)); - generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound); + generator.emitResolveScope(callArguments.thisRegister(), generator.propertyNames().eval); + generator.emitGetFromScope(func.get(), callArguments.thisRegister(), generator.propertyNames().eval, ThrowIfNotFound); return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStart(), divotEnd()); } @@ -709,18 +471,8 @@ RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, Re RefPtr func = generator.emitNode(m_expr); RefPtr returnValue = generator.finalDestination(dst, func.get()); CallArguments callArguments(generator, m_args); - if (m_expr->isSuperNode()) { - ASSERT(generator.isConstructor()); - ASSERT(generator.constructorKind() == ConstructorKind::Derived); - generator.emitMove(callArguments.thisRegister(), generator.newTarget()); - RegisterID* ret = generator.emitConstruct(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); - generator.emitMove(generator.thisRegister(), ret); - return ret; - } generator.emitLoad(callArguments.thisRegister(), jsUndefined()); - RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); - generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); - return ret; + return generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); } // ------------------------------ FunctionCallResolveNode ---------------------------------- @@ -729,18 +481,14 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, { ExpectedFunction expectedFunction = generator.expectedFunctionForIdentifier(m_ident); - Variable var = generator.variable(m_ident); - if (RegisterID* local = var.local()) { - generator.emitTDZCheckIfNecessary(var, local, nullptr); - RefPtr func = generator.emitMove(generator.tempDestination(dst), local); + if (Local local = generator.local(m_ident)) { + RefPtr func = generator.emitMove(generator.tempDestination(dst), local.get()); RefPtr returnValue = generator.finalDestination(dst, func.get()); CallArguments callArguments(generator, m_args); 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. - RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); - generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); - return ret; + return generator.emitCall(returnValue.get(), func.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); } RefPtr func = generator.newTemporary(); @@ -749,82 +497,23 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, JSTextPosition newDivot = divotStart() + m_ident.length(); generator.emitExpressionInfo(newDivot, divotStart(), newDivot); - generator.moveToDestinationIfNeeded( - callArguments.thisRegister(), - generator.emitResolveScope(callArguments.thisRegister(), var)); - generator.emitGetFromScope(func.get(), callArguments.thisRegister(), var, ThrowIfNotFound); - generator.emitTDZCheckIfNecessary(var, func.get(), nullptr); - RegisterID* ret = generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd()); - generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); - return ret; -} - -// ------------------------------ BytecodeIntrinsicNode ---------------------------------- - -RegisterID* BytecodeIntrinsicNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) -{ - return (this->*m_emitter)(generator, dst); -} - -RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putByValDirect(BytecodeGenerator& generator, RegisterID* dst) -{ - ArgumentListNode* node = m_args->m_listNode; - RefPtr base = generator.emitNode(node); - node = node->m_next; - RefPtr index = generator.emitNode(node); - node = node->m_next; - RefPtr value = generator.emitNode(node); - - ASSERT(!node->m_next); - - return generator.moveToDestinationIfNeeded(dst, generator.emitDirectPutByVal(base.get(), index.get(), value.get())); -} - -RegisterID* BytecodeIntrinsicNode::emit_intrinsic_toString(BytecodeGenerator& generator, RegisterID* dst) -{ - ArgumentListNode* node = m_args->m_listNode; - RefPtr src = generator.emitNode(node); - ASSERT(!node->m_next); - - return generator.moveToDestinationIfNeeded(dst, generator.emitToString(generator.tempDestination(dst), src.get())); + generator.emitResolveScope(callArguments.thisRegister(), m_ident); + generator.emitGetFromScope(func.get(), callArguments.thisRegister(), m_ident, ThrowIfNotFound); + return generator.emitCall(returnValue.get(), func.get(), expectedFunction, callArguments, divot(), divotStart(), divotEnd()); } // ------------------------------ FunctionCallBracketNode ---------------------------------- RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) { - bool baseIsSuper = m_base->isSuperNode(); - bool subscriptIsString = m_subscript->isString(); - - RefPtr base; - if (baseIsSuper) - base = emitSuperBaseForCallee(generator); - else { - if (subscriptIsString) - base = generator.emitNode(m_base); - else - base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator)); - } - - RefPtr function; - if (subscriptIsString) { - generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); - function = generator.emitGetById(generator.tempDestination(dst), base.get(), static_cast(m_subscript)->value()); - } else { - RefPtr property = generator.emitNode(m_subscript); - generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); - function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get()); - } - + RefPtr base = generator.emitNode(m_base); + RegisterID* property = generator.emitNode(m_subscript); + generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); + RefPtr function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property); RefPtr returnValue = generator.finalDestination(dst, function.get()); CallArguments callArguments(generator, m_args); - if (baseIsSuper) - generator.emitMove(callArguments.thisRegister(), generator.thisRegister()); - else - generator.emitMove(callArguments.thisRegister(), base.get()); - RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); - generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); - return ret; + generator.emitMove(callArguments.thisRegister(), base.get()); + return generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); } // ------------------------------ FunctionCallDotNode ---------------------------------- @@ -834,16 +523,10 @@ RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, Regi RefPtr function = generator.tempDestination(dst); RefPtr returnValue = generator.finalDestination(dst, function.get()); CallArguments callArguments(generator, m_args); - bool baseIsSuper = m_base->isSuperNode(); - if (baseIsSuper) - generator.emitMove(callArguments.thisRegister(), generator.thisRegister()); - else - generator.emitNode(callArguments.thisRegister(), m_base); + generator.emitNode(callArguments.thisRegister(), m_base); generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd()); - generator.emitGetById(function.get(), baseIsSuper ? emitSuperBaseForCallee(generator) : callArguments.thisRegister(), m_ident); - RegisterID* ret = generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); - generator.emitProfileType(returnValue.get(), divotStart(), divotEnd()); - return ret; + generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident); + return generator.emitCall(returnValue.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStart(), divotEnd()); } RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) @@ -852,26 +535,11 @@ RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RefPtr