Modified: trunk/JSTests/ChangeLog (219208 => 219209)
--- trunk/JSTests/ChangeLog 2017-07-06 18:35:58 UTC (rev 219208)
+++ trunk/JSTests/ChangeLog 2017-07-06 18:43:41 UTC (rev 219209)
@@ -1,3 +1,14 @@
+2017-07-06 Saam Barati <sbar...@apple.com>
+
+ We are missing places where we invalidate the for-in context
+ https://bugs.webkit.org/show_bug.cgi?id=174184
+
+ Reviewed by Geoffrey Garen.
+
+ * stress/for-in-invalidate-context-weird-assignments.js: Added.
+ (assert):
+ (test):
+
2017-07-05 Saam Barati <sbar...@apple.com>
NewArray in FTLLowerDFGToB3 does not handle speculating on doubles when having a bad time
Added: trunk/JSTests/stress/for-in-invalidate-context-weird-assignments.js (0 => 219209)
--- trunk/JSTests/stress/for-in-invalidate-context-weird-assignments.js (rev 0)
+++ trunk/JSTests/stress/for-in-invalidate-context-weird-assignments.js 2017-07-06 18:43:41 UTC (rev 219209)
@@ -0,0 +1,82 @@
+function assert(b) {
+ if (!b)
+ throw new Error("Bad");
+}
+
+function test(f) {
+ noInline(f);
+ for (let i = 0; i < 1000; ++i)
+ f();
+}
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ for (i in [0, 1, 2]) { }
+ assert(typeof i === "string");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ for (var i of [0]) { }
+ assert(typeof i === "number");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ for ({i} of [{i: 0}]) { }
+ assert(typeof i === "number");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ ;({i} = {i: 0});
+ assert(typeof i === "number");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ ;([i] = [0]);
+ assert(typeof i === "number");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ ;({...i} = {a:20, b:30});
+ assert(typeof i === "object");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ eval("i = 0;");
+ assert(typeof i === "number");
+ assert(o[i] === undefined);
+ }
+});
+
+test(function() {
+ let o = {xx: 0};
+ for (let i in o) {
+ var i = 0;
+ assert(typeof i === "number");
+ assert(o[i] === undefined);
+ }
+});
Modified: trunk/Source/_javascript_Core/ChangeLog (219208 => 219209)
--- trunk/Source/_javascript_Core/ChangeLog 2017-07-06 18:35:58 UTC (rev 219208)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-07-06 18:43:41 UTC (rev 219209)
@@ -1,3 +1,18 @@
+2017-07-06 Saam Barati <sbar...@apple.com>
+
+ We are missing places where we invalidate the for-in context
+ https://bugs.webkit.org/show_bug.cgi?id=174184
+
+ Reviewed by Geoffrey Garen.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::invalidateForInContextForLocal):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::EmptyLetExpression::emitBytecode):
+ (JSC::ForInNode::emitLoopHeader):
+ (JSC::ForOfNode::emitBytecode):
+ (JSC::BindingNode::bindValue):
+
2017-07-06 Yusuke Suzuki <utatane....@gmail.com>
Unreviewed, suppress warnings in GCC environment
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (219208 => 219209)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-07-06 18:35:58 UTC (rev 219208)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2017-07-06 18:43:41 UTC (rev 219209)
@@ -4710,10 +4710,8 @@
// reassigned from its original value.
for (size_t i = m_forInContextStack.size(); i--; ) {
ForInContext& context = m_forInContextStack[i].get();
- if (context.local() != localRegister)
- continue;
- context.invalidate();
- break;
+ if (context.local() == localRegister)
+ context.invalidate();
}
}
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (219208 => 219209)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-07-06 18:35:58 UTC (rev 219208)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2017-07-06 18:43:41 UTC (rev 219209)
@@ -2553,6 +2553,7 @@
Variable var = generator.variable(m_ident);
if (RegisterID* local = var.local()) {
generator.emitLoad(local, jsUndefined());
+ generator.invalidateForInContextForLocal(local);
generator.emitProfileType(local, var, position(), JSTextPosition(-1, position().offset + m_ident.length(), -1));
} else {
RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);
@@ -2746,13 +2747,13 @@
void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName)
{
- auto lambdaEmitResolveVariable = [&](const Identifier& ident)
- {
+ auto lambdaEmitResolveVariable = [&] (const Identifier& ident) {
Variable var = generator.variable(ident);
if (RegisterID* local = var.local()) {
if (var.isReadOnly())
generator.emitReadOnlyExceptionIfNeeded(var);
generator.emitMove(local, propertyName);
+ generator.invalidateForInContextForLocal(local);
} else {
if (generator.isStrictMode())
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
@@ -2820,6 +2821,7 @@
return;
}
generator.emitMove(var.local(), propertyName);
+ generator.invalidateForInContextForLocal(var.local());
generator.emitProfileType(propertyName, var, simpleBinding->divotStart(), simpleBinding->divotEnd());
return;
}
@@ -2999,6 +3001,7 @@
if (var.isReadOnly())
generator.emitReadOnlyExceptionIfNeeded(var);
generator.emitMove(local, value);
+ generator.invalidateForInContextForLocal(local);
} else {
if (generator.isStrictMode())
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
@@ -4145,6 +4148,7 @@
return;
}
generator.emitMove(local, value);
+ generator.invalidateForInContextForLocal(local);
generator.emitProfileType(local, var, divotStart(), divotEnd());
if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
generator.liftTDZCheckIfPossible(var);