Modified: branches/safari-611-branch/JSTests/ChangeLog (278903 => 278904)
--- branches/safari-611-branch/JSTests/ChangeLog 2021-06-15 21:49:35 UTC (rev 278903)
+++ branches/safari-611-branch/JSTests/ChangeLog 2021-06-15 21:49:38 UTC (rev 278904)
@@ -1,5 +1,47 @@
2021-06-15 Alan Coon <alanc...@apple.com>
+ Cherry-pick r278819. rdar://problem/79355258
+
+ https://bugs.webkit.org/show_bug.cgi?id=226576
+ <rdar://problem/78810362>
+
+ Reviewed by Yusuke Suzuki.
+
+ JSTests:
+
+ * stress/short-circuit-read-modify-write-cant-write-dst-before-tdz-check.js: Added.
+ (let.result.eval.try.captureV):
+ (catch):
+
+ Source/_javascript_Core:
+
+ ShortCircuitReadModifyResolveNode can't emit a value into
+ its result until after it emits a TDZ check. We were temporarily
+ storing the result of the get_from_scope into the dst. Then
+ we'd emit the TDZ check. The TDZ check can throw, and it could
+ lead to us returning TDZ from the eval itself. Instead, we need
+ to use a temporary to emit a TDZ check on. Only after the TDZ check
+ passes can we move the temporary into the result.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ShortCircuitReadModifyResolveNode::emitBytecode):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278819 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-06-13 Saam Barati <sbar...@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=226576
+ <rdar://problem/78810362>
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/short-circuit-read-modify-write-cant-write-dst-before-tdz-check.js: Added.
+ (let.result.eval.try.captureV):
+ (catch):
+
+2021-06-15 Alan Coon <alanc...@apple.com>
+
Cherry-pick r278578. rdar://problem/79355258
Short circuit read modify write nodes emit byte code that uses the wrong locals
Added: branches/safari-611-branch/JSTests/stress/short-circuit-read-modify-write-cant-write-dst-before-tdz-check.js (0 => 278904)
--- branches/safari-611-branch/JSTests/stress/short-circuit-read-modify-write-cant-write-dst-before-tdz-check.js (rev 0)
+++ branches/safari-611-branch/JSTests/stress/short-circuit-read-modify-write-cant-write-dst-before-tdz-check.js 2021-06-15 21:49:38 UTC (rev 278904)
@@ -0,0 +1,11 @@
+let result = eval(`
+try {
+ function captureV() { return v; }
+
+ v &&= "abc";
+ let v = var07;
+} catch (e) {
+}
+`);
+if (result !== undefined)
+ throw new Error("Bad result")
Modified: branches/safari-611-branch/Source/_javascript_Core/ChangeLog (278903 => 278904)
--- branches/safari-611-branch/Source/_javascript_Core/ChangeLog 2021-06-15 21:49:35 UTC (rev 278903)
+++ branches/safari-611-branch/Source/_javascript_Core/ChangeLog 2021-06-15 21:49:38 UTC (rev 278904)
@@ -1,5 +1,54 @@
2021-06-15 Alan Coon <alanc...@apple.com>
+ Cherry-pick r278819. rdar://problem/79355258
+
+ https://bugs.webkit.org/show_bug.cgi?id=226576
+ <rdar://problem/78810362>
+
+ Reviewed by Yusuke Suzuki.
+
+ JSTests:
+
+ * stress/short-circuit-read-modify-write-cant-write-dst-before-tdz-check.js: Added.
+ (let.result.eval.try.captureV):
+ (catch):
+
+ Source/_javascript_Core:
+
+ ShortCircuitReadModifyResolveNode can't emit a value into
+ its result until after it emits a TDZ check. We were temporarily
+ storing the result of the get_from_scope into the dst. Then
+ we'd emit the TDZ check. The TDZ check can throw, and it could
+ lead to us returning TDZ from the eval itself. Instead, we need
+ to use a temporary to emit a TDZ check on. Only after the TDZ check
+ passes can we move the temporary into the result.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ShortCircuitReadModifyResolveNode::emitBytecode):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278819 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-06-13 Saam Barati <sbar...@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=226576
+ <rdar://problem/78810362>
+
+ Reviewed by Yusuke Suzuki.
+
+ ShortCircuitReadModifyResolveNode can't emit a value into
+ its result until after it emits a TDZ check. We were temporarily
+ storing the result of the get_from_scope into the dst. Then
+ we'd emit the TDZ check. The TDZ check can throw, and it could
+ lead to us returning TDZ from the eval itself. Instead, we need
+ to use a temporary to emit a TDZ check on. Only after the TDZ check
+ passes can we move the temporary into the result.
+
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ShortCircuitReadModifyResolveNode::emitBytecode):
+
+2021-06-15 Alan Coon <alanc...@apple.com>
+
Cherry-pick r278578. rdar://problem/79355258
Short circuit read modify write nodes emit byte code that uses the wrong locals
Modified: branches/safari-611-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (278903 => 278904)
--- branches/safari-611-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2021-06-15 21:49:35 UTC (rev 278903)
+++ branches/safari-611-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2021-06-15 21:49:38 UTC (rev 278904)
@@ -3250,15 +3250,15 @@
generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
- RefPtr<RegisterID> result = generator.tempDestination(dst);
+ RefPtr<RegisterID> uncheckedResult = generator.newTemporary();
- generator.emitGetFromScope(result.get(), scope.get(), var, ThrowIfNotFound);
- generator.emitTDZCheckIfNecessary(var, result.get(), nullptr);
+ generator.emitGetFromScope(uncheckedResult.get(), scope.get(), var, ThrowIfNotFound);
+ generator.emitTDZCheckIfNecessary(var, uncheckedResult.get(), nullptr);
Ref<Label> afterAssignment = generator.newLabel();
- emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
+ emitShortCircuitAssignment(generator, uncheckedResult.get(), m_operator, afterAssignment.get());
- generator.emitNode(result.get(), m_right); // Execute side effects first.
+ generator.emitNode(uncheckedResult.get(), m_right); // Execute side effects first.
bool threwException = isReadOnly ? generator.emitReadOnlyExceptionIfNeeded(var) : false;
@@ -3266,12 +3266,12 @@
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
if (!isReadOnly) {
- result = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
- generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
+ generator.emitPutToScope(scope.get(), var, uncheckedResult.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
+ generator.emitProfileType(uncheckedResult.get(), var, divotStart(), divotEnd());
}
generator.emitLabel(afterAssignment.get());
- return generator.move(dst, result.get());
+ return generator.move(generator.finalDestination(dst, uncheckedResult.get()), uncheckedResult.get());
}
// ------------------------------ AssignResolveNode -----------------------------------