Diff
Modified: trunk/JSTests/ChangeLog (220777 => 220778)
--- trunk/JSTests/ChangeLog 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/JSTests/ChangeLog 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1,3 +1,18 @@
+2017-08-15 Robin Morisset <[email protected]>
+
+ Support the 'with' keyword in FTL.
+ https://bugs.webkit.org/show_bug.cgi?id=175585
+
+ 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.
+
2017-08-14 Keith Miller <[email protected]>
Add testing tool to lie to the DFG about profiles
Modified: trunk/JSTests/stress/with.js (220777 => 220778)
--- trunk/JSTests/stress/with.js 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/JSTests/stress/with.js 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1,36 +1,24 @@
-for (var i = 0; i < 10000; ++i) {
- var x = 1;
- var y = 2;
-
- var z = {a: 42};
- with (z) {
+function foo (x, y, z, newX, checkZ, errorMessage) {
+ with(z) {
x = y;
}
- if (x !== 2 || y !== 2 || z.a !== 42) {
- throw "Error: bad result, first case, for i = " + i;
+ if (x !== newX || !checkZ(z)) {
+ throw errorMessage;
}
+}
- z = {y: 42}
- with (z) {
- x = y;
+for (var i = 0; i < 10000; ++i) {
+ foo(1, 2, {a:42}, 2, z => z.a === 42, "Error: bad result for non-overlapping case, i = " + i);
+ foo(1, 2, {x:42}, 1, z => z.x === 2, "Error: bad result for setter case, i = " + i);
+ foo(1, 2, {y:42}, 42, z => z.y === 42, "Error: bad result for getter case, i = " + i);
+ foo(1, 2, {x:42, y:13}, 1, z => z.x === 13 && z.y === 13, "Error: bad result for setter/getter case, i = " + i);
+ foo(1, 2, "toto", 2, z => z === "toto", "Error: bad result for string case, i = " + i);
+ try {
+ foo(1, 2, null, 2, z =>
+ {throw "Error: missing type error, i = " + i}, "Unreachable");
+ } catch (e) {
+ if (!(e instanceof TypeError)) {
+ throw e;
+ }
}
- if (x !== 42 || y !== 2 || z.y !== 42) {
- throw "Error: bad result, second case, for i = " + i;
- }
-
- z = {x: 13};
- with (z) {
- x = y;
- }
- if (x !== 42 || y !== 2 || z.x !== 2) {
- throw "Error: bad result, third case, for i = " + i;
- }
-
- z = {x:13, y:14};
- with (z) {
- x = y;
- }
- if (x !== 42 || y !== 2 || z.x !== 14 || z.y !== 14) {
- throw "Error: bad result, fourth case, for i = " + i;
- }
}
Modified: trunk/Source/_javascript_Core/ChangeLog (220777 => 220778)
--- trunk/Source/_javascript_Core/ChangeLog 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1,3 +1,39 @@
+2017-08-15 Robin Morisset <[email protected]>
+
+ Support the 'with' keyword in FTL
+ https://bugs.webkit.org/show_bug.cgi?id=175585
+
+ 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:
+
2017-08-15 Saam Barati <[email protected]>
Make VM::scratchBufferForSize thread safe
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -3766,8 +3766,8 @@
emitOpcode(op_push_with_scope);
instructions().append(newScope->index());
+ instructions().append(scopeRegister()->index());
instructions().append(objectScope->index());
- instructions().append(scopeRegister()->index());
emitMove(scopeRegister(), newScope);
m_lexicalScopeStack.append({ nullptr, newScope, true, 0 });
Modified: trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/debugger/DebuggerCallFrame.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -255,7 +255,7 @@
JSGlobalObject* globalObject = callFrame->vmEntryGlobalObject();
if (scopeExtensionObject) {
JSScope* ignoredPreviousScope = globalObject->globalScope();
- globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, scopeExtensionObject, ignoredPreviousScope));
+ globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, ignoredPreviousScope, scopeExtensionObject));
}
JSValue thisValue = this->thisValue();
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -5651,9 +5651,9 @@
}
case op_push_with_scope: {
- Node* scopeObject = get(VirtualRegister(currentInstruction[2].u.operand));
- Node* currentScope = get(VirtualRegister(currentInstruction[3].u.operand));
- set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(PushWithScope, scopeObject, currentScope));
+ Node* currentScope = get(VirtualRegister(currentInstruction[2].u.operand));
+ Node* object = get(VirtualRegister(currentInstruction[3].u.operand));
+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(PushWithScope, currentScope, object));
NEXT_OPCODE(op_push_with_scope);
}
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1710,6 +1710,7 @@
case CreateScopedArguments:
case CreateActivation:
+ case PushWithScope:
case NewFunction:
case NewGeneratorFunction:
case NewAsyncFunction: {
@@ -1717,12 +1718,6 @@
break;
}
- case PushWithScope: {
- // Child2 is always the current scope, which is guaranteed to be an object.
- fixEdge<KnownCellUse>(node->child2());
- break;
- }
-
case SetFunctionName: {
// The first child is guaranteed to be a cell because op_set_function_name is only used
// on a newly instantiated function object (the first child).
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1126,16 +1126,17 @@
void SpeculativeJIT::compilePushWithScope(Node* node)
{
- JSValueOperand scopeObject(this, node->child1());
- SpeculateCellOperand currentScope(this, node->child2());
- JSValueRegs scopeObjectRegs = scopeObject.jsValueRegs();
+ SpeculateCellOperand currentScope(this, node->child1());
GPRReg currentScopeGPR = currentScope.gpr();
+ JSValueOperand object(this, node->child2());
+ JSValueRegs objectRegs = object.jsValueRegs();
+
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
- callOperation(operationPushWithScope, resultGPR, currentScopeGPR, scopeObjectRegs);
+ callOperation(operationPushWithScope, resultGPR, currentScopeGPR, objectRegs);
m_jit.exceptionCheck();
cellResult(resultGPR, node);
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -115,6 +115,7 @@
case SkipScope:
case GetGlobalObject:
case CreateActivation:
+ case PushWithScope:
case NewFunction:
case NewGeneratorFunction:
case NewAsyncFunction:
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -739,6 +739,9 @@
case CreateActivation:
compileCreateActivation();
break;
+ case PushWithScope:
+ compilePushWithScope();
+ break;
case NewFunction:
case NewGeneratorFunction:
case NewAsyncFunction:
@@ -4262,7 +4265,17 @@
return;
}
}
-
+
+ void compilePushWithScope()
+ {
+ LValue parentScope = lowCell(m_node->child1());
+ LValue object = lowJSValue(m_node->child2());
+
+ LValue result = vmCall(Int64, m_out.operation(operationPushWithScope), m_callFrame, parentScope, object);
+
+ setJSValue(result);
+ }
+
void compileCreateActivation()
{
LValue scope = lowCell(m_node->child1());
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1996,18 +1996,18 @@
return couldDelete;
}
-JSCell* JIT_OPERATION operationPushWithScope(ExecState* exec, JSCell* currentScopeCell, EncodedJSValue scopeObjectValue)
+JSCell* JIT_OPERATION operationPushWithScope(ExecState* exec, JSCell* currentScopeCell, EncodedJSValue objectValue)
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
auto scope = DECLARE_THROW_SCOPE(vm);
- JSObject* newScope = JSValue::decode(scopeObjectValue).toObject(exec);
+ JSObject* object = JSValue::decode(objectValue).toObject(exec);
RETURN_IF_EXCEPTION(scope, nullptr);
JSScope* currentScope = jsCast<JSScope*>(currentScopeCell);
- return JSWithScope::create(vm, exec->lexicalGlobalObject(), newScope, currentScope);
+ return JSWithScope::create(vm, exec->lexicalGlobalObject(), currentScope, object);
}
EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedProto)
Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (220777 => 220778)
--- trunk/Source/_javascript_Core/jit/JITOperations.h 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h 2017-08-16 01:10:01 UTC (rev 220778)
@@ -419,7 +419,7 @@
size_t JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, UniquedStringImpl*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationDeleteByValJSResult(ExecState*, EncodedJSValue base, EncodedJSValue target) WTF_INTERNAL;
size_t JIT_OPERATION operationDeleteByVal(ExecState*, EncodedJSValue base, EncodedJSValue target) WTF_INTERNAL;
-JSCell* JIT_OPERATION operationPushWithScope(ExecState*, JSCell* currentScopeCell, EncodedJSValue scopeObject) WTF_INTERNAL;
+JSCell* JIT_OPERATION operationPushWithScope(ExecState*, JSCell* currentScopeCell, EncodedJSValue object) WTF_INTERNAL;
JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
EncodedJSValue JIT_OPERATION operationInstanceOf(ExecState*, EncodedJSValue, EncodedJSValue proto) WTF_INTERNAL;
int32_t JIT_OPERATION operationSizeFrameForForwardArguments(ExecState*, EncodedJSValue arguments, int32_t numUsedStackSlots, int32_t firstVarArgOffset) WTF_INTERNAL;
Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -814,12 +814,12 @@
SLOW_PATH_DECL(slow_path_push_with_scope)
{
BEGIN();
- JSObject* newScope = OP_C(2).jsValue().toObject(exec);
+ JSObject* newScope = OP_C(3).jsValue().toObject(exec);
CHECK_EXCEPTION();
- int scopeReg = pc[3].u.operand;
+ int scopeReg = pc[2].u.operand;
JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
- RETURN(JSWithScope::create(vm, exec->lexicalGlobalObject(), newScope, currentScope));
+ RETURN(JSWithScope::create(vm, exec->lexicalGlobalObject(), currentScope, newScope));
}
SLOW_PATH_DECL(slow_path_resolve_scope_for_hoisting_func_decl_in_eval)
Modified: trunk/Source/_javascript_Core/runtime/Completion.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/runtime/Completion.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/runtime/Completion.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -123,7 +123,7 @@
if (scopeExtensionObject) {
JSScope* ignoredPreviousScope = globalObject->globalScope();
- globalObject->setGlobalScopeExtension(JSWithScope::create(exec->vm(), globalObject, scopeExtensionObject, ignoredPreviousScope));
+ globalObject->setGlobalScopeExtension(JSWithScope::create(exec->vm(), globalObject, ignoredPreviousScope, scopeExtensionObject));
}
JSValue returnValue = JSC::evaluate(globalObject->globalExec(), source, globalObject, returnedException);
Modified: trunk/Source/_javascript_Core/runtime/JSWithScope.cpp (220777 => 220778)
--- trunk/Source/_javascript_Core/runtime/JSWithScope.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/runtime/JSWithScope.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -33,7 +33,7 @@
const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWithScope) };
JSWithScope* JSWithScope::create(
- VM& vm, JSGlobalObject* globalObject, JSObject* object, JSScope* next)
+ VM& vm, JSGlobalObject* globalObject, JSScope* next, JSObject* object)
{
Structure* structure = globalObject->withScopeStructure();
JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(vm.heap)) JSWithScope(vm, structure, object, next);
Modified: trunk/Source/_javascript_Core/runtime/JSWithScope.h (220777 => 220778)
--- trunk/Source/_javascript_Core/runtime/JSWithScope.h 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/_javascript_Core/runtime/JSWithScope.h 2017-08-16 01:10:01 UTC (rev 220778)
@@ -33,7 +33,7 @@
public:
typedef JSScope Base;
- JS_EXPORT_PRIVATE static JSWithScope* create(VM&, JSGlobalObject*, JSObject*, JSScope* next);
+ JS_EXPORT_PRIVATE static JSWithScope* create(VM&, JSGlobalObject*, JSScope* next, JSObject*);
JSObject* object() { return m_object.get(); }
Modified: trunk/Source/WebCore/ChangeLog (220777 => 220778)
--- trunk/Source/WebCore/ChangeLog 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/WebCore/ChangeLog 2017-08-16 01:10:01 UTC (rev 220778)
@@ -1,3 +1,15 @@
+2017-08-15 Robin Morisset <[email protected]>
+
+ Change the order of arguments of JSWithScope::create() for consistency
+ https://bugs.webkit.org/show_bug.cgi?id=175585
+
+ Reviewed by Saam Barati.
+
+ No change of behavior.
+
+ * bindings/js/JSHTMLElementCustom.cpp:
+ (WebCore::JSHTMLElement::pushEventHandlerScope const):
+
2017-08-15 Youenn Fablet <[email protected]>
[Cache API] Ensure ResourceResponse is not null when redirected/tainting/type fields are set
Modified: trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp (220777 => 220778)
--- trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp 2017-08-16 00:03:45 UTC (rev 220777)
+++ trunk/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp 2017-08-16 01:10:01 UTC (rev 220778)
@@ -120,14 +120,14 @@
VM& vm = exec->vm();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- scope = JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), element.document())), scope);
+ scope = JSWithScope::create(vm, lexicalGlobalObject, scope, asObject(toJS(exec, globalObject(), element.document())));
// The form is next, searched before the document, but after the element itself.
if (HTMLFormElement* form = element.form())
- scope = JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), *form)), scope);
+ scope = JSWithScope::create(vm, lexicalGlobalObject, scope, asObject(toJS(exec, globalObject(), *form)));
// The element is on top, searched first.
- return JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), element)), scope);
+ return JSWithScope::create(vm, lexicalGlobalObject, scope, asObject(toJS(exec, globalObject(), element)));
}
} // namespace WebCore