|
Lines 48-53
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec1
|
| 48 |
#include "Options.h" |
48 |
#include "Options.h" |
| 49 |
#include "PrivateFieldPutKind.h" |
49 |
#include "PrivateFieldPutKind.h" |
| 50 |
#include "StrongInlines.h" |
50 |
#include "StrongInlines.h" |
|
|
51 |
#include "SuperSampler.h" |
| 51 |
#include "UnlinkedCodeBlock.h" |
52 |
#include "UnlinkedCodeBlock.h" |
| 52 |
#include "UnlinkedEvalCodeBlock.h" |
53 |
#include "UnlinkedEvalCodeBlock.h" |
| 53 |
#include "UnlinkedFunctionCodeBlock.h" |
54 |
#include "UnlinkedFunctionCodeBlock.h" |
|
Lines 300-306
BytecodeGenerator::BytecodeGenerator(VM&
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec2
|
| 300 |
, m_isBuiltinFunction(false) |
301 |
, m_isBuiltinFunction(false) |
| 301 |
, m_usesNonStrictEval(false) |
302 |
, m_usesNonStrictEval(false) |
| 302 |
, m_inTailPosition(false) |
303 |
, m_inTailPosition(false) |
| 303 |
, m_hasCachedVariablesUnderTDZ(false) |
|
|
| 304 |
, m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval()) |
304 |
, m_needsToUpdateArrowFunctionContext(programNode->usesArrowFunction() || programNode->usesEval()) |
| 305 |
, m_ecmaMode(ecmaMode) |
305 |
, m_ecmaMode(ecmaMode) |
| 306 |
{ |
306 |
{ |
|
Lines 355-361
BytecodeGenerator::BytecodeGenerator(VM&
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec3
|
| 355 |
// |
355 |
// |
| 356 |
// Note that we intentionally enable tail call for naked constructors since it does not have special code for "return". |
356 |
// Note that we intentionally enable tail call for naked constructors since it does not have special code for "return". |
| 357 |
, m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && ecmaMode.isStrict()) |
357 |
, m_inTailPosition(Options::useTailCalls() && !isConstructor() && constructorKind() == ConstructorKind::None && ecmaMode.isStrict()) |
| 358 |
, m_hasCachedVariablesUnderTDZ(false) |
|
|
| 359 |
, m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval()) |
358 |
, m_needsToUpdateArrowFunctionContext(functionNode->usesArrowFunction() || functionNode->usesEval()) |
| 360 |
, m_ecmaMode(ecmaMode) |
359 |
, m_ecmaMode(ecmaMode) |
| 361 |
, m_derivedContextType(codeBlock->derivedContextType()) |
360 |
, m_derivedContextType(codeBlock->derivedContextType()) |
|
Lines 852-858
BytecodeGenerator::BytecodeGenerator(VM&
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec4
|
| 852 |
, m_isBuiltinFunction(false) |
851 |
, m_isBuiltinFunction(false) |
| 853 |
, m_usesNonStrictEval(codeBlock->usesEval() && !ecmaMode.isStrict()) |
852 |
, m_usesNonStrictEval(codeBlock->usesEval() && !ecmaMode.isStrict()) |
| 854 |
, m_inTailPosition(false) |
853 |
, m_inTailPosition(false) |
| 855 |
, m_hasCachedVariablesUnderTDZ(false) |
|
|
| 856 |
, m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval()) |
854 |
, m_needsToUpdateArrowFunctionContext(evalNode->usesArrowFunction() || evalNode->usesEval()) |
| 857 |
, m_ecmaMode(ecmaMode) |
855 |
, m_ecmaMode(ecmaMode) |
| 858 |
, m_derivedContextType(codeBlock->derivedContextType()) |
856 |
, m_derivedContextType(codeBlock->derivedContextType()) |
|
Lines 916-922
BytecodeGenerator::BytecodeGenerator(VM&
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec5
|
| 916 |
, m_isBuiltinFunction(false) |
914 |
, m_isBuiltinFunction(false) |
| 917 |
, m_usesNonStrictEval(false) |
915 |
, m_usesNonStrictEval(false) |
| 918 |
, m_inTailPosition(false) |
916 |
, m_inTailPosition(false) |
| 919 |
, m_hasCachedVariablesUnderTDZ(false) |
|
|
| 920 |
, m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval()) |
917 |
, m_needsToUpdateArrowFunctionContext(moduleProgramNode->usesArrowFunction() || moduleProgramNode->usesEval()) |
| 921 |
, m_ecmaMode(ecmaMode) |
918 |
, m_ecmaMode(ecmaMode) |
| 922 |
{ |
919 |
{ |
|
Lines 2170-2176
void BytecodeGenerator::popLexicalScopeI
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec6
|
| 2170 |
} |
2167 |
} |
| 2171 |
|
2168 |
|
| 2172 |
m_TDZStack.removeLast(); |
2169 |
m_TDZStack.removeLast(); |
| 2173 |
m_cachedVariablesUnderTDZ = { }; |
2170 |
m_cachedVariablesUnderTDZ.removeLast(); |
| 2174 |
} |
2171 |
} |
| 2175 |
|
2172 |
|
| 2176 |
void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode* node, RegisterID* loopSymbolTable) |
2173 |
void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode* node, RegisterID* loopSymbolTable) |
|
Lines 2880-2889
void BytecodeGenerator::liftTDZCheckIfPo
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec7
|
| 2880 |
for (unsigned i = m_TDZStack.size(); i--;) { |
2877 |
for (unsigned i = m_TDZStack.size(); i--;) { |
| 2881 |
auto iter = m_TDZStack[i].find(identifier); |
2878 |
auto iter = m_TDZStack[i].find(identifier); |
| 2882 |
if (iter != m_TDZStack[i].end()) { |
2879 |
if (iter != m_TDZStack[i].end()) { |
| 2883 |
if (iter->value == TDZNecessityLevel::Optimize) { |
2880 |
if (iter->value == TDZNecessityLevel::Optimize) |
| 2884 |
m_cachedVariablesUnderTDZ = { }; |
|
|
| 2885 |
iter->value = TDZNecessityLevel::NotNeeded; |
2881 |
iter->value = TDZNecessityLevel::NotNeeded; |
| 2886 |
} |
|
|
| 2887 |
break; |
2882 |
break; |
| 2888 |
} |
2883 |
} |
| 2889 |
} |
2884 |
} |
|
Lines 2908-2966
void BytecodeGenerator::pushTDZVariables
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec8
|
| 2908 |
map.add(entry.key, entry.value.isFunction() ? TDZNecessityLevel::NotNeeded : level); |
2903 |
map.add(entry.key, entry.value.isFunction() ? TDZNecessityLevel::NotNeeded : level); |
| 2909 |
|
2904 |
|
| 2910 |
m_TDZStack.append(WTFMove(map)); |
2905 |
m_TDZStack.append(WTFMove(map)); |
| 2911 |
m_cachedVariablesUnderTDZ = { }; |
2906 |
m_cachedVariablesUnderTDZ.append({ }); |
| 2912 |
} |
2907 |
} |
| 2913 |
|
2908 |
|
| 2914 |
Optional<CompactVariableMap::Handle> BytecodeGenerator::getVariablesUnderTDZ() |
2909 |
Optional<BytecodeGenerator::CachedTDZStack> BytecodeGenerator::getVariablesUnderTDZ() |
| 2915 |
{ |
2910 |
{ |
| 2916 |
if (m_cachedVariablesUnderTDZ) { |
2911 |
SuperSamplerScope superSamplerScope(false); |
| 2917 |
if (!m_hasCachedVariablesUnderTDZ) { |
2912 |
|
| 2918 |
ASSERT(m_cachedVariablesUnderTDZ.environment().toVariableEnvironment().isEmpty()); |
2913 |
auto assertCacheIsCoherent = [&] { |
| 2919 |
return WTF::nullopt; |
2914 |
#if ASSERT_ENABLED |
| 2920 |
} |
2915 |
for (size_t i = 0; i < m_cachedVariablesUnderTDZ.size(); ++i) |
|
|
2916 |
ASSERT(!!m_cachedVariablesUnderTDZ[i]); |
| 2917 |
#endif |
| 2918 |
}; |
| 2919 |
|
| 2920 |
RELEASE_ASSERT(m_TDZStack.size() == m_cachedVariablesUnderTDZ.size()); |
| 2921 |
|
| 2922 |
if (m_cachedVariablesUnderTDZ.isEmpty()) |
| 2923 |
return WTF::nullopt; |
| 2924 |
|
| 2925 |
if (m_cachedVariablesUnderTDZ.last()) { |
| 2926 |
assertCacheIsCoherent(); |
| 2921 |
return m_cachedVariablesUnderTDZ; |
2927 |
return m_cachedVariablesUnderTDZ; |
| 2922 |
} |
2928 |
} |
| 2923 |
|
2929 |
|
| 2924 |
// We keep track of variablesThatDontNeedTDZ in this algorithm to prevent |
2930 |
for (size_t i = m_TDZStack.size(); i--;) { |
| 2925 |
// reporting that "x" is under TDZ if this function is called at "...". |
2931 |
if (m_cachedVariablesUnderTDZ[i]) |
| 2926 |
// |
2932 |
break; |
| 2927 |
// { |
2933 |
|
| 2928 |
// { |
|
|
| 2929 |
// let x; |
| 2930 |
// ... |
| 2931 |
// } |
| 2932 |
// let x; |
| 2933 |
// } |
| 2934 |
SmallPtrSet<UniquedStringImpl*, 16> variablesThatDontNeedTDZ; |
| 2935 |
VariableEnvironment environment; |
| 2936 |
for (unsigned i = m_TDZStack.size(); i--; ) { |
| 2937 |
auto& map = m_TDZStack[i]; |
2934 |
auto& map = m_TDZStack[i]; |
| 2938 |
for (auto& entry : map) { |
2935 |
VariableEnvironment environment; |
| 2939 |
if (entry.value != TDZNecessityLevel::NotNeeded) { |
2936 |
for (auto& entry : map) { |
| 2940 |
if (!variablesThatDontNeedTDZ.contains(entry.key.get())) |
2937 |
if (entry.value != TDZNecessityLevel::NotNeeded) |
| 2941 |
environment.add(entry.key.get()); |
2938 |
environment.add(entry.key.get()); |
| 2942 |
} else |
|
|
| 2943 |
variablesThatDontNeedTDZ.add(entry.key.get()); |
| 2944 |
} |
2939 |
} |
|
|
2940 |
m_cachedVariablesUnderTDZ[i] = m_vm.m_compactVariableMap->get(environment); |
| 2945 |
} |
2941 |
} |
| 2946 |
|
2942 |
|
| 2947 |
m_cachedVariablesUnderTDZ = m_vm.m_compactVariableMap->get(environment); |
2943 |
assertCacheIsCoherent(); |
| 2948 |
m_hasCachedVariablesUnderTDZ = !environment.isEmpty(); |
|
|
| 2949 |
if (!m_hasCachedVariablesUnderTDZ) |
| 2950 |
return WTF::nullopt; |
| 2951 |
|
| 2952 |
return m_cachedVariablesUnderTDZ; |
2944 |
return m_cachedVariablesUnderTDZ; |
| 2953 |
} |
2945 |
} |
| 2954 |
|
2946 |
|
| 2955 |
void BytecodeGenerator::preserveTDZStack(BytecodeGenerator::PreservedTDZStack& preservedStack) |
2947 |
void BytecodeGenerator::preserveTDZStack(BytecodeGenerator::PreservedTDZStack& preservedStack) |
| 2956 |
{ |
2948 |
{ |
| 2957 |
preservedStack.m_preservedTDZStack = m_TDZStack; |
2949 |
preservedStack.m_preservedTDZStack = m_TDZStack; |
|
|
2950 |
preservedStack.m_cachedTDZStack = m_cachedVariablesUnderTDZ; |
| 2958 |
} |
2951 |
} |
| 2959 |
|
2952 |
|
| 2960 |
void BytecodeGenerator::restoreTDZStack(const BytecodeGenerator::PreservedTDZStack& preservedStack) |
2953 |
void BytecodeGenerator::restoreTDZStack(const BytecodeGenerator::PreservedTDZStack& preservedStack) |
| 2961 |
{ |
2954 |
{ |
| 2962 |
m_TDZStack = preservedStack.m_preservedTDZStack; |
2955 |
m_TDZStack = preservedStack.m_preservedTDZStack; |
| 2963 |
m_cachedVariablesUnderTDZ = { }; |
2956 |
m_cachedVariablesUnderTDZ = preservedStack.m_cachedTDZStack; |
| 2964 |
} |
2957 |
} |
| 2965 |
|
2958 |
|
| 2966 |
RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst) |
2959 |
RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst) |
|
Lines 3147-3153
RegisterID* BytecodeGenerator::emitNewIn
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec9
|
| 3147 |
superBinding = SuperBinding::Needed; |
3140 |
superBinding = SuperBinding::Needed; |
| 3148 |
} |
3141 |
} |
| 3149 |
|
3142 |
|
| 3150 |
Optional<CompactVariableMap::Handle> variablesUnderTDZ = getVariablesUnderTDZ(); |
3143 |
auto variablesUnderTDZ = getVariablesUnderTDZ(); |
| 3151 |
SourceParseMode parseMode = SourceParseMode::InstanceFieldInitializerMode; |
3144 |
SourceParseMode parseMode = SourceParseMode::InstanceFieldInitializerMode; |
| 3152 |
ConstructAbility constructAbility = ConstructAbility::CannotConstruct; |
3145 |
ConstructAbility constructAbility = ConstructAbility::CannotConstruct; |
| 3153 |
|
3146 |
|