Skip to content

Commit eaf36fe

Browse files
committed
MSFT: 6967505 setInterval(alert(), 10000/237) throws Invalid calling object exception after domtimeline script is injected
In debugger when we used to put all globaobject properties in the ActivationObject and use that as "this" pointer for global object. We should separate out the ActivationObject from GlobalObject and use the GlobalObject as "this". Fixed a couple of issues exposed by this change.
1 parent 5669a00 commit eaf36fe

5 files changed

Lines changed: 35 additions & 13 deletions

File tree

lib/Runtime/Debug/DebugManager.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ namespace Js
125125
return (DynamicObject*)CrossSite::MarshalVar(scriptContext, (Var)this->pConsoleScope);
126126
}
127127

128-
FrameDisplay *DebugManager::GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne, bool addGlobalThisAtScopeTwo)
128+
FrameDisplay *DebugManager::GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne)
129129
{
130130
// The scope chain for console eval looks like:
131131
// - dummy empty object - new vars, let, consts, functions get added here
@@ -136,10 +136,7 @@ namespace Js
136136

137137
FrameDisplay* environment = JavascriptOperators::OP_LdFrameDisplay(this->GetConsoleScope(scriptContext), const_cast<FrameDisplay *>(&NullFrameDisplay), scriptContext);
138138

139-
if (addGlobalThisAtScopeTwo)
140-
{
141-
environment = JavascriptOperators::OP_LdFrameDisplay(scriptContext->GetGlobalObject()->ToThis(), environment, scriptContext);
142-
}
139+
environment = JavascriptOperators::OP_LdFrameDisplay(scriptContext->GetGlobalObject()->ToThis(), environment, scriptContext);
143140

144141
if (scopeAtOne != nullptr)
145142
{

lib/Runtime/Debug/DebugManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ namespace Js
5959
MutationBreakpoint* GetActiveMutationBreakpoint() const;
6060
#endif
6161
DynamicObject* GetConsoleScope(ScriptContext* scriptContext);
62-
FrameDisplay *GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne, bool addGlobalThisAtScopeTwo);
62+
FrameDisplay *GetFrameDisplay(ScriptContext* scriptContext, DynamicObject* scopeAtZero, DynamicObject* scopeAtOne);
6363
void UpdateConsoleScope(DynamicObject* copyFromScope, ScriptContext* scriptContext);
6464
PageAllocator * GetDiagnosticPageAllocator() { return &this->diagnosticPageAllocator; }
6565
#if DBG

lib/Runtime/Debug/DiagObjectModel.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,8 @@ namespace Js
10861086

10871087
// In the eval function, we will not show global items directly, instead they should go as a group node.
10881088
bool shouldAddGlobalItemsDirectly = pFBody->GetIsGlobalFunc() && !pFBody->IsEval();
1089-
if (shouldAddGlobalItemsDirectly)
1089+
bool dontAddGlobalsDirectly = (frameWalkerFlags & FrameWalkerFlags::FW_DontAddGlobalsDirectly) == FrameWalkerFlags::FW_DontAddGlobalsDirectly;
1090+
if (shouldAddGlobalItemsDirectly && !dontAddGlobalsDirectly)
10901091
{
10911092
// Global properties will be enumerated using RootObjectVariablesWalker
10921093
pVarWalkers->Add(Anew(arena, RootObjectVariablesWalker, pFrame, pFrame->GetRootObject(), UIGroupType_None));
@@ -1171,7 +1172,7 @@ namespace Js
11711172
}
11721173

11731174
// No need to add global properties if this is a global function, as it is already done above.
1174-
if (!shouldAddGlobalItemsDirectly)
1175+
if (!shouldAddGlobalItemsDirectly && !dontAddGlobalsDirectly)
11751176
{
11761177
pVarWalker = Anew(arena, RootObjectVariablesWalker, pFrame, pFrame->GetRootObject(), UIGroupType_Globals);
11771178
pVarWalkers->Add(pVarWalker);

lib/Runtime/Debug/DiagObjectModel.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,12 @@ namespace Js
144144

145145
enum FrameWalkerFlags
146146
{
147-
FW_None = 0x0,
148-
FW_MakeGroups = 0x1, // Make groups such as [Scope], [Globals] etc.
149-
FW_EnumWithScopeAlso = 0x2, // While walking include the with scope as well.
150-
FW_AllowLexicalThis = 0x4, // Do not filter out Js::PropertyIds::_lexicalThisSlotSymbol
151-
FW_AllowSuperReference = 0x8, // Allow walking of Js::PropertyIds::_superReferenceSymbol and Js::PropertyIds::_superCtorReferenceSymbol
147+
FW_None = 0x0,
148+
FW_MakeGroups = 0x1, // Make groups such as [Scope], [Globals] etc.
149+
FW_EnumWithScopeAlso = 0x2, // While walking include the with scope as well.
150+
FW_AllowLexicalThis = 0x4, // Do not filter out Js::PropertyIds::_lexicalThisSlotSymbol
151+
FW_AllowSuperReference = 0x8, // Allow walking of Js::PropertyIds::_superReferenceSymbol and Js::PropertyIds::_superCtorReferenceSymbol
152+
FW_DontAddGlobalsDirectly = 0x10, // Do not add global object directly.
152153
};
153154

154155
class VariableWalkerBase : public IDiagObjectModelWalkerBase

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2846,6 +2846,29 @@ namespace Js
28462846
// If we have console scope and no one in the scope had the property add it to console scope
28472847
if ((length > 0) && ConsoleScopeActivationObject::Is(pDisplay->GetItem(length - 1)))
28482848
{
2849+
// CheckPrototypesForAccessorOrNonWritableProperty does not check for const in global object. We should check it here.
2850+
if ((length > 1) && GlobalObject::Is(pDisplay->GetItem(length - 2)))
2851+
{
2852+
GlobalObject* globalObject = GlobalObject::FromVar(pDisplay->GetItem(length - 2));
2853+
Var setterValue = nullptr;
2854+
2855+
DescriptorFlags flags = JavascriptOperators::GetRootSetter(globalObject, propertyId, &setterValue, &info, scriptContext);
2856+
Assert((flags & Accessor) != Accessor);
2857+
Assert((flags & Proxy) != Proxy);
2858+
if ((flags & Data) == Data && (flags & Writable) == None)
2859+
{
2860+
if (!allowUndecInConsoleScope)
2861+
{
2862+
if (flags & Const)
2863+
{
2864+
JavascriptError::ThrowTypeError(scriptContext, ERRAssignmentToConst);
2865+
}
2866+
Assert(!isLexicalThisSlotSymbol);
2867+
return;
2868+
}
2869+
}
2870+
}
2871+
28492872
RecyclableObject* obj = RecyclableObject::FromVar((DynamicObject*)pDisplay->GetItem(length - 1));
28502873
OUTPUT_TRACE(Js::ConsoleScopePhase, _u("Adding property '%s' to console scope object\n"), scriptContext->GetPropertyName(propertyId)->GetBuffer());
28512874
JavascriptOperators::SetProperty(obj, obj, propertyId, newValue, scriptContext, propertyOperationFlags);

0 commit comments

Comments
 (0)