Browse Source

[1.4>master] [MERGE #2502 @jianchun] fix incorrect debugger mode reparse after function redefer

Merge pull request #2502 from jianchun:defer

Debug mode reparse should still set "reuseNestedFunc", otherwise we'll
discard existing nested func info and create new FunctionInfo/FunctionBody
for nested functions, conflicting with existing ones.

Existing debug mode reparse also not expecting function redefer introduced
ParseableFunctionInfo in nested FunctionBody chain. It did not reuse
existing child FunctionBody and not clean up them for reparse properly
when a parent function was redeferred. Patch the code to fix this.

Credits to Paul/Akrosh.
Jianchun Xu 9 years ago
parent
commit
ec7eeb006d
1 changed files with 12 additions and 2 deletions
  1. 12 2
      lib/Runtime/ByteCode/ByteCodeGenerator.cpp

+ 12 - 2
lib/Runtime/ByteCode/ByteCodeGenerator.cpp

@@ -1633,7 +1633,7 @@ Symbol * ByteCodeGenerator::FindSymbol(Symbol **symRef, IdentPtr pid, bool forRe
         bool didTransferToFncVarSym = false;
 
         if (!PHASE_OFF(Js::OptimizeBlockScopePhase, top->byteCodeFunction) &&
-            sym->GetIsBlockVar() && 
+            sym->GetIsBlockVar() &&
             !sym->GetScope()->IsBlockInLoop() &&
             sym->GetSymbolType() == STFunction)
         {
@@ -3318,13 +3318,23 @@ void VisitNestedScopes(ParseNode* pnodeScopeList, ParseNode* pnodeParent, ByteCo
 
             Js::ParseableFunctionInfo::NestedArray * parentNestedArray = parentFunc->GetNestedArray();
             Js::ParseableFunctionInfo* reuseNestedFunc = nullptr;
-            if (parentNestedArray && byteCodeGenerator->GetScriptContext()->IsScriptContextInNonDebugMode())
+            if (parentNestedArray)
             {
                 Assert(*pIndex < parentNestedArray->nestedCount);
                 Js::FunctionInfo * info = parentNestedArray->functionInfoArray[*pIndex];
                 if (info && info->HasParseableInfo())
                 {
                     reuseNestedFunc = info->GetParseableFunctionInfo();
+
+                    // If parentFunc was redeferred, try to set pCurrentFunction to this FunctionBody,
+                    // and cleanup to reparse (as previous cleanup stops at redeferred parentFunc).
+                    if (!byteCodeGenerator->IsInNonDebugMode()
+                        && !byteCodeGenerator->pCurrentFunction
+                        && reuseNestedFunc->IsFunctionBody())
+                    {
+                        byteCodeGenerator->pCurrentFunction = reuseNestedFunc->GetFunctionBody();
+                        byteCodeGenerator->pCurrentFunction->CleanupToReparse();
+                    }
                 }
             }
             PreVisitFunction(pnodeScope, byteCodeGenerator, reuseNestedFunc);