@@ -328,16 +328,6 @@ namespace Js
328
328
void
329
329
FunctionBody::CopySourceInfo (ParseableFunctionInfo* originalFunctionInfo)
330
330
{
331
- this ->m_sourceIndex = originalFunctionInfo->GetSourceIndex ();
332
- this ->m_cchStartOffset = originalFunctionInfo->StartInDocument ();
333
- this ->m_cchLength = originalFunctionInfo->LengthInChars ();
334
- this ->m_lineNumber = originalFunctionInfo->GetRelativeLineNumber ();
335
- this ->m_columnNumber = originalFunctionInfo->GetRelativeColumnNumber ();
336
- this ->m_isEval = originalFunctionInfo->IsEval ();
337
- this ->m_isDynamicFunction = originalFunctionInfo->IsDynamicFunction ();
338
- this ->m_cbStartOffset = originalFunctionInfo->StartOffset ();
339
- this ->m_cbLength = originalFunctionInfo->LengthInBytes ();
340
-
341
331
this ->FinishSourceInfo ();
342
332
}
343
333
@@ -453,7 +443,6 @@ namespace Js
453
443
loopInterpreterLimit (CONFIG_FLAG(LoopInterpretCount)),
454
444
savedPolymorphicCacheState (0 ),
455
445
debuggerScopeIndex (0 ),
456
- flags (Flags_HasNoExplicitReturnValue),
457
446
m_hasFinally (false ),
458
447
#if ENABLE_PROFILE_INFO
459
448
dynamicProfileInfo (nullptr ),
@@ -564,6 +553,32 @@ namespace Js
564
553
InitDisableInlineSpread ();
565
554
}
566
555
556
+ void FunctionBody::RedeferFunction ()
557
+ {
558
+ Assert (this ->CanBeDeferred ());
559
+ PHASE_PRINT_TRACE (Js::RedeferralPhase, this , L" Redeferring function %d.%d: %s\n " ,
560
+ GetSourceContextId (), GetLocalFunctionId (),
561
+ GetDisplayName () ? GetDisplayName () : L" (Anonymous function)" );
562
+
563
+ ParseableFunctionInfo * parseableFunctionInfo =
564
+ Js::ParseableFunctionInfo::NewDeferredFunctionFromFunctionBody (this );
565
+
566
+ FunctionInfo * functionInfo = this ->GetFunctionInfo ();
567
+ functionInfo->SetAttributes ((FunctionInfo::Attributes)(functionInfo->GetAttributes () | FunctionInfo::Attributes::DeferredParse));
568
+ functionInfo->SetFunctionProxy (parseableFunctionInfo);
569
+
570
+ // In either case register the function reference
571
+ // GetScriptContext()->GetLibrary()->RegisterDynamicFunctionReference(parseableFunctionInfo);
572
+
573
+ this ->MapFunctionObjectTypes ([&](DynamicType* type)
574
+ {
575
+ Assert (type->GetTypeId () == TypeIds_Function);
576
+
577
+ ScriptFunctionType* functionType = (ScriptFunctionType*)type;
578
+ functionType->SetEntryPoint (GetScriptContext ()->DeferredParsingThunk );
579
+ });
580
+ }
581
+
567
582
void FunctionBody::SetDefaultFunctionEntryPointInfo (FunctionEntryPointInfo* entryPointInfo, const JavascriptMethod originalEntryPoint)
568
583
{
569
584
Assert (entryPointInfo);
@@ -1040,9 +1055,10 @@ namespace Js
1040
1055
}
1041
1056
}
1042
1057
1043
- void ParseableFunctionInfo::Copy (FunctionBody * other)
1058
+ void ParseableFunctionInfo::Copy (ParseableFunctionInfo * other)
1044
1059
{
1045
1060
#define CopyDeferParseField (field ) other->field = this ->field;
1061
+ CopyDeferParseField (flags);
1046
1062
CopyDeferParseField (m_isDeclaration);
1047
1063
CopyDeferParseField (m_isAccessor);
1048
1064
CopyDeferParseField (m_isStrictMode);
@@ -1067,8 +1083,21 @@ namespace Js
1067
1083
other->SetDeferredStubs (this ->GetDeferredStubs ());
1068
1084
CopyDeferParseField (m_isAsmjsMode);
1069
1085
CopyDeferParseField (m_isAsmJsFunction);
1070
- #undef CopyDeferParseField
1071
1086
1087
+ CopyDeferParseField (m_sourceIndex);
1088
+ CopyDeferParseField (m_cchStartOffset);
1089
+ CopyDeferParseField (m_cchLength);
1090
+ CopyDeferParseField (m_lineNumber);
1091
+ CopyDeferParseField (m_columnNumber);
1092
+ CopyDeferParseField (m_cbStartOffset);
1093
+ CopyDeferParseField (m_cbLength);
1094
+
1095
+ #undef CopyDeferParseField
1096
+ }
1097
+
1098
+ void ParseableFunctionInfo::Copy (FunctionBody* other)
1099
+ {
1100
+ this ->Copy (static_cast <ParseableFunctionInfo*>(other));
1072
1101
other->CopySourceInfo (this );
1073
1102
}
1074
1103
@@ -1137,6 +1166,7 @@ namespace Js
1137
1166
#if DYNAMIC_INTERPRETER_THUNK
1138
1167
m_dynamicInterpreterThunk (nullptr ),
1139
1168
#endif
1169
+ flags (Flags_HasNoExplicitReturnValue),
1140
1170
m_hasBeenParsed(false ),
1141
1171
m_isGlobalFunc(false ),
1142
1172
m_isDeclaration(false ),
@@ -1207,6 +1237,41 @@ namespace Js
1207
1237
this ->SetOriginalEntryPoint (DefaultEntryThunk);
1208
1238
}
1209
1239
1240
+ ParseableFunctionInfo::ParseableFunctionInfo (ParseableFunctionInfo * proxy) :
1241
+ FunctionProxy (proxy->GetScriptContext (), proxy->GetUtf8SourceInfo(), proxy->GetFunctionNumber()),
1242
+ #if DYNAMIC_INTERPRETER_THUNK
1243
+ m_dynamicInterpreterThunk (nullptr ),
1244
+ #endif
1245
+ m_hasBeenParsed (false ),
1246
+ m_isNamedFunctionExpression(proxy->GetIsNamedFunctionExpression ()),
1247
+ m_isNameIdentifierRef (proxy->GetIsNameIdentifierRef ()),
1248
+ m_isStaticNameFunction(proxy->GetIsStaticNameFunction ()),
1249
+ m_reportedInParamCount(proxy->GetReportedInParamsCount ()),
1250
+ m_reparsed(proxy->IsReparsed ())
1251
+ #if DBG
1252
+ ,m_wasEverAsmjsMode(proxy->m_wasEverAsmjsMode)
1253
+ #endif
1254
+ {
1255
+ proxy->Copy (this );
1256
+
1257
+ FunctionInfo * functionInfo = proxy->GetFunctionInfo ();
1258
+ this ->functionInfo = functionInfo;
1259
+
1260
+ uint nestedCount = proxy->GetNestedCount ();
1261
+ if (nestedCount > 0 )
1262
+ {
1263
+ nestedArray = RecyclerNewPlusZ (m_scriptContext->GetRecycler (),
1264
+ nestedCount*sizeof (FunctionProxy*), NestedArray, nestedCount);
1265
+ }
1266
+ else
1267
+ {
1268
+ nestedArray = nullptr ;
1269
+ }
1270
+
1271
+ SetBoundPropertyRecords (proxy->GetBoundPropertyRecords ());
1272
+ SetDisplayName (proxy->GetDisplayName (), proxy->GetDisplayNameLength (), proxy->GetShortDisplayNameOffset ());
1273
+ }
1274
+
1210
1275
ParseableFunctionInfo* ParseableFunctionInfo::New (ScriptContext* scriptContext, int nestedCount,
1211
1276
LocalFunctionId functionId, Utf8SourceInfo* sourceInfo, const char16* displayName, uint displayNameLength, uint displayShortNameOffset, Js::PropertyRecordList* propertyRecords, FunctionInfo::Attributes attributes)
1212
1277
{
@@ -1247,6 +1312,38 @@ namespace Js
1247
1312
propertyRecords);
1248
1313
}
1249
1314
1315
+ ParseableFunctionInfo *
1316
+ ParseableFunctionInfo::NewDeferredFunctionFromFunctionBody (FunctionBody * functionBody)
1317
+ {
1318
+ ScriptContext * scriptContext = functionBody->GetScriptContext ();
1319
+ FunctionInfo * functionInfo = functionBody->GetFunctionInfo ();
1320
+ uint nestedCount = functionBody->GetNestedCount ();
1321
+
1322
+ ParseableFunctionInfo * info = RecyclerNewWithBarrierFinalized (scriptContext->GetRecycler (),
1323
+ ParseableFunctionInfo,
1324
+ functionBody);
1325
+
1326
+ // Create new entry point info
1327
+ info->m_defaultEntryPointInfo = RecyclerNew (scriptContext->GetRecycler (), ProxyEntryPointInfo, scriptContext->DeferredParsingThunk );
1328
+
1329
+ // New allocation is done at this point, so update existing structures
1330
+ // Adjust functionInfo attributes, point to new proxy
1331
+ functionInfo->SetAttributes ((FunctionInfo::Attributes)(functionInfo->GetAttributes () | FunctionInfo::Attributes::DeferredParse));
1332
+ functionInfo->SetFunctionProxy (info);
1333
+ functionInfo->SetOriginalEntryPoint (DefaultEntryThunk);
1334
+
1335
+ // Initialize nested function array, update back pointers
1336
+ for (uint i = 0 ; i < nestedCount; i++)
1337
+ {
1338
+ FunctionProxy * nestedProxy = functionBody->GetNestedFunc (i);
1339
+ info->SetNestedFunc (nestedProxy, i, 0 );
1340
+ }
1341
+
1342
+ // Update function objects
1343
+
1344
+ return info;
1345
+ }
1346
+
1250
1347
DWORD_PTR FunctionProxy::GetSecondaryHostSourceContext () const
1251
1348
{
1252
1349
return this ->GetUtf8SourceInfo ()->GetSecondaryHostSourceContext ();
@@ -1734,6 +1831,11 @@ namespace Js
1734
1831
this ->Copy (funcBody);
1735
1832
PERF_COUNTER_DEC (Code, DeferredFunction);
1736
1833
1834
+ this ->UpdateFunctionBodyImpl (funcBody);
1835
+ // FunctionInfo * functionInfo = this->GetFunctionInfo();
1836
+ // funcBody->SetFunctionInfo(functionInfo);
1837
+ // functionInfo->SetFunctionProxy(funcBody);
1838
+
1737
1839
if (!this ->GetSourceContextInfo ()->IsDynamic ())
1738
1840
{
1739
1841
PHASE_PRINT_TESTTRACE1 (Js::DeferParsePhase, _u (" TestTrace: Deferred function parsed - ID: %d; Display Name: %s; Length: %d; Nested Function Count: %d; Utf8SourceInfo: %d; Source Length: %d; Is Top Level: %s; Source Url: %s\n " ), m_functionNumber, m_displayName, this ->m_cchLength , this ->GetNestedCount (), this ->m_utf8SourceInfo ->GetSourceInfoId (), this ->m_utf8SourceInfo ->GetCchLength (), this ->GetIsTopLevel () ? _u (" True" ) : _u (" False" ), this ->GetSourceContextInfo ()->url );
@@ -1870,7 +1972,7 @@ namespace Js
1870
1972
hrParser = ps.ParseSourceWithOffset (&parseTree, pszStart, offset, length, charOffset, isCesu8, grfscr, &se,
1871
1973
&nextFunctionId, funcBody->GetRelativeLineNumber (), funcBody->GetSourceContextInfo (),
1872
1974
funcBody);
1873
- Assert (FAILED (hrParser) || nextFunctionId == funcBody->deferredParseNextFunctionId || isDebugOrAsmJsReparse || isByteCodeDeserialization);
1975
+ // Assert(FAILED(hrParser) || nextFunctionId == funcBody->deferredParseNextFunctionId || isDebugOrAsmJsReparse || isByteCodeDeserialization);
1874
1976
1875
1977
if (FAILED (hrParser))
1876
1978
{
@@ -1956,7 +2058,7 @@ namespace Js
1956
2058
// Restore if the function has nameIdentifier reference, as that name on the left side will not be parsed again while deferparse.
1957
2059
funcBody->SetIsNameIdentifierRef (this ->GetIsNameIdentifierRef ());
1958
2060
1959
- this ->UpdateFunctionBodyImpl (funcBody);
2061
+ // this->UpdateFunctionBodyImpl(funcBody);
1960
2062
this ->m_hasBeenParsed = true ;
1961
2063
returnFunctionBody = funcBody;
1962
2064
}
@@ -3420,33 +3522,34 @@ namespace Js
3420
3522
}
3421
3523
}
3422
3524
3423
- void FunctionBody::SetStackNestedFuncParent (FunctionBody * parentFunctionBody )
3525
+ void FunctionBody::SetStackNestedFuncParent (FunctionInfo * parentFunctionInfo )
3424
3526
{
3527
+ FunctionBody * parentFunctionBody = parentFunctionInfo->GetFunctionBody ();
3425
3528
Assert (this ->GetStackNestedFuncParent () == nullptr );
3426
3529
Assert (CanDoStackNestedFunc ());
3427
3530
Assert (parentFunctionBody->DoStackNestedFunc ());
3428
3531
3429
- this ->SetAuxPtr (AuxPointerType::StackNestedFuncParent, this ->GetScriptContext ()->GetRecycler ()->CreateWeakReferenceHandle (parentFunctionBody ));
3532
+ this ->SetAuxPtr (AuxPointerType::StackNestedFuncParent, this ->GetScriptContext ()->GetRecycler ()->CreateWeakReferenceHandle (parentFunctionInfo ));
3430
3533
}
3431
3534
3432
- FunctionBody * FunctionBody::GetStackNestedFuncParentStrongRef ()
3535
+ FunctionInfo * FunctionBody::GetStackNestedFuncParentStrongRef ()
3433
3536
{
3434
3537
Assert (this ->GetStackNestedFuncParent () != nullptr );
3435
3538
return this ->GetStackNestedFuncParent ()->Get ();
3436
3539
}
3437
3540
3438
- RecyclerWeakReference<FunctionBody > * FunctionBody::GetStackNestedFuncParent ()
3541
+ RecyclerWeakReference<FunctionInfo > * FunctionBody::GetStackNestedFuncParent ()
3439
3542
{
3440
- return static_cast <RecyclerWeakReference<FunctionBody >*>(this ->GetAuxPtr (AuxPointerType::StackNestedFuncParent));
3543
+ return static_cast <RecyclerWeakReference<FunctionInfo >*>(this ->GetAuxPtr (AuxPointerType::StackNestedFuncParent));
3441
3544
}
3442
3545
3443
- FunctionBody * FunctionBody::GetAndClearStackNestedFuncParent ()
3546
+ FunctionInfo * FunctionBody::GetAndClearStackNestedFuncParent ()
3444
3547
{
3445
3548
if (this ->GetAuxPtr (AuxPointerType::StackNestedFuncParent))
3446
3549
{
3447
- FunctionBody * parentFunctionBody = GetStackNestedFuncParentStrongRef ();
3550
+ FunctionInfo * parentFunctionInfo = GetStackNestedFuncParentStrongRef ();
3448
3551
ClearStackNestedFuncParent ();
3449
- return parentFunctionBody ;
3552
+ return parentFunctionInfo ;
3450
3553
}
3451
3554
return nullptr ;
3452
3555
}
@@ -4098,7 +4201,7 @@ namespace Js
4098
4201
}
4099
4202
#endif
4100
4203
4101
- void FunctionBody ::SetIsNonUserCode (bool set)
4204
+ void ParseableFunctionInfo ::SetIsNonUserCode (bool set)
4102
4205
{
4103
4206
// Mark current function as a non-user code, so that we can distinguish cases where exceptions are
4104
4207
// caught in non-user code (see ProbeContainer::HasAllowedForException).
@@ -4107,7 +4210,7 @@ namespace Js
4107
4210
// Propagate setting for all functions in this scope (nested).
4108
4211
this ->ForEachNestedFunc ([&](FunctionProxy* proxy, uint32 index)
4109
4212
{
4110
- Js::FunctionBody * pBody = proxy->GetFunctionBody ();
4213
+ ParseableFunctionInfo * pBody = proxy->GetParseableFunctionInfo ();
4111
4214
if (pBody != nullptr )
4112
4215
{
4113
4216
pBody->SetIsNonUserCode (set);
0 commit comments