Changeset 220778 in webkit


Ignore:
Timestamp:
Aug 15, 2017 6:10:01 PM (7 years ago)
Author:
commit-queue@webkit.org
Message:

JSTests:
Support the 'with' keyword in FTL.
https://bugs.webkit.org/show_bug.cgi?id=175585

Patch by Robin Morisset <rmorisset@apple.com> on 2017-08-15
Reviewed by Saam Barati.

Also improve the JSTest/stress/with.js file to test
what happens when non-objects are passed to with.

  • stress/with.js:

(foo):
(i.catch):
(i.with): Deleted.

Source/JavaScriptCore:
Support the 'with' keyword in FTL
https://bugs.webkit.org/show_bug.cgi?id=175585

Patch by Robin Morisset <rmorisset@apple.com> on 2017-08-15
Reviewed by Saam Barati.

Also makes sure that the order of arguments of PushWithScope, op_push_with_scope, JSWithScope::create()
and so on is consistent (always parentScope first, the new scopeObject second). We used to go from one
to the other at different step which was quite confusing. I picked this order for consistency with CreateActivation
that takes its parentScope argument first.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitPushWithScope):

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::evaluateWithScopeExtension):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compilePushWithScope):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compilePushWithScope):

  • jit/JITOperations.cpp:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/Completion.cpp:

(JSC::evaluateWithScopeExtension):

  • runtime/JSWithScope.cpp:

(JSC::JSWithScope::create):

  • runtime/JSWithScope.h:

Source/WebCore:
Change the order of arguments of JSWithScope::create() for consistency
https://bugs.webkit.org/show_bug.cgi?id=175585

Patch by Robin Morisset <rmorisset@apple.com> on 2017-08-15
Reviewed by Saam Barati.

No change of behavior.

  • bindings/js/JSHTMLElementCustom.cpp:

(WebCore::JSHTMLElement::pushEventHandlerScope const):

Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r220735 r220778  
     12017-08-15  Robin Morisset  <rmorisset@apple.com>
     2
     3        Support the 'with' keyword in FTL.
     4        https://bugs.webkit.org/show_bug.cgi?id=175585
     5
     6        Reviewed by Saam Barati.
     7
     8        Also improve the JSTest/stress/with.js file to test
     9        what happens when non-objects are passed to with.
     10
     11        * stress/with.js:
     12        (foo):
     13        (i.catch):
     14        (i.with): Deleted.
     15
    1162017-08-14  Keith Miller  <keith_miller@apple.com>
    217
  • trunk/JSTests/stress/with.js

    r220724 r220778  
    1 for (var i = 0; i < 10000; ++i) {
    2     var x = 1;
    3     var y = 2;
    4 
    5     var z = {a: 42};
    6     with (z) {
     1function foo (x, y, z, newX, checkZ, errorMessage) {
     2    with(z) {
    73        x = y;
    84    }
    9     if (x !== 2 || y !== 2 || z.a !== 42) {
    10         throw "Error: bad result, first case, for i = " + i;
    11     }
    12 
    13     z = {y: 42}
    14     with (z) {
    15         x = y;
    16     }
    17     if (x !== 42 || y !== 2 || z.y !== 42) {
    18         throw "Error: bad result, second case, for i = " + i;
    19     }
    20 
    21     z = {x: 13};
    22     with (z) {
    23         x = y;
    24     }
    25     if (x !== 42 || y !== 2 || z.x !== 2) {
    26         throw "Error: bad result, third case, for i = " + i;
    27     }
    28 
    29     z = {x:13, y:14};
    30     with (z) {
    31         x = y;
    32     }
    33     if (x !== 42 || y !== 2 || z.x !== 14 || z.y !== 14) {
    34         throw "Error: bad result, fourth case, for i = " + i;
     5    if (x !== newX || !checkZ(z)) {
     6        throw errorMessage;
    357    }
    368}
     9
     10for (var i = 0; i < 10000; ++i) {
     11    foo(1, 2, {a:42}, 2, z => z.a === 42, "Error: bad result for non-overlapping case, i = " + i);
     12    foo(1, 2, {x:42}, 1, z => z.x === 2, "Error: bad result for setter case, i = " + i);
     13    foo(1, 2, {y:42}, 42, z => z.y === 42, "Error: bad result for getter case, i = " + i);
     14    foo(1, 2, {x:42, y:13}, 1, z => z.x === 13 && z.y === 13, "Error: bad result for setter/getter case, i = " + i);
     15    foo(1, 2, "toto", 2, z => z === "toto", "Error: bad result for string case, i = " + i);
     16    try {
     17        foo(1, 2, null, 2, z =>
     18                {throw "Error: missing type error, i = " + i}, "Unreachable");
     19    } catch (e) {
     20        if (!(e instanceof TypeError)) {
     21            throw e;
     22        }
     23    }
     24}
  • trunk/Source/JavaScriptCore/ChangeLog

    r220777 r220778  
     12017-08-15  Robin Morisset  <rmorisset@apple.com>
     2
     3        Support the 'with' keyword in FTL
     4        https://bugs.webkit.org/show_bug.cgi?id=175585
     5
     6        Reviewed by Saam Barati.
     7
     8        Also makes sure that the order of arguments of PushWithScope, op_push_with_scope, JSWithScope::create()
     9        and so on is consistent (always parentScope first, the new scopeObject second). We used to go from one
     10        to the other at different step which was quite confusing. I picked this order for consistency with CreateActivation
     11        that takes its parentScope argument first.
     12
     13        * bytecompiler/BytecodeGenerator.cpp:
     14        (JSC::BytecodeGenerator::emitPushWithScope):
     15        * debugger/DebuggerCallFrame.cpp:
     16        (JSC::DebuggerCallFrame::evaluateWithScopeExtension):
     17        * dfg/DFGByteCodeParser.cpp:
     18        (JSC::DFG::ByteCodeParser::parseBlock):
     19        * dfg/DFGFixupPhase.cpp:
     20        (JSC::DFG::FixupPhase::fixupNode):
     21        * dfg/DFGSpeculativeJIT.cpp:
     22        (JSC::DFG::SpeculativeJIT::compilePushWithScope):
     23        * ftl/FTLCapabilities.cpp:
     24        (JSC::FTL::canCompile):
     25        * ftl/FTLLowerDFGToB3.cpp:
     26        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     27        (JSC::FTL::DFG::LowerDFGToB3::compilePushWithScope):
     28        * jit/JITOperations.cpp:
     29        * runtime/CommonSlowPaths.cpp:
     30        (JSC::SLOW_PATH_DECL):
     31        * runtime/Completion.cpp:
     32        (JSC::evaluateWithScopeExtension):
     33        * runtime/JSWithScope.cpp:
     34        (JSC::JSWithScope::create):
     35        * runtime/JSWithScope.h:
     36
    1372017-08-15  Saam Barati  <sbarati@apple.com>
    238
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r220735 r220778  
    37673767    emitOpcode(op_push_with_scope);
    37683768    instructions().append(newScope->index());
     3769    instructions().append(scopeRegister()->index());
    37693770    instructions().append(objectScope->index());
    3770     instructions().append(scopeRegister()->index());
    37713771
    37723772    emitMove(scopeRegister(), newScope);
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r218794 r220778  
    256256    if (scopeExtensionObject) {
    257257        JSScope* ignoredPreviousScope = globalObject->globalScope();
    258         globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, scopeExtensionObject, ignoredPreviousScope));
     258        globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, ignoredPreviousScope, scopeExtensionObject));
    259259    }
    260260
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r220770 r220778  
    56525652
    56535653        case op_push_with_scope: {
    5654             Node* scopeObject = get(VirtualRegister(currentInstruction[2].u.operand));
    5655             Node* currentScope = get(VirtualRegister(currentInstruction[3].u.operand));
    5656             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(PushWithScope, scopeObject, currentScope));
     5654            Node* currentScope = get(VirtualRegister(currentInstruction[2].u.operand));
     5655            Node* object = get(VirtualRegister(currentInstruction[3].u.operand));
     5656            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(PushWithScope, currentScope, object));
    56575657            NEXT_OPCODE(op_push_with_scope);
    56585658        }
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r220735 r220778  
    17111711        case CreateScopedArguments:
    17121712        case CreateActivation:
     1713        case PushWithScope:
    17131714        case NewFunction:
    17141715        case NewGeneratorFunction:
    17151716        case NewAsyncFunction: {
    17161717            fixEdge<CellUse>(node->child1());
    1717             break;
    1718         }
    1719 
    1720         case PushWithScope: {
    1721             // Child2 is always the current scope, which is guaranteed to be an object.
    1722             fixEdge<KnownCellUse>(node->child2());
    17231718            break;
    17241719        }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r220724 r220778  
    11271127void SpeculativeJIT::compilePushWithScope(Node* node)
    11281128{
    1129     JSValueOperand scopeObject(this, node->child1());
    1130     SpeculateCellOperand currentScope(this, node->child2());
    1131     JSValueRegs scopeObjectRegs = scopeObject.jsValueRegs();
     1129    SpeculateCellOperand currentScope(this, node->child1());
    11321130    GPRReg currentScopeGPR = currentScope.gpr();
     1131
     1132    JSValueOperand object(this, node->child2());
     1133    JSValueRegs objectRegs = object.jsValueRegs();
    11331134
    11341135    GPRFlushedCallResult result(this);
     
    11361137   
    11371138    flushRegisters();
    1138     callOperation(operationPushWithScope, resultGPR, currentScopeGPR, scopeObjectRegs);
     1139    callOperation(operationPushWithScope, resultGPR, currentScopeGPR, objectRegs);
    11391140    m_jit.exceptionCheck();
    11401141   
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r220118 r220778  
    116116    case GetGlobalObject:
    117117    case CreateActivation:
     118    case PushWithScope:
    118119    case NewFunction:
    119120    case NewGeneratorFunction:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r220712 r220778  
    740740            compileCreateActivation();
    741741            break;
     742        case PushWithScope:
     743            compilePushWithScope();
     744            break;
    742745        case NewFunction:
    743746        case NewGeneratorFunction:
     
    42634266        }
    42644267    }
    4265    
     4268
     4269    void compilePushWithScope()
     4270    {
     4271        LValue parentScope = lowCell(m_node->child1());
     4272        LValue object = lowJSValue(m_node->child2());
     4273
     4274        LValue result = vmCall(Int64, m_out.operation(operationPushWithScope), m_callFrame, parentScope, object);
     4275
     4276        setJSValue(result);
     4277    }
     4278
    42664279    void compileCreateActivation()
    42674280    {
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r220724 r220778  
    19971997}
    19981998
    1999 JSCell* JIT_OPERATION operationPushWithScope(ExecState* exec, JSCell* currentScopeCell, EncodedJSValue scopeObjectValue)
     1999JSCell* JIT_OPERATION operationPushWithScope(ExecState* exec, JSCell* currentScopeCell, EncodedJSValue objectValue)
    20002000{
    20012001    VM& vm = exec->vm();
     
    20032003    auto scope = DECLARE_THROW_SCOPE(vm);
    20042004
    2005     JSObject* newScope = JSValue::decode(scopeObjectValue).toObject(exec);
     2005    JSObject* object = JSValue::decode(objectValue).toObject(exec);
    20062006    RETURN_IF_EXCEPTION(scope, nullptr);
    20072007
    20082008    JSScope* currentScope = jsCast<JSScope*>(currentScopeCell);
    20092009
    2010     return JSWithScope::create(vm, exec->lexicalGlobalObject(), newScope, currentScope);
     2010    return JSWithScope::create(vm, exec->lexicalGlobalObject(), currentScope, object);
    20112011}
    20122012
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r220724 r220778  
    420420EncodedJSValue JIT_OPERATION operationDeleteByValJSResult(ExecState*, EncodedJSValue base, EncodedJSValue target) WTF_INTERNAL;
    421421size_t JIT_OPERATION operationDeleteByVal(ExecState*, EncodedJSValue base, EncodedJSValue target) WTF_INTERNAL;
    422 JSCell* JIT_OPERATION operationPushWithScope(ExecState*, JSCell* currentScopeCell, EncodedJSValue scopeObject) WTF_INTERNAL;
     422JSCell* JIT_OPERATION operationPushWithScope(ExecState*, JSCell* currentScopeCell, EncodedJSValue object) WTF_INTERNAL;
    423423JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
    424424EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r218794 r220778  
    815815{
    816816    BEGIN();
    817     JSObject* newScope = OP_C(2).jsValue().toObject(exec);
    818     CHECK_EXCEPTION();
    819 
    820     int scopeReg = pc[3].u.operand;
     817    JSObject* newScope = OP_C(3).jsValue().toObject(exec);
     818    CHECK_EXCEPTION();
     819
     820    int scopeReg = pc[2].u.operand;
    821821    JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
    822     RETURN(JSWithScope::create(vm, exec->lexicalGlobalObject(), newScope, currentScope));
     822    RETURN(JSWithScope::create(vm, exec->lexicalGlobalObject(), currentScope, newScope));
    823823}
    824824
  • trunk/Source/JavaScriptCore/runtime/Completion.cpp

    r220186 r220778  
    124124    if (scopeExtensionObject) {
    125125        JSScope* ignoredPreviousScope = globalObject->globalScope();
    126         globalObject->setGlobalScopeExtension(JSWithScope::create(exec->vm(), globalObject, scopeExtensionObject, ignoredPreviousScope));
     126        globalObject->setGlobalScopeExtension(JSWithScope::create(exec->vm(), globalObject, ignoredPreviousScope, scopeExtensionObject));
    127127    }
    128128
  • trunk/Source/JavaScriptCore/runtime/JSWithScope.cpp

    r217108 r220778  
    3434
    3535JSWithScope* JSWithScope::create(
    36     VM& vm, JSGlobalObject* globalObject, JSObject* object, JSScope* next)
     36    VM& vm, JSGlobalObject* globalObject, JSScope* next, JSObject* object)
    3737{
    3838    Structure* structure = globalObject->withScopeStructure();
  • trunk/Source/JavaScriptCore/runtime/JSWithScope.h

    r206525 r220778  
    3434    typedef JSScope Base;
    3535
    36     JS_EXPORT_PRIVATE static JSWithScope* create(VM&, JSGlobalObject*, JSObject*, JSScope* next);
     36    JS_EXPORT_PRIVATE static JSWithScope* create(VM&, JSGlobalObject*, JSScope* next, JSObject*);
    3737
    3838    JSObject* object() { return m_object.get(); }
  • trunk/Source/WebCore/ChangeLog

    r220764 r220778  
     12017-08-15  Robin Morisset  <rmorisset@apple.com>
     2
     3        Change the order of arguments of JSWithScope::create() for consistency
     4        https://bugs.webkit.org/show_bug.cgi?id=175585
     5
     6        Reviewed by Saam Barati.
     7
     8        No change of behavior.
     9
     10        * bindings/js/JSHTMLElementCustom.cpp:
     11        (WebCore::JSHTMLElement::pushEventHandlerScope const):
     12
    1132017-08-15  Youenn Fablet  <youenn@apple.com>
    214
  • trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp

    r211892 r220778  
    121121    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    122122   
    123     scope = JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), element.document())), scope);
     123    scope = JSWithScope::create(vm, lexicalGlobalObject, scope, asObject(toJS(exec, globalObject(), element.document())));
    124124
    125125    // The form is next, searched before the document, but after the element itself.
    126126    if (HTMLFormElement* form = element.form())
    127         scope = JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), *form)), scope);
     127        scope = JSWithScope::create(vm, lexicalGlobalObject, scope, asObject(toJS(exec, globalObject(), *form)));
    128128
    129129    // The element is on top, searched first.
    130     return JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), element)), scope);
     130    return JSWithScope::create(vm, lexicalGlobalObject, scope, asObject(toJS(exec, globalObject(), element)));
    131131}
    132132
Note: See TracChangeset for help on using the changeset viewer.