Skip to content

Commit 6c2c8a7

Browse files
committed
[MERGE #5288 @boingoing] OS#17530048 - AssertMsg(i < this->Length(), "index out of bound") -- Chakra!BVFixed::AssertRange
Merge pull request #5288 from boingoing:correct_functioncount_bytecode Function count saved in the serialized bytecode is computed based on the total number of functions we visit and add to the bytecode. It is possible, though, for us to have a higher function id after defer parsing due to the reparse scenario we have for lambda argument lists. We avoid lambda parameter reparse when using the parser state cache except in the presence of default arguments. So serializing and running bytecode containing a lambda function with a default argument containing another function will increment the next function id to be greater than the size of the startup functions array in SourceDynamicProfileManager which will hit this assert. Example: ```js (a = () => 1) => 2; (function(){})(); // <-- function id of this function is equal to the size of startupFunctions array ``` Fix by serializing the function count from the source info instead of counting the functions we add to the bytecode one-by-one. Fixes: https://microsoft.visualstudio.com/_workitems/edit/17530048 https://microsoft.visualstudio.com/_workitems/edit/17529917
2 parents bf73152 + 5169255 commit 6c2c8a7

File tree

5 files changed

+283
-271
lines changed

5 files changed

+283
-271
lines changed

lib/Jsrt/Jsrt.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3756,6 +3756,7 @@ JsErrorCode JsSerializeScriptCore(const byte *script, size_t cb,
37563756

37573757
SourceContextInfo * sourceContextInfo = scriptContext->GetSourceContextInfo(JS_SOURCE_CONTEXT_NONE, nullptr);
37583758
Assert(sourceContextInfo != nullptr);
3759+
sourceContextInfo->nextLocalFunctionId = 0;
37593760

37603761
const int chsize = (loadScriptFlag & LoadScriptFlag_Utf8Source) ? sizeof(utf8char_t) : sizeof(WCHAR);
37613762
SRCINFO si = {
@@ -5536,6 +5537,7 @@ CHAKRA_API JsSerializeParserStateCore(
55365537

55375538
SourceContextInfo * sourceContextInfo = scriptContext->GetSourceContextInfo(JS_SOURCE_CONTEXT_NONE, nullptr);
55385539
Assert(sourceContextInfo != nullptr);
5540+
sourceContextInfo->nextLocalFunctionId = 0;
55395541

55405542
const int chsize = (loadScriptFlag & LoadScriptFlag_Utf8Source) ?
55415543
sizeof(utf8char_t) : sizeof(WCHAR);

lib/Runtime/ByteCode/ByteCodeSerializer.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,9 +2378,6 @@ class ByteCodeBufferBuilder
23782378
#endif
23792379
}
23802380

2381-
// Increment the function count
2382-
++functionCount.value;
2383-
23842381
// Reverse to put prepended items in correct order
23852382
builder.list = builder.list->ReverseCurrentList();
23862383
PrependStruct<SerializedFieldList>(builder, _u("Serialized Field List"), &definedFields);
@@ -2391,6 +2388,7 @@ class ByteCodeBufferBuilder
23912388
HRESULT AddTopFunctionBody(FunctionBody * function, SRCINFO const * srcInfo, ByteCodeCache* cache)
23922389
{
23932390
topFunctionId = function->GetLocalFunctionId();
2391+
functionCount.value = srcInfo->sourceContextInfo->nextLocalFunctionId;
23942392
return AddFunction(functionsTable, function, srcInfo, cache);
23952393
}
23962394

@@ -2576,9 +2574,6 @@ class ByteCodeBufferBuilder
25762574
{
25772575
AddDeferredStubs(builder, currentStub->deferredStubs, currentStub->nestedCount, cache, recursive);
25782576
}
2579-
2580-
// Each deferred stub will turn into a function after we defer-parse the parent of the stub.
2581-
++functionCount.value;
25822577
}
25832578

25842579
return S_OK;

0 commit comments

Comments
 (0)