blob: 5fd53139491c550c5487d7505039a8f2e2922ae3 [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeBasePch.h"
namespace Js
{
EnterScriptObject::EnterScriptObject(ScriptContext* scriptContext, ScriptEntryExitRecord* entryExitRecord,
void * returnAddress, bool doCleanup, bool isCallRoot, bool hasCaller)
{
Assert(scriptContext);
#ifdef PROFILE_EXEC
scriptContext->ProfileBegin(Js::RunPhase);
#endif
if (scriptContext->GetThreadContext() &&
scriptContext->GetThreadContext()->IsNoScriptScope())
{
FromDOM_NoScriptScope_fatal_error();
}
// Keep a copy locally so the optimizer can just copy prop it to the dtor
this->scriptContext = scriptContext;
this->entryExitRecord = entryExitRecord;
this->doCleanup = doCleanup;
this->isCallRoot = isCallRoot;
this->hr = NOERROR;
this->hasForcedEnter =
#ifdef ENABLE_SCRIPT_DEBUGGING
scriptContext->GetDebugContext() != nullptr ?
scriptContext->GetDebugContext()->GetProbeContainer()->isForcedToEnterScriptStart :
#endif
false;
// Initialize the entry exit record
entryExitRecord->returnAddrOfScriptEntryFunction = returnAddress;
entryExitRecord->hasCaller = hasCaller;
entryExitRecord->scriptContext = scriptContext;
#ifdef EXCEPTION_CHECK
entryExitRecord->handledExceptionType = ExceptionCheck::ClearHandledExceptionType();
#endif
#if DBG_DUMP
entryExitRecord->isCallRoot = isCallRoot;
#endif
if (!scriptContext->IsClosed())
{
library = scriptContext->GetLibrary();
}
try
{
AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_OutOfMemory);
scriptContext->GetThreadContext()->PushHostScriptContext(scriptContext->GetHostScriptContext());
}
catch (Js::OutOfMemoryException)
{
this->hr = E_OUTOFMEMORY;
}
BEGIN_NO_EXCEPTION
{
// We can not have any exception in the constructor, otherwise the destructor will
// not run and we might be in an inconsistent state
// Put any code that may raise an exception in OnScriptStart
scriptContext->GetThreadContext()->EnterScriptStart(entryExitRecord, doCleanup);
}
END_NO_EXCEPTION
}
void EnterScriptObject::VerifyEnterScript()
{
if (FAILED(hr))
{
Assert(hr == E_OUTOFMEMORY);
throw Js::OutOfMemoryException();
}
}
EnterScriptObject::~EnterScriptObject()
{
scriptContext->OnScriptEnd(isCallRoot, hasForcedEnter);
if (SUCCEEDED(hr))
{
scriptContext->GetThreadContext()->PopHostScriptContext();
}
scriptContext->GetThreadContext()->EnterScriptEnd(entryExitRecord, doCleanup);
#ifdef PROFILE_EXEC
scriptContext->ProfileEnd(Js::RunPhase);
#endif
}
};