blob: 075f8edaa7d29a6f27e90f6bedc0443f9bba7910 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "Backend.h"
NativeCodeGenerator *
NewNativeCodeGenerator(Js::ScriptContext * scriptContext)
{
return HeapNew(NativeCodeGenerator, scriptContext);
}
void
DeleteNativeCodeGenerator(NativeCodeGenerator * nativeCodeGen)
{
HeapDelete(nativeCodeGen);
}
void
CloseNativeCodeGenerator(NativeCodeGenerator * nativeCodeGen)
{
nativeCodeGen->Close();
}
bool
IsClosedNativeCodeGenerator(NativeCodeGenerator * nativeCodeGen)
{
return nativeCodeGen->IsClosed();
}
void SetProfileModeNativeCodeGen(NativeCodeGenerator *pNativeCodeGen, BOOL fSet)
{
pNativeCodeGen->SetProfileMode(fSet);
}
void UpdateNativeCodeGeneratorForDebugMode(NativeCodeGenerator* nativeCodeGen)
{
nativeCodeGen->UpdateQueueForDebugMode();
}
CriticalSection *GetNativeCodeGenCriticalSection(NativeCodeGenerator *pNativeCodeGen)
{
return pNativeCodeGen->Processor()->GetCriticalSection();
}
///----------------------------------------------------------------------------
///
/// GenerateFunction
///
/// This is the main entry point for the runtime to call the native code
/// generator for js function.
///
///----------------------------------------------------------------------------
void
GenerateFunction(NativeCodeGenerator * nativeCodeGen, Js::FunctionBody * fn, Js::ScriptFunction * function)
{
nativeCodeGen->GenerateFunction(fn, function);
}
InProcCodeGenAllocators* GetForegroundAllocator(NativeCodeGenerator * nativeCodeGen, PageAllocator* pageallocator)
{
return nativeCodeGen->GetCodeGenAllocator(pageallocator);
}
#ifdef ENABLE_PREJIT
void
GenerateAllFunctions(NativeCodeGenerator * nativeCodeGen, Js::FunctionBody *fn)
{
nativeCodeGen->GenerateAllFunctions(fn);
}
#endif
#ifdef IR_VIEWER
Js::Var
RejitIRViewerFunction(NativeCodeGenerator *nativeCodeGen, Js::FunctionBody *fn, Js::ScriptContext *scriptContext)
{
return nativeCodeGen->RejitIRViewerFunction(fn, scriptContext);
}
#endif
#ifdef ALLOW_JIT_REPRO
HRESULT JitFromEncodedWorkItem(NativeCodeGenerator *nativeCodeGen, _In_reads_(bufferSize) const byte* buffer, _In_ uint bufferSize)
{
return nativeCodeGen->JitFromEncodedWorkItem(buffer, bufferSize);
}
#endif
void
GenerateLoopBody(NativeCodeGenerator *nativeCodeGen, Js::FunctionBody *fn, Js::LoopHeader * loopHeader, Js::EntryPointInfo* info, uint localCount, Js::Var localSlots[])
{
nativeCodeGen->GenerateLoopBody(fn, loopHeader, info, localCount, localSlots);
}
void
NativeCodeGenEnterScriptStart(NativeCodeGenerator * nativeCodeGen)
{
if (nativeCodeGen)
{
nativeCodeGen->EnterScriptStart();
}
}
BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress)
{
return NativeCodeGenerator::IsThunk(codeAddress);
}
BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress)
{
return NativeCodeGenerator::IsAsmJsCodeGenThunk(codeAddress);
}
CheckCodeGenFunction GetCheckCodeGenFunction(Js::JavascriptMethod codeAddress)
{
return NativeCodeGenerator::GetCheckCodeGenFunction(codeAddress);
}
Js::JavascriptMethod GetCheckCodeGenThunk()
{
return NativeCodeGenerator::CheckCodeGenThunk;
}
#ifdef ASMJS_PLAT
Js::JavascriptMethod GetCheckAsmJsCodeGenThunk()
{
return NativeCodeGenerator::CheckAsmJsCodeGenThunk;
}
#endif
uint GetBailOutRegisterSaveSlotCount()
{
// REVIEW: not all registers are used, we are allocating more space then necessary.
return LinearScanMD::GetRegisterSaveSlotCount();
}
uint
GetBailOutReserveSlotCount()
{
return 1; //For arguments id
}
#if DBG
void CheckIsExecutable(Js::RecyclableObject * function, Js::JavascriptMethod entrypoint)
{
Js::ScriptContext * scriptContext = function->GetScriptContext();
// it's easy to call the default entry point from RecyclableObject.
AssertMsg((Js::VarIs<Js::JavascriptFunction>(function) && Js::VarTo<Js::JavascriptFunction>(function)->IsExternalFunction())
|| Js::CrossSite::IsThunk(entrypoint)
// External object with entrypoint
|| (!Js::VarIs<Js::JavascriptFunction>(function)
&& function->IsExternal()
&& Js::JavascriptConversion::IsCallable(function))
|| !scriptContext->IsActuallyClosed()
|| (scriptContext->GetThreadContext()->IsScriptActive() && !Js::JavascriptConversion::IsCallable(function)),
"Can't call function when the script context is closed");
if (scriptContext->GetThreadContext()->IsScriptActive())
{
return;
}
if (function->IsExternal())
{
return;
}
Js::TypeId typeId = Js::JavascriptOperators::GetTypeId(function);
if (typeId == Js::TypeIds_HostDispatch)
{
AssertMsg(false, "Has to go through CallRootFunction to start calling Javascript function");
}
else if (typeId == Js::TypeId::TypeIds_Function)
{
if (((Js::JavascriptFunction*)function)->IsExternalFunction())
{
return;
}
else if (((Js::JavascriptFunction*)function)->IsWinRTFunction())
{
return;
}
else
{
AssertMsg(false, "Has to go through CallRootFunction to start calling Javascript function");
}
}
else
{
AssertMsg(false, "Has to go through CallRootFunction to start calling Javascript function");
}
}
#endif
#ifdef PROFILE_EXEC
void
CreateProfilerNativeCodeGen(NativeCodeGenerator * nativeCodeGen, Js::ScriptContextProfiler * profiler)
{
nativeCodeGen->CreateProfiler(profiler);
}
void
ProfilePrintNativeCodeGen(NativeCodeGenerator * nativeCodeGen)
{
nativeCodeGen->ProfilePrint();
}
void
SetProfilerFromNativeCodeGen(NativeCodeGenerator * toNativeCodeGen, NativeCodeGenerator * fromNativeCodeGen)
{
toNativeCodeGen->SetProfilerFromNativeCodeGen(fromNativeCodeGen);
}
#endif
void DeleteNativeCodeData(NativeCodeData * data)
{
if (data)
{
HeapDelete(data);
}
}