| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "RuntimeDebugPch.h"
- #include "Language/JavascriptFunctionArgIndex.h"
- #include "Language/InterpreterStackFrame.h"
- #include "Language/JavascriptStackWalker.h"
- namespace Js
- {
- DiagStackFrame::DiagStackFrame():
- isTopFrame(false)
- {
- }
- // Returns whether or not this frame is on the top of the callstack.
- bool DiagStackFrame::IsTopFrame()
- {
- return this->isTopFrame && GetScriptContext()->GetDebugContext()->GetProbeContainer()->IsPrimaryBrokenToDebuggerContext();
- }
- void DiagStackFrame::SetIsTopFrame()
- {
- this->isTopFrame = true;
- }
- ScriptFunction* DiagStackFrame::GetScriptFunction()
- {
- return ScriptFunction::FromVar(GetJavascriptFunction());
- }
- FunctionBody* DiagStackFrame::GetFunction()
- {
- return GetJavascriptFunction()->GetFunctionBody();
- }
- ScriptContext* DiagStackFrame::GetScriptContext()
- {
- return GetJavascriptFunction()->GetScriptContext();
- }
- PCWSTR DiagStackFrame::GetDisplayName()
- {
- return GetFunction()->GetExternalDisplayName();
- }
- bool DiagStackFrame::IsInterpreterFrame()
- {
- return false;
- }
- InterpreterStackFrame* DiagStackFrame::AsInterpreterFrame()
- {
- AssertMsg(FALSE, "AsInterpreterFrame called for non-interpreter frame.");
- return nullptr;
- }
- ArenaAllocator * DiagStackFrame::GetArena()
- {
- Assert(GetScriptContext() != NULL);
- return GetScriptContext()->GetThreadContext()->GetDebugManager()->GetDiagnosticArena()->Arena();
- }
- FrameDisplay * DiagStackFrame::GetFrameDisplay()
- {
- FrameDisplay *display = NULL;
- Assert(this->GetFunction() != NULL);
- RegSlot frameDisplayReg = this->GetFunction()->GetFrameDisplayRegister();
- if (frameDisplayReg != Js::Constants::NoRegister && frameDisplayReg != 0)
- {
- display = (FrameDisplay*)this->GetNonVarRegValue(frameDisplayReg);
- }
- else
- {
- display = this->GetScriptFunction()->GetEnvironment();
- }
-
- return display;
- }
- Var DiagStackFrame::GetScopeObjectFromFrameDisplay(uint index)
- {
- FrameDisplay * display = GetFrameDisplay();
- return (display != NULL && display->GetLength() > index) ? display->GetItem(index) : NULL;
- }
- Var DiagStackFrame::GetRootObject()
- {
- Assert(this->GetFunction());
- return this->GetFunction()->LoadRootObject();
- }
- BOOL DiagStackFrame::IsStrictMode()
- {
- Js::JavascriptFunction* scopeFunction = this->GetJavascriptFunction();
- return scopeFunction->IsStrictMode();
- }
- BOOL DiagStackFrame::IsThisAvailable()
- {
- Js::JavascriptFunction* scopeFunction = this->GetJavascriptFunction();
- return !scopeFunction->IsLambda() || scopeFunction->GetParseableFunctionInfo()->GetCapturesThis();
- }
- Js::Var DiagStackFrame::GetThisFromFrame(Js::IDiagObjectAddress ** ppOutAddress, Js::IDiagObjectModelWalkerBase * localsWalker)
- {
- Js::ScriptContext* scriptContext = this->GetScriptContext();
- Js::JavascriptFunction* scopeFunction = this->GetJavascriptFunction();
- Js::ModuleID moduleId = scopeFunction->IsScriptFunction() ? scopeFunction->GetFunctionBody()->GetModuleID() : 0;
- Js::Var varThis = scriptContext->GetLibrary()->GetNull();
- if (!scopeFunction->IsLambda())
- {
- Js::JavascriptStackWalker::GetThis(&varThis, moduleId, scopeFunction, scriptContext);
- }
- else
- {
- if (!scopeFunction->GetParseableFunctionInfo()->GetCapturesThis())
- {
- return nullptr;
- }
- else
- {
- // Emulate Js::JavascriptOperators::OP_GetThisScoped using a locals walker and assigning moduleId object if not found by locals walker
- if (localsWalker == nullptr)
- {
- ArenaAllocator *arena = scriptContext->GetThreadContext()->GetDebugManager()->GetDiagnosticArena()->Arena();
- localsWalker = Anew(arena, Js::LocalsWalker, this, Js::FrameWalkerFlags::FW_EnumWithScopeAlso | Js::FrameWalkerFlags::FW_AllowLexicalThis);
- }
- bool unused = false;
- Js::IDiagObjectAddress* address = localsWalker->FindPropertyAddress(Js::PropertyIds::_lexicalThisSlotSymbol, unused);
- if (ppOutAddress != nullptr)
- {
- *ppOutAddress = address;
- }
- if (address != nullptr)
- {
- varThis = address->GetValue(FALSE);
- }
- else if (moduleId == kmodGlobal)
- {
- varThis = Js::JavascriptOperators::OP_LdRoot(scriptContext)->ToThis();
- }
- else
- {
- varThis = (Var)Js::JavascriptOperators::GetModuleRoot(moduleId, scriptContext);
- }
- }
- }
- Js::GlobalObject::UpdateThisForEval(varThis, moduleId, scriptContext, this->IsStrictMode());
- return varThis;
- }
- void DiagStackFrame::TryFetchValueAndAddress(const char16 *source, int sourceLength, Js::ResolvedObject * pOutResolvedObj)
- {
- Assert(source);
- Assert(pOutResolvedObj);
- Js::ScriptContext* scriptContext = this->GetScriptContext();
- Js::JavascriptFunction* scopeFunction = this->GetJavascriptFunction();
- // Do fast path for 'this', fields on slot, TODO : literals (integer,string)
- if (sourceLength == 4 && wcsncmp(source, _u("this"), 4) == 0)
- {
- pOutResolvedObj->obj = this->GetThisFromFrame(&pOutResolvedObj->address);
- if (pOutResolvedObj->obj == nullptr)
- {
- // TODO: Throw exception; this was not captured by the lambda
- Assert(scopeFunction->IsLambda());
- Assert(!scopeFunction->GetParseableFunctionInfo()->GetCapturesThis());
- }
- }
- else
- {
- Js::PropertyRecord const * propRecord;
- scriptContext->FindPropertyRecord(source, sourceLength, &propRecord);
- if (propRecord != nullptr)
- {
- ArenaAllocator *arena = scriptContext->GetThreadContext()->GetDebugManager()->GetDiagnosticArena()->Arena();
- Js::IDiagObjectModelWalkerBase * localsWalker = Anew(arena, Js::LocalsWalker, this, Js::FrameWalkerFlags::FW_EnumWithScopeAlso);
- bool isConst = false;
- pOutResolvedObj->address = localsWalker->FindPropertyAddress(propRecord->GetPropertyId(), isConst);
- if (pOutResolvedObj->address != nullptr)
- {
- pOutResolvedObj->obj = pOutResolvedObj->address->GetValue(FALSE);
- pOutResolvedObj->isConst = isConst;
- }
- }
- }
- }
- Js::ScriptFunction* DiagStackFrame::TryGetFunctionForEval(Js::ScriptContext* scriptContext, const char16 *source, int sourceLength, BOOL isLibraryCode /* = FALSE */)
- {
- // TODO: pass the real length of the source code instead of wcslen
- uint32 grfscr = fscrReturnExpression | fscrEval | fscrEvalCode | fscrGlobalCode | fscrConsoleScopeEval;
- if (!this->IsThisAvailable())
- {
- grfscr |= fscrDebuggerErrorOnGlobalThis;
- }
- if (isLibraryCode)
- {
- grfscr |= fscrIsLibraryCode;
- }
- return scriptContext->GetGlobalObject()->EvalHelper(scriptContext, source, sourceLength, kmodGlobal, grfscr, Js::Constants::EvalCode, FALSE, FALSE, this->IsStrictMode());
- }
- void DiagStackFrame::EvaluateImmediate(const char16 *source, int sourceLength, BOOL isLibraryCode, Js::ResolvedObject * resolvedObject)
- {
- this->TryFetchValueAndAddress(source, sourceLength, resolvedObject);
- if (resolvedObject->obj == nullptr)
- {
- Js::ScriptFunction* pfuncScript = this->TryGetFunctionForEval(this->GetScriptContext(), source, sourceLength, isLibraryCode);
- if (pfuncScript != nullptr)
- {
- // Passing the nonuser code state from the enclosing function to the current function.
- // Treat native library frame (no function body) as non-user code.
- Js::FunctionBody* body = this->GetFunction();
- if (!body || body->IsNonUserCode())
- {
- Js::FunctionBody *pCurrentFuncBody = pfuncScript->GetFunctionBody();
- if (pCurrentFuncBody != nullptr)
- {
- pCurrentFuncBody->SetIsNonUserCode(true);
- }
- }
- OUTPUT_TRACE(Js::ConsoleScopePhase, _u("EvaluateImmediate strict = %d, libraryCode = %d, source = '%s'\n"),
- this->IsStrictMode(), isLibraryCode, source);
- resolvedObject->obj = this->DoEval(pfuncScript);
- }
- }
- }
- #ifdef ENABLE_MUTATION_BREAKPOINT
- static void SetConditionalMutationBreakpointVariables(Js::DynamicObject * activeScopeObject, Js::ScriptContext * scriptContext)
- {
- // For Conditional Object Mutation Breakpoint user can access the new value, changing property name and mutation type using special variables
- // $newValue$, $propertyName$ and $mutationType$. Add this variables to activation object.
- Js::DebugManager* debugManager = scriptContext->GetDebugContext()->GetProbeContainer()->GetDebugManager();
- Js::MutationBreakpoint *mutationBreakpoint = debugManager->GetActiveMutationBreakpoint();
- if (mutationBreakpoint != nullptr)
- {
- if (Js::Constants::NoProperty == debugManager->mutationNewValuePid)
- {
- debugManager->mutationNewValuePid = scriptContext->GetOrAddPropertyIdTracked(_u("$newValue$"), 10);
- }
- if (Js::Constants::NoProperty == debugManager->mutationPropertyNamePid)
- {
- debugManager->mutationPropertyNamePid = scriptContext->GetOrAddPropertyIdTracked(_u("$propertyName$"), 14);
- }
- if (Js::Constants::NoProperty == debugManager->mutationTypePid)
- {
- debugManager->mutationTypePid = scriptContext->GetOrAddPropertyIdTracked(_u("$mutationType$"), 14);
- }
- AssertMsg(debugManager->mutationNewValuePid != Js::Constants::NoProperty, "Should have a valid mutationNewValuePid");
- AssertMsg(debugManager->mutationPropertyNamePid != Js::Constants::NoProperty, "Should have a valid mutationPropertyNamePid");
- AssertMsg(debugManager->mutationTypePid != Js::Constants::NoProperty, "Should have a valid mutationTypePid");
- Js::Var newValue = mutationBreakpoint->GetBreakNewValueVar();
- // Incase of MutationTypeDelete we won't have new value
- if (nullptr != newValue)
- {
- activeScopeObject->SetProperty(debugManager->mutationNewValuePid,
- mutationBreakpoint->GetBreakNewValueVar(),
- Js::PropertyOperationFlags::PropertyOperation_None,
- nullptr);
- }
- else
- {
- activeScopeObject->SetProperty(debugManager->mutationNewValuePid,
- scriptContext->GetLibrary()->GetUndefined(),
- Js::PropertyOperationFlags::PropertyOperation_None,
- nullptr);
- }
- // User should not be able to change $propertyName$ and $mutationType$ variables
- // Since we don't have address for $propertyName$ and $mutationType$ even if user change these varibales it won't be reflected after eval
- // But declaring these as const to prevent accidental typos by user so that we throw error in case user changes these variables
- Js::PropertyOperationFlags flags = static_cast<Js::PropertyOperationFlags>(Js::PropertyOperation_SpecialValue | Js::PropertyOperation_AllowUndecl);
- activeScopeObject->SetPropertyWithAttributes(debugManager->mutationPropertyNamePid,
- Js::JavascriptString::NewCopySz(mutationBreakpoint->GetBreakPropertyName(), scriptContext),
- PropertyConstDefaults, nullptr, flags);
- activeScopeObject->SetPropertyWithAttributes(debugManager->mutationTypePid,
- Js::JavascriptString::NewCopySz(mutationBreakpoint->GetMutationTypeForConditionalEval(mutationBreakpoint->GetBreakMutationType()), scriptContext),
- PropertyConstDefaults, nullptr, flags);
- }
- }
- #endif
- Js::Var DiagStackFrame::DoEval(Js::ScriptFunction* pfuncScript)
- {
- Js::Var varResult = nullptr;
- Js::JavascriptFunction* scopeFunction = this->GetJavascriptFunction();
- Js::ScriptContext* scriptContext = this->GetScriptContext();
- ArenaAllocator *arena = scriptContext->GetThreadContext()->GetDebugManager()->GetDiagnosticArena()->Arena();
- Js::LocalsWalker *localsWalker = Anew(arena, Js::LocalsWalker, this,
- Js::FrameWalkerFlags::FW_EnumWithScopeAlso | Js::FrameWalkerFlags::FW_AllowLexicalThis | Js::FrameWalkerFlags::FW_AllowSuperReference | Js::FrameWalkerFlags::FW_DontAddGlobalsDirectly);
- // Store the diag address of a var to the map so that it will be used for editing the value.
- typedef JsUtil::BaseDictionary<Js::PropertyId, Js::IDiagObjectAddress*, ArenaAllocator, PrimeSizePolicy> PropIdToDiagAddressMap;
- PropIdToDiagAddressMap * propIdtoDiagAddressMap = Anew(arena, PropIdToDiagAddressMap, arena);
- // Create one scope object and init all scope properties in it, and push this object in front of the environment.
- Js::DynamicObject * activeScopeObject = localsWalker->CreateAndPopulateActivationObject(scriptContext, [propIdtoDiagAddressMap](Js::ResolvedObject& resolveObject)
- {
- if (!resolveObject.isConst)
- {
- propIdtoDiagAddressMap->AddNew(resolveObject.propId, resolveObject.address);
- }
- });
- if (!activeScopeObject)
- {
- activeScopeObject = scriptContext->GetLibrary()->CreateActivationObject();
- }
- #ifdef ENABLE_MUTATION_BREAKPOINT
- SetConditionalMutationBreakpointVariables(activeScopeObject, scriptContext);
- #endif
- #if DBG
- uint32 countForVerification = activeScopeObject->GetPropertyCount();
- #endif
- // Dummy scope object in the front, so that no new variable will be added to the scope.
- Js::DynamicObject * dummyObject = scriptContext->GetLibrary()->CreateActivationObject();
- // Remove its prototype object so that those item will not be visible to the expression evaluation.
- dummyObject->SetPrototype(scriptContext->GetLibrary()->GetNull());
- Js::DebugManager* debugManager = scriptContext->GetDebugContext()->GetProbeContainer()->GetDebugManager();
- Js::FrameDisplay* env = debugManager->GetFrameDisplay(scriptContext, dummyObject, activeScopeObject);
- pfuncScript->SetEnvironment(env);
- Js::Var varThis = this->GetThisFromFrame(nullptr, localsWalker);
- if (varThis == nullptr)
- {
- Assert(scopeFunction->IsLambda());
- Assert(!scopeFunction->GetParseableFunctionInfo()->GetCapturesThis());
- varThis = scriptContext->GetLibrary()->GetNull();
- }
- Js::Arguments args(1, (Js::Var*) &varThis);
- varResult = pfuncScript->CallFunction(args);
- debugManager->UpdateConsoleScope(dummyObject, scriptContext);
- // We need to find out the edits have been done to the dummy scope object during the eval. We need to apply those mutations to the actual vars.
- uint32 count = activeScopeObject->GetPropertyCount();
- #if DBG
- Assert(countForVerification == count);
- #endif
- for (uint32 i = 0; i < count; i++)
- {
- Js::PropertyId propertyId = activeScopeObject->GetPropertyId((Js::PropertyIndex)i);
- if (propertyId != Js::Constants::NoProperty)
- {
- Js::Var value = nullptr;
- if (Js::JavascriptOperators::GetProperty(activeScopeObject, propertyId, &value, scriptContext))
- {
- Js::IDiagObjectAddress * pAddress = nullptr;
- if (propIdtoDiagAddressMap->TryGetValue(propertyId, &pAddress))
- {
- Assert(pAddress);
- if (pAddress->GetValue(FALSE) != value)
- {
- pAddress->Set(value);
- }
- }
- }
- }
- }
- return varResult;
- }
- Var DiagStackFrame::GetInnerScopeFromRegSlot(RegSlot location)
- {
- return GetNonVarRegValue(location);
- }
- DiagInterpreterStackFrame::DiagInterpreterStackFrame(InterpreterStackFrame* frame) :
- m_interpreterFrame(frame)
- {
- Assert(m_interpreterFrame != NULL);
- AssertMsg(m_interpreterFrame->GetScriptContext() && m_interpreterFrame->GetScriptContext()->IsScriptContextInDebugMode(),
- "This only supports interpreter stack frames running in debug mode.");
- }
- JavascriptFunction* DiagInterpreterStackFrame::GetJavascriptFunction()
- {
- return m_interpreterFrame->GetJavascriptFunction();
- }
- ScriptContext* DiagInterpreterStackFrame::GetScriptContext()
- {
- return m_interpreterFrame->GetScriptContext();
- }
- int DiagInterpreterStackFrame::GetByteCodeOffset()
- {
- return m_interpreterFrame->GetReader()->GetCurrentOffset();
- }
- // Address on stack that belongs to current frame.
- // Currently we only use this to determine which of given frames is above/below another one.
- DWORD_PTR DiagInterpreterStackFrame::GetStackAddress()
- {
- return m_interpreterFrame->GetStackAddress();
- }
- bool DiagInterpreterStackFrame::IsInterpreterFrame()
- {
- return true;
- }
- InterpreterStackFrame* DiagInterpreterStackFrame::AsInterpreterFrame()
- {
- return m_interpreterFrame;
- }
- Var DiagInterpreterStackFrame::GetRegValue(RegSlot slotId, bool allowTemp)
- {
- return m_interpreterFrame->GetReg(slotId);
- }
- Var DiagInterpreterStackFrame::GetNonVarRegValue(RegSlot slotId)
- {
- return m_interpreterFrame->GetNonVarReg(slotId);
- }
- void DiagInterpreterStackFrame::SetRegValue(RegSlot slotId, Var value)
- {
- m_interpreterFrame->SetReg(slotId, value);
- }
- Var DiagInterpreterStackFrame::GetArgumentsObject()
- {
- return m_interpreterFrame->GetArgumentsObject();
- }
- Var DiagInterpreterStackFrame::CreateHeapArguments()
- {
- return m_interpreterFrame->CreateHeapArguments(GetScriptContext());
- }
- FrameDisplay * DiagInterpreterStackFrame::GetFrameDisplay()
- {
- return m_interpreterFrame->GetFrameDisplayForNestedFunc();
- }
- Var DiagInterpreterStackFrame::GetInnerScopeFromRegSlot(RegSlot location)
- {
- return m_interpreterFrame->InnerScopeFromRegSlot(location);
- }
- #if ENABLE_NATIVE_CODEGEN
- DiagNativeStackFrame::DiagNativeStackFrame(
- ScriptFunction* function,
- int byteCodeOffset,
- void* stackAddr,
- void *codeAddr) :
- m_function(function),
- m_byteCodeOffset(byteCodeOffset),
- m_stackAddr(stackAddr),
- m_localVarSlotsOffset(InvalidOffset),
- m_localVarChangedOffset(InvalidOffset)
- {
- Assert(m_stackAddr != NULL);
- AssertMsg(m_function && m_function->GetScriptContext() && m_function->GetScriptContext()->IsScriptContextInDebugMode(),
- "This only supports functions in debug mode.");
- FunctionEntryPointInfo * entryPointInfo = GetFunction()->GetEntryPointFromNativeAddress((DWORD_PTR)codeAddr);
- if (entryPointInfo)
- {
- m_localVarSlotsOffset = entryPointInfo->localVarSlotsOffset;
- m_localVarChangedOffset = entryPointInfo->localVarChangedOffset;
- }
- else
- {
- AssertMsg(FALSE, "Failed to get entry point for native address. Most likely the frame is old/gone.");
- }
- OUTPUT_TRACE(Js::DebuggerPhase, _u("DiagNativeStackFrame::DiagNativeStackFrame: e.p(addr %p)=%p varOff=%d changedOff=%d\n"), codeAddr, entryPointInfo, m_localVarSlotsOffset, m_localVarChangedOffset);
- }
- JavascriptFunction* DiagNativeStackFrame::GetJavascriptFunction()
- {
- return m_function;
- }
- ScriptContext* DiagNativeStackFrame::GetScriptContext()
- {
- return m_function->GetScriptContext();
- }
- int DiagNativeStackFrame::GetByteCodeOffset()
- {
- return m_byteCodeOffset;
- }
- // Address on stack that belongs to current frame.
- // Currently we only use this to determine which of given frames is above/below another one.
- DWORD_PTR DiagNativeStackFrame::GetStackAddress()
- {
- return reinterpret_cast<DWORD_PTR>(m_stackAddr);
- }
- Var DiagNativeStackFrame::GetRegValue(RegSlot slotId, bool allowTemp)
- {
- Js::Var *varPtr = GetSlotOffsetLocation(slotId, allowTemp);
- return (varPtr != NULL) ? *varPtr : NULL;
- }
- Var * DiagNativeStackFrame::GetSlotOffsetLocation(RegSlot slotId, bool allowTemp)
- {
- Assert(GetFunction() != NULL);
- int32 slotOffset;
- if (GetFunction()->GetSlotOffset(slotId, &slotOffset, allowTemp))
- {
- Assert(m_localVarSlotsOffset != InvalidOffset);
- slotOffset = m_localVarSlotsOffset + slotOffset;
- // We will have the var offset only (which is always the Var size. With TypeSpecialization, below will change to accommodate double offset.
- return (Js::Var *)(((char *)m_stackAddr) + slotOffset);
- }
- Assert(false);
- return NULL;
- }
- Var DiagNativeStackFrame::GetNonVarRegValue(RegSlot slotId)
- {
- return GetRegValue(slotId);
- }
- void DiagNativeStackFrame::SetRegValue(RegSlot slotId, Var value)
- {
- Js::Var *varPtr = GetSlotOffsetLocation(slotId);
- Assert(varPtr != NULL);
- // First assign the value
- *varPtr = value;
- Assert(m_localVarChangedOffset != InvalidOffset);
- // Now change the bit in the stack which tells that current stack values got changed.
- char *stackOffset = (((char *)m_stackAddr) + m_localVarChangedOffset);
- Assert(*stackOffset == 0 || *stackOffset == FunctionBody::LocalsChangeDirtyValue);
- *stackOffset = FunctionBody::LocalsChangeDirtyValue;
- }
- Var DiagNativeStackFrame::GetArgumentsObject()
- {
- return (Var)((void **)m_stackAddr)[JavascriptFunctionArgIndex_ArgumentsObject];
- }
- Var DiagNativeStackFrame::CreateHeapArguments()
- {
- // We would be creating the arguments object if there is no default arguments object present.
- Assert(GetArgumentsObject() == NULL);
- CallInfo const * callInfo = (CallInfo const *)&(((void **)m_stackAddr)[JavascriptFunctionArgIndex_CallInfo]);
- // At the least we will have 'this' by default.
- Assert(callInfo->Count > 0);
- // Get the passed parameter's position (which is starting from 'this')
- Var * inParams = (Var *)&(((void **)m_stackAddr)[JavascriptFunctionArgIndex_This]);
- return JavascriptOperators::LoadHeapArguments(
- m_function,
- callInfo->Count - 1,
- &inParams[1],
- GetScriptContext()->GetLibrary()->GetNull(),
- (PropertyId*)GetScriptContext()->GetLibrary()->GetNull(),
- GetScriptContext(),
- /* formalsAreLetDecls */ false);
- }
- #endif
- DiagRuntimeStackFrame::DiagRuntimeStackFrame(JavascriptFunction* function, PCWSTR displayName, void* stackAddr):
- m_function(function),
- m_displayName(displayName),
- m_stackAddr(stackAddr)
- {
- }
- JavascriptFunction* DiagRuntimeStackFrame::GetJavascriptFunction()
- {
- return m_function;
- }
- PCWSTR DiagRuntimeStackFrame::GetDisplayName()
- {
- return m_displayName;
- }
- DWORD_PTR DiagRuntimeStackFrame::GetStackAddress()
- {
- return reinterpret_cast<DWORD_PTR>(m_stackAddr);
- }
- int DiagRuntimeStackFrame::GetByteCodeOffset()
- {
- return 0;
- }
- Var DiagRuntimeStackFrame::GetRegValue(RegSlot slotId, bool allowTemp)
- {
- return nullptr;
- }
- Var DiagRuntimeStackFrame::GetNonVarRegValue(RegSlot slotId)
- {
- return nullptr;
- }
- void DiagRuntimeStackFrame::SetRegValue(RegSlot slotId, Var value)
- {
- }
- Var DiagRuntimeStackFrame::GetArgumentsObject()
- {
- return nullptr;
- }
- Var DiagRuntimeStackFrame::CreateHeapArguments()
- {
- return nullptr;
- }
- } // namespace Js
|