- Revision
- 232219
- Author
- mark....@apple.com
- Date
- 2018-05-25 17:23:57 -0700 (Fri, 25 May 2018)
Log Message
for-in loops should preserve and restore the TDZ stack for each of its internal loops.
https://bugs.webkit.org/show_bug.cgi?id=185995
<rdar://problem/40173142>
Reviewed by Saam Barati.
JSTests:
* stress/regress-185995.js: Added.
Source/_javascript_Core:
This is because there's no guarantee that any of the loop bodies will be
executed. Hence, there's no guarantee that the TDZ variables will have been
initialized after each loop body.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::preserveTDZStack):
(JSC::BytecodeGenerator::restoreTDZStack):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ForInNode::emitBytecode):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (232218 => 232219)
--- trunk/JSTests/ChangeLog 2018-05-26 00:13:43 UTC (rev 232218)
+++ trunk/JSTests/ChangeLog 2018-05-26 00:23:57 UTC (rev 232219)
@@ -1,3 +1,13 @@
+2018-05-25 Mark Lam <mark....@apple.com>
+
+ for-in loops should preserve and restore the TDZ stack for each of its internal loops.
+ https://bugs.webkit.org/show_bug.cgi?id=185995
+ <rdar://problem/40173142>
+
+ Reviewed by Saam Barati.
+
+ * stress/regress-185995.js: Added.
+
2018-05-23 Keith Miller <keith_mil...@apple.com>
Define length on CoW array should properly convert to writable
Added: trunk/JSTests/stress/regress-185995.js (0 => 232219)
--- trunk/JSTests/stress/regress-185995.js (rev 0)
+++ trunk/JSTests/stress/regress-185995.js 2018-05-26 00:23:57 UTC (rev 232219)
@@ -0,0 +1,13 @@
+(function() {
+ var exception;
+ try {
+ var list = { 'a' : 5 };
+ for(const { x = x } in list)
+ x();
+ } catch (e) {
+ exception = e;
+ }
+
+ if (exception != "ReferenceError: Cannot access uninitialized variable.")
+ throw "FAILED";
+})();
Modified: trunk/Source/_javascript_Core/ChangeLog (232218 => 232219)
--- trunk/Source/_javascript_Core/ChangeLog 2018-05-26 00:13:43 UTC (rev 232218)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-05-26 00:23:57 UTC (rev 232219)
@@ -1,5 +1,24 @@
2018-05-25 Mark Lam <mark....@apple.com>
+ for-in loops should preserve and restore the TDZ stack for each of its internal loops.
+ https://bugs.webkit.org/show_bug.cgi?id=185995
+ <rdar://problem/40173142>
+
+ Reviewed by Saam Barati.
+
+ This is because there's no guarantee that any of the loop bodies will be
+ executed. Hence, there's no guarantee that the TDZ variables will have been
+ initialized after each loop body.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::preserveTDZStack):
+ (JSC::BytecodeGenerator::restoreTDZStack):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ForInNode::emitBytecode):
+
+2018-05-25 Mark Lam <mark....@apple.com>
+
MachineContext's instructionPointer() should handle null PCs correctly.
https://bugs.webkit.org/show_bug.cgi?id=186004
<rdar://problem/40570067>
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (232218 => 232219)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2018-05-26 00:13:43 UTC (rev 232218)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2018-05-26 00:23:57 UTC (rev 232219)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwar...@uwaterloo.ca>
* Copyright (C) 2012 Igalia, S.L.
*
@@ -3139,6 +3139,16 @@
}
}
+void BytecodeGenerator::preserveTDZStack(BytecodeGenerator::PreservedTDZStack& preservedStack)
+{
+ preservedStack.m_preservedTDZStack = m_TDZStack;
+}
+
+void BytecodeGenerator::restoreTDZStack(const BytecodeGenerator::PreservedTDZStack& preservedStack)
+{
+ m_TDZStack = preservedStack.m_preservedTDZStack;
+}
+
RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
{
size_t begin = instructions().size();
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (232218 => 232219)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2018-05-26 00:13:43 UTC (rev 232218)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2018-05-26 00:23:57 UTC (rev 232219)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwar...@uwaterloo.ca>
* Copyright (C) 2012 Igalia, S.L.
*
@@ -1113,6 +1113,13 @@
void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable = nullptr, bool canReuseLexicalEnvironment = false);
bool needsDerivedConstructorInArrowFunctionLexicalEnvironment();
+ enum class TDZNecessityLevel {
+ NotNeeded,
+ Optimize,
+ DoNotOptimize
+ };
+ typedef HashMap<RefPtr<UniquedStringImpl>, TDZNecessityLevel, IdentifierRepHash> TDZMap;
+
public:
JSString* addStringConstant(const Identifier&);
JSValue addBigIntConstant(const Identifier&, uint8_t radix);
@@ -1122,6 +1129,15 @@
RegisterID* emitThrowExpressionTooDeepException();
+ class PreservedTDZStack {
+ private:
+ Vector<TDZMap> m_preservedTDZStack;
+ friend class BytecodeGenerator;
+ };
+
+ void preserveTDZStack(PreservedTDZStack&);
+ void restoreTDZStack(const PreservedTDZStack&);
+
private:
Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow> m_instructions;
@@ -1134,12 +1150,7 @@
int m_symbolTableConstantIndex;
};
Vector<LexicalScopeStackEntry> m_lexicalScopeStack;
- enum class TDZNecessityLevel {
- NotNeeded,
- Optimize,
- DoNotOptimize
- };
- typedef HashMap<RefPtr<UniquedStringImpl>, TDZNecessityLevel, IdentifierRepHash> TDZMap;
+
Vector<TDZMap> m_TDZStack;
std::optional<size_t> m_varScopeLexicalScopeStackIndex;
void pushTDZVariables(const VariableEnvironment&, TDZCheckOptimization, TDZRequirement);
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (232218 => 232219)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2018-05-26 00:13:43 UTC (rev 232218)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2018-05-26 00:23:57 UTC (rev 232219)
@@ -3075,6 +3075,9 @@
enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
+ BytecodeGenerator::PreservedTDZStack preservedTDZStack;
+ generator.preserveTDZStack(preservedTDZStack);
+
// Indexed property loop.
{
Ref<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
@@ -3114,6 +3117,7 @@
generator.emitJump(end.get());
generator.emitLabel(loopEnd.get());
}
+ generator.restoreTDZStack(preservedTDZStack);
// Structure property loop.
{
@@ -3154,6 +3158,7 @@
generator.emitJump(end.get());
generator.emitLabel(loopEnd.get());
}
+ generator.restoreTDZStack(preservedTDZStack);
// Generic property loop.
{