Ignore:
Timestamp:
Aug 17, 2015, 3:24:20 PM (10 years ago)
Author:
[email protected]
Message:

[ES6] Implement ES6 arrow function syntax. Arrow function specific features. Lexical bind of this
https://bugs.webkit.org/show_bug.cgi?id=144956

Source/JavaScriptCore:

Patch by Aleksandr Skachkov <[email protected]> on 2015-08-17
Reviewed by Saam Barati.

Added support of ES6 arrow function specific feature, lexical bind of this and no constructor. http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax
In patch were implemented the following cases:

this - variable |this| is point to the |this| of the function where arrow function is declared. Lexical bind of |this|
constructor - the using of the command |new| for arrow function leads to runtime error
call(), apply(), bind() - methods can only pass in arguments, but has no effect on |this|

  • CMakeLists.txt:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):

  • bytecode/ExecutableInfo.h:

(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::isArrowFunction):

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::isArrowFunction):

  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::generateFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::UnlinkedFunctionExecutable::codeBlockFor):

  • bytecode/UnlinkedFunctionExecutable.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewFunctionCommon):
(JSC::BytecodeGenerator::emitNewFunctionExpression):
(JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
(JSC::BytecodeGenerator::emitLoadArrowFunctionThis):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ArrowFuncExprNode::emitBytecode):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToPhantomNewFunction):
(JSC::DFG::Node::hasCellOperand):
(JSC::DFG::Node::isFunctionAllocation):

  • dfg/DFGNodeType.h:
  • dfg/DFGObjectAllocationSinkingPhase.cpp:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGPromotedHeapLocation.cpp:

(WTF::printInternal):

  • dfg/DFGPromotedHeapLocation.h:
  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileLoadArrowFunctionThis):
(JSC::DFG::SpeculativeJIT::compileNewFunctionCommon):
(JSC::DFG::SpeculativeJIT::compileNewFunction):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStoreBarrierInsertionPhase.cpp:
  • dfg/DFGStructureRegistrationPhase.cpp:

(JSC::DFG::StructureRegistrationPhase::run):

  • ftl/FTLAbstractHeapRepository.cpp:
  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
(JSC::FTL::DFG::LowerDFGToLLVM::compileNewFunction):
(JSC::FTL::DFG::LowerDFGToLLVM::compileLoadArrowFunctionThis):

  • ftl/FTLOperations.cpp:

(JSC::FTL::operationMaterializeObjectInOSR):

  • interpreter/Interpreter.cpp:
  • interpreter/Interpreter.h:
  • jit/CCallHelpers.h:

(JSC::CCallHelpers::setupArgumentsWithExecState): Added 3 arguments version for windows build.

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • jit/JIT.h:
  • jit/JITInlines.h:

(JSC::JIT::callOperation):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_load_arrowfunction_this):
(JSC::JIT::emit_op_new_func_exp):
(JSC::JIT::emitNewFuncExprCommon):
(JSC::JIT::emit_op_new_arrow_func_exp):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_load_arrowfunction_this):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • llint/LLIntOffsetsExtractor.cpp:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::setUpCall):

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createFunctionMetadata):
(JSC::ASTBuilder::createArrowFunctionExpr):

  • parser/NodeConstructors.h:

(JSC::BaseFuncExprNode::BaseFuncExprNode):
(JSC::FuncExprNode::FuncExprNode):
(JSC::ArrowFuncExprNode::ArrowFuncExprNode):

  • parser/Nodes.cpp:

(JSC::FunctionMetadataNode::FunctionMetadataNode):

  • parser/Nodes.h:

(JSC::ExpressionNode::isArrowFuncExprNode):

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseFunctionBody):
(JSC::Parser<LexerType>::parseFunctionInfo):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createFunctionMetadata):

  • runtime/Executable.cpp:

(JSC::ScriptExecutable::newCodeBlockFor):

  • runtime/Executable.h:
  • runtime/JSArrowFunction.cpp: Added.

(JSC::JSArrowFunction::destroy):
(JSC::JSArrowFunction::create):
(JSC::JSArrowFunction::JSArrowFunction):
(JSC::JSArrowFunction::createWithInvalidatedReallocationWatchpoint):
(JSC::JSArrowFunction::visitChildren):
(JSC::JSArrowFunction::getConstructData):

  • runtime/JSArrowFunction.h: Added.

(JSC::JSArrowFunction::allocationSize):
(JSC::JSArrowFunction::createImpl):
(JSC::JSArrowFunction::boundThis):
(JSC::JSArrowFunction::createStructure):
(JSC::JSArrowFunction::offsetOfThisValue):

  • runtime/JSFunction.h:
  • runtime/JSFunctionInlines.h:

(JSC::JSFunction::JSFunction):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::arrowFunctionStructure):

  • tests/stress/arrowfunction-activation-sink-osrexit-default-value-tdz-error.js: Added.
  • tests/stress/arrowfunction-activation-sink-osrexit-default-value.js: Added.
  • tests/stress/arrowfunction-activation-sink-osrexit.js: Added.
  • tests/stress/arrowfunction-activation-sink.js: Added.
  • tests/stress/arrowfunction-bound.js: Added.
  • tests/stress/arrowfunction-call.js: Added.
  • tests/stress/arrowfunction-constructor.js: Added.
  • tests/stress/arrowfunction-lexical-bind-this-1.js: Added.
  • tests/stress/arrowfunction-lexical-bind-this-2.js: Added.
  • tests/stress/arrowfunction-lexical-bind-this-3.js: Added.
  • tests/stress/arrowfunction-lexical-bind-this-4.js: Added.
  • tests/stress/arrowfunction-lexical-bind-this-5.js: Added.
  • tests/stress/arrowfunction-lexical-bind-this-6.js: Added.
  • tests/stress/arrowfunction-lexical-this-activation-sink-osrexit.js: Added.
  • tests/stress/arrowfunction-lexical-this-activation-sink.js: Added.
  • tests/stress/arrowfunction-lexical-this-sinking-no-double-allocate.js: Added.
  • tests/stress/arrowfunction-lexical-this-sinking-osrexit.js: Added.
  • tests/stress/arrowfunction-lexical-this-sinking-put.js: Added.
  • tests/stress/arrowfunction-others.js: Added.
  • tests/stress/arrowfunction-run-10-1.js: Added.
  • tests/stress/arrowfunction-run-10-2.js: Added.
  • tests/stress/arrowfunction-run-10000-1.js: Added.
  • tests/stress/arrowfunction-run-10000-2.js: Added.
  • tests/stress/arrowfunction-sinking-no-double-allocate.js: Added.
  • tests/stress/arrowfunction-sinking-osrexit.js: Added.
  • tests/stress/arrowfunction-sinking-put.js: Added.
  • tests/stress/arrowfunction-tdz.js: Added.
  • tests/stress/arrowfunction-typeof.js: Added.

LayoutTests:

Patch by Skachkov Oleksandr <[email protected]> on 2015-08-17
Reviewed by Saam Barati.

  • js/arrowfunction-bind-expected.txt: Added.
  • js/arrowfunction-bind.html: Added.
  • js/arrowfunction-call-expected.txt: Added.
  • js/arrowfunction-call.html: Added.
  • js/arrowfunction-constructor-expected.txt: Added.
  • js/arrowfunction-constructor.html: Added.
  • js/arrowfunction-lexical-bind-this-expected.txt: Added.
  • js/arrowfunction-lexical-bind-this.html: Added.
  • js/arrowfunction-others-expected.txt: Added.
  • js/arrowfunction-others.html: Added.
  • js/arrowfunction-tdz-expected.txt: Added.
  • js/arrowfunction-tdz.html: Added.
  • js/arrowfunction-typeof-expected.txt: Added.
  • js/arrowfunction-typeof.html: Added.
  • js/regress/arrowfunction-call-expected.txt: Added.
  • js/regress/arrowfunction-call.html: Added.
  • js/regress/script-tests/arrowfunction-call.js: Added.
  • js/regress/script-tests/function-call.js: Added.
  • js/script-tests/arrowfunction-bind.js: Added.
  • js/script-tests/arrowfunction-call.js: Added.
  • js/script-tests/arrowfunction-constructor.js: Added.
  • js/script-tests/arrowfunction-lexical-bind-this.js: Added.
  • js/script-tests/arrowfunction-others.js: Added.
  • js/script-tests/arrowfunction-tdz.js: Added.
  • js/script-tests/arrowfunction-typeof.js: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp

    r188507 r188545  
    139139    // replace any use of those pointers by the corresponding
    140140    // materialization
    141     enum class Kind { Escaped, Object, Activation, Function };
     141    enum class Kind { Escaped, Object, Activation, Function, NewArrowFunction };
    142142
    143143    explicit Allocation(Node* identifier = nullptr, Kind kind = Kind::Escaped)
     
    233233    bool isFunctionAllocation() const
    234234    {
    235         return m_kind == Kind::Function;
     235        return m_kind == Kind::Function || m_kind == Kind::NewArrowFunction;
     236    }
     237   
     238    bool isArrowFunctionAllocation() const
     239    {
     240        return m_kind == Kind::NewArrowFunction;
    236241    }
    237242
     
    267272        case Kind::Function:
    268273            out.print("Function");
     274            break;
     275               
     276        case Kind::NewArrowFunction:
     277            out.print("NewArrowFunction");
    269278            break;
    270279
     
    841850        }
    842851
    843         case NewFunction: {
     852        case NewFunction:
     853        case NewArrowFunction: {
     854            bool isArrowFunction = node->op() == NewArrowFunction;
    844855            if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid()) {
    845856                m_heap.escape(node->child1().node());
    846857                break;
    847858            }
    848             target = &m_heap.newAllocation(node, Allocation::Kind::Function);
     859           
     860            target = &m_heap.newAllocation(node, isArrowFunction ? Allocation::Kind::NewArrowFunction : Allocation::Kind::Function);
    849861            writes.add(FunctionExecutablePLoc, LazyNode(node->cellOperand()));
    850862            writes.add(FunctionActivationPLoc, LazyNode(node->child1().node()));
     863            if (isArrowFunction)
     864                writes.add(ArrowFunctionBoundThisPLoc, LazyNode(node->child2().node()));
    851865            break;
    852866        }
     
    10351049            break;
    10361050
     1051        case LoadArrowFunctionThis:
     1052            target = m_heap.onlyLocalAllocation(node->child1().node());
     1053            if (target && target->isArrowFunctionAllocation())
     1054                exactRead = ArrowFunctionBoundThisPLoc;
     1055            else
     1056                m_heap.escape(node->child1().node());
     1057            break;
     1058       
    10371059        case GetScope:
    10381060            target = m_heap.onlyLocalAllocation(node->child1().node());
     
    14681490        }
    14691491
     1492        case Allocation::Kind::NewArrowFunction:
    14701493        case Allocation::Kind::Function: {
    14711494            FrozenValue* executable = allocation.identifier()->cellOperand();
    1472 
     1495           
     1496            NodeType nodeType = allocation.kind() == Allocation::Kind::NewArrowFunction ? NewArrowFunction : NewFunction;
     1497           
    14731498            return m_graph.addNode(
    1474                 allocation.identifier()->prediction(), NewFunction,
     1499                allocation.identifier()->prediction(), nodeType,
    14751500                NodeOrigin(
    14761501                    allocation.identifier()->origin.semantic,
     
    17761801                        break;
    17771802
     1803                    case NewArrowFunction:
    17781804                    case NewFunction:
    17791805                        node->convertToPhantomNewFunction();
     
    20262052            break;
    20272053        }
    2028 
    2029         case NewFunction: {
     2054       
     2055        case NewFunction:
     2056        case NewArrowFunction: {
     2057            bool isArrowFunction = node->op() == NewArrowFunction;
    20302058            Vector<PromotedHeapLocation> locations = m_locationsForAllocation.get(escapee);
    2031             ASSERT(locations.size() == 2);
    2032 
     2059            ASSERT(locations.size() == (isArrowFunction ? 3 : 2));
     2060               
    20332061            PromotedHeapLocation executable(FunctionExecutablePLoc, allocation.identifier());
    20342062            ASSERT_UNUSED(executable, locations.contains(executable));
    2035 
     2063               
    20362064            PromotedHeapLocation activation(FunctionActivationPLoc, allocation.identifier());
    20372065            ASSERT(locations.contains(activation));
    20382066
    20392067            node->child1() = Edge(resolve(block, activation), KnownCellUse);
     2068           
     2069            if (isArrowFunction) {
     2070                PromotedHeapLocation boundThis(ArrowFunctionBoundThisPLoc, allocation.identifier());
     2071                ASSERT(locations.contains(boundThis));
     2072                node->child2() = Edge(resolve(block, boundThis), CellUse);
     2073            }
     2074           
    20402075            break;
    20412076        }
Note: See TracChangeset for help on using the changeset viewer.