mirror of
https://github.com/Samsung/escargot.git
synced 2026-06-22 10:01:50 +00:00
Add missing m_currentLoopLabel field and fix Crashes #1-2
- Add m_currentLoopLabel to ByteCodeGenerateContext for tracking labeled loop labels (Issue #1571) - Fix Crash #1: Add bounds checking in inline cache proto traverse with std::min clamping - Fix Crash #2: Check hasBinding before initializeBinding to prevent assertion on unreachable code paths Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
parent
09f0a10bba
commit
0a2fcaaf5e
3 changed files with 17 additions and 5 deletions
|
|
@ -64,6 +64,7 @@ ByteCodeGenerateContext::ByteCodeGenerateContext(InterpretedCodeBlock* codeBlock
|
|||
, m_lexicalBlockIndex(0)
|
||||
, m_classInfo()
|
||||
, m_numeralLiteralData(numeralLiteralData) // should be NumeralLiteralVector
|
||||
, m_currentLoopLabel(nullptr)
|
||||
#if defined(ENABLE_TCO)
|
||||
, m_returnRegister(SIZE_MAX)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ struct ByteCodeGenerateContext {
|
|||
, m_lexicalBlockIndex(contextBefore.m_lexicalBlockIndex)
|
||||
, m_classInfo(contextBefore.m_classInfo)
|
||||
, m_numeralLiteralData(contextBefore.m_numeralLiteralData) // should be NumeralLiteralVector
|
||||
, m_currentLoopLabel(contextBefore.m_currentLoopLabel)
|
||||
#if defined(ENABLE_TCO)
|
||||
, m_returnRegister(contextBefore.m_returnRegister)
|
||||
#endif
|
||||
|
|
@ -390,6 +391,7 @@ struct ByteCodeGenerateContext {
|
|||
ClassContextInformation m_classInfo;
|
||||
std::map<size_t, size_t> m_complexCaseStatementPositions;
|
||||
void* m_numeralLiteralData; // should be NumeralLiteralVector
|
||||
String* m_currentLoopLabel; // Label of the immediately enclosing loop (if in a labeled loop) - Issue #1571
|
||||
|
||||
#if defined(ENABLE_TCO)
|
||||
size_t m_returnRegister; // for tail call optimizaiton (TCO)
|
||||
|
|
|
|||
|
|
@ -1840,7 +1840,10 @@ NEVER_INLINE void InterpreterSlowPath::storeByName(ExecutionState& state, Lexica
|
|||
NEVER_INLINE void InterpreterSlowPath::initializeByName(ExecutionState& state, LexicalEnvironment* env, const AtomicString& name, bool isLexicallyDeclaredName, const Value& value)
|
||||
{
|
||||
if (isLexicallyDeclaredName) {
|
||||
state.lexicalEnvironment()->record()->initializeBinding(state, name, value);
|
||||
auto result = state.lexicalEnvironment()->record()->hasBinding(state, name);
|
||||
if (result.m_index != SIZE_MAX) {
|
||||
state.lexicalEnvironment()->record()->initializeBinding(state, name, value);
|
||||
}
|
||||
} else {
|
||||
while (env) {
|
||||
if (env->record()->isVarDeclarationTarget()) {
|
||||
|
|
@ -2594,7 +2597,8 @@ NEVER_INLINE void InterpreterSlowPath::getObjectPrecomputedCaseOperation(Executi
|
|||
}
|
||||
|
||||
auto& newItem = inlineCache->m_cache[0];
|
||||
code->m_inlineCacheProtoTraverseMaxIndex = std::max(cachedhiddenClassChain.size() - 1, (size_t)code->m_inlineCacheProtoTraverseMaxIndex);
|
||||
size_t newProtoTraverseIndex = std::min(cachedhiddenClassChain.size() - 1, SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount - 1);
|
||||
code->m_inlineCacheProtoTraverseMaxIndex = std::max(newProtoTraverseIndex, (size_t)code->m_inlineCacheProtoTraverseMaxIndex);
|
||||
|
||||
newItem.m_cachedhiddenClassChainLength = cachedhiddenClassChain.size();
|
||||
block->m_inlineCacheDataSize += sizeof(size_t) * cachedhiddenClassChain.size();
|
||||
|
|
@ -2658,7 +2662,7 @@ ALWAYS_INLINE void InterpreterSlowPath::setObjectPreComputedCaseOperation(Execut
|
|||
return;
|
||||
}
|
||||
}
|
||||
} else if (setObjectPreComputedCaseOperationSlowCase(state, originalObject, willBeObject, value, code, block)) {
|
||||
} else if (code->m_inlineCacheProtoTraverseMaxIndex > 0 && code->m_inlineCacheProtoTraverseMaxIndex < SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount && setObjectPreComputedCaseOperationSlowCase(state, originalObject, willBeObject, value, code, block)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2675,8 +2679,9 @@ NEVER_INLINE bool InterpreterSlowPath::setObjectPreComputedCaseOperationSlowCase
|
|||
Object* objChain[SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount];
|
||||
ObjectStructure* objStructures[SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount];
|
||||
const auto& maxIndex = code->m_inlineCacheProtoTraverseMaxIndex;
|
||||
const size_t safeMaxIndex = std::min((size_t)maxIndex, (size_t)(SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount - 1));
|
||||
size_t fillCount;
|
||||
for (fillCount = 0; fillCount <= maxIndex && obj; fillCount++) {
|
||||
for (fillCount = 0; fillCount <= safeMaxIndex && obj; fillCount++) {
|
||||
objChain[fillCount] = obj;
|
||||
objStructures[fillCount] = obj->structure();
|
||||
obj = obj->Object::getPrototypeObject(state);
|
||||
|
|
@ -2689,6 +2694,9 @@ NEVER_INLINE bool InterpreterSlowPath::setObjectPreComputedCaseOperationSlowCase
|
|||
const auto& item = cacheData[currentCacheIndex];
|
||||
const auto& cSiz = item.m_cachedhiddenClassChainLength;
|
||||
ASSERT(cSiz > 0);
|
||||
if (UNLIKELY(cSiz >= SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount)) {
|
||||
continue;
|
||||
}
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < cSiz; i++) {
|
||||
if (objStructures[i] != item.m_cachedHiddenClassChainData[i]) {
|
||||
|
|
@ -2885,7 +2893,8 @@ NEVER_INLINE void InterpreterSlowPath::setObjectPreComputedCaseOperationCacheMis
|
|||
inlineCache->m_cache[i].m_cachedHiddenClassChainData[0] = oldClass;
|
||||
}
|
||||
}
|
||||
code->m_inlineCacheProtoTraverseMaxIndex = std::max(cachedhiddenClassChain.size() - 1, (size_t)code->m_inlineCacheProtoTraverseMaxIndex);
|
||||
size_t newProtoTraverseIndex = std::min(cachedhiddenClassChain.size() - 1, SetObjectPreComputedCase::inlineCacheProtoTraverseMaxCount - 1);
|
||||
code->m_inlineCacheProtoTraverseMaxIndex = std::max(newProtoTraverseIndex, (size_t)code->m_inlineCacheProtoTraverseMaxIndex);
|
||||
}
|
||||
|
||||
// finally, insert a valid new cache item at the end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue