@@ -1835,6 +1835,44 @@ if (!sourceList)
18351835 }
18361836 }
18371837
1838+ void WasmFunctionGenerateBytecode (AsmJsScriptFunction* func, bool propagateError)
1839+ {
1840+ FunctionBody* body = func->GetFunctionBody ();
1841+ AsmJsFunctionInfo* info = body->GetAsmJsFunctionInfo ();
1842+ ScriptContext* scriptContext = func->GetScriptContext ();
1843+
1844+ Js::FunctionEntryPointInfo * entypointInfo = (Js::FunctionEntryPointInfo*)func->GetEntryPointInfo ();
1845+ Wasm::WasmReaderInfo* readerInfo = info->GetWasmReaderInfo ();
1846+ info->SetWasmReaderInfo (nullptr );
1847+ try
1848+ {
1849+ Wasm::WasmBytecodeGenerator::GenerateFunctionBytecode (scriptContext, body, readerInfo);
1850+ func->GetDynamicType ()->SetEntryPoint (Js::AsmJsExternalEntryPoint);
1851+ entypointInfo->jsMethod = AsmJsDefaultEntryThunk;
1852+ // Do MTJRC/MAIC:0 check
1853+ #if ENABLE_DEBUG_CONFIG_OPTIONS
1854+ if (CONFIG_FLAG (ForceNative) || CONFIG_FLAG (MaxAsmJsInterpreterRunCount) == 0 )
1855+ {
1856+ GenerateFunction (scriptContext->GetNativeCodeGenerator (), func->GetFunctionBody (), func);
1857+ }
1858+ #endif
1859+ }
1860+ catch (Wasm::WasmCompilationException ex)
1861+ {
1862+ if (propagateError)
1863+ {
1864+ throw ;
1865+ }
1866+ Js::JavascriptLibrary *library = scriptContext->GetLibrary ();
1867+ Js::JavascriptError *pError = library->CreateError ();
1868+ Js::JavascriptError::SetErrorMessage (pError, JSERR_WasmCompileError, ex.ReleaseErrorMessage (), scriptContext);
1869+
1870+ func->GetDynamicType ()->SetEntryPoint (WasmLazyTrapCallback);
1871+ entypointInfo->jsMethod = WasmLazyTrapCallback;
1872+ func->SetLazyError (pError);
1873+ }
1874+ }
1875+
18381876 void WasmLoadFunctions (Wasm::WasmModule * wasmModule, ScriptContext* ctx, Var* moduleMemoryPtr, Var* exportObj, Var* localModuleFunctions, bool * hasAnyLazyTraps)
18391877 {
18401878 FrameDisplay * frameDisplay = RecyclerNewPlus (ctx->GetRecycler (), sizeof (void *), FrameDisplay, 1 );
@@ -1845,35 +1883,22 @@ if (!sourceList)
18451883 for (uint i = 0 ; i < wasmModule->funcCount ; ++i)
18461884 {
18471885 AsmJsScriptFunction * funcObj = ctx->GetLibrary ()->CreateAsmJsScriptFunction (functionArray[i]->body );
1848- funcObj->GetDynamicType ()->SetEntryPoint (AsmJsExternalEntryPoint);
18491886 funcObj->SetModuleMemory (moduleMemoryPtr);
18501887 FunctionEntryPointInfo * entypointInfo = (FunctionEntryPointInfo*)funcObj->GetEntryPointInfo ();
18511888 entypointInfo->SetIsAsmJSFunction (true );
1852- entypointInfo->jsMethod = AsmJsDefaultEntryThunk;
18531889 entypointInfo->SetModuleAddress ((uintptr_t )moduleMemoryPtr);
18541890 funcObj->SetEnvironment (frameDisplay);
18551891 localModuleFunctions[i] = funcObj;
1856-
1857- if (wasmModule-> lazyTraps && wasmModule-> lazyTraps [i] )
1892+
1893+ if (PHASE_ON (WasmDeferredPhase, funcObj-> GetFunctionBody ()) )
18581894 {
1859- Assert (PHASE_ON1 (WasmLazyTrapPhase));
1860- *hasAnyLazyTraps = true ;
1861- JavascriptLibrary *library = ctx->GetLibrary ();
1862- JavascriptError *pError = library->CreateError ();
1863- JavascriptError::SetErrorMessage (pError, JSERR_WasmCompileError, wasmModule->lazyTraps [i]->ReleaseErrorMessage (), ctx);
1864-
1865- funcObj->GetDynamicType ()->SetEntryPoint (WasmLazyTrapCallback);
1866- entypointInfo->jsMethod = WasmLazyTrapCallback;
1867- funcObj->SetLazyError (pError);
1868- continue ;
1895+ funcObj->GetDynamicType ()->SetEntryPoint (ScriptContext::WasmDeferredParseExternalThunk);
1896+ entypointInfo->jsMethod = ScriptContext::WasmDeferredParseInternalThunk;
18691897 }
1870- // Do MTJRC/MAIC:0 check
1871- #if ENABLE_DEBUG_CONFIG_OPTIONS
1872- if (CONFIG_FLAG (ForceNative) || CONFIG_FLAG (MaxAsmJsInterpreterRunCount) == 0 )
1898+ else
18731899 {
1874- GenerateFunction (ctx-> GetNativeCodeGenerator () , funcObj->GetFunctionBody (), funcObj );
1900+ WasmFunctionGenerateBytecode (funcObj, ! PHASE_ON (WasmLazyTrapPhase , funcObj->GetFunctionBody ()) );
18751901 }
1876- #endif
18771902 }
18781903 }
18791904
@@ -1996,8 +2021,7 @@ if (!sourceList)
19962021 uint funcIndex = wasmModule->info ->GetIndirectFunctionIndex (i);
19972022 if (funcIndex >= wasmModule->info ->GetFunctionCount ())
19982023 {
1999- // TODO: michhol give error messages
2000- Js::Throw::InternalError ();
2024+ throw Wasm::WasmCompilationException (_u (" Invalid function index %U for indirect function table" ), funcIndex);
20012025 }
20022026 Wasm::WasmFunctionInfo * indirFunc = wasmModule->info ->GetFunSig (funcIndex);
20032027 uint sigId = indirFunc->GetSignature ()->GetSignatureId ();
@@ -2011,6 +2035,72 @@ if (!sourceList)
20112035 }
20122036 }
20132037
2038+ #if _M_IX86
2039+ __declspec (naked)
2040+ Var ScriptContext::WasmDeferredParseExternalThunk(RecyclableObject* function, CallInfo callInfo, ...)
2041+ {
2042+ // Register functions
2043+ __asm
2044+ {
2045+ push ebp
2046+ mov ebp, esp
2047+ lea eax, [esp + 8 ]
2048+ push 0
2049+ push eax
2050+ call ScriptContext::WasmDeferredParseEntryPoint
2051+ #ifdef _CONTROL_FLOW_GUARD
2052+ // verify that the call target is valid
2053+ mov ecx, eax
2054+ call[__guard_check_icall_fptr]
2055+ mov eax, ecx
2056+ #endif
2057+ pop ebp
2058+ // Although we don't restore ESP here on WinCE, this is fine because script profiler is not shipped for WinCE.
2059+ jmp eax
2060+ }
2061+ }
2062+
2063+ __declspec (naked)
2064+ Var ScriptContext::WasmDeferredParseInternalThunk(RecyclableObject* function, CallInfo callInfo, ...)
2065+ {
2066+ // Register functions
2067+ __asm
2068+ {
2069+ push ebp
2070+ mov ebp, esp
2071+ lea eax, [esp + 8 ]
2072+ push 1
2073+ push eax
2074+ call ScriptContext::WasmDeferredParseEntryPoint
2075+ #ifdef _CONTROL_FLOW_GUARD
2076+ // verify that the call target is valid
2077+ mov ecx, eax
2078+ call[__guard_check_icall_fptr]
2079+ mov eax, ecx
2080+ #endif
2081+ pop ebp
2082+ // Although we don't restore ESP here on WinCE, this is fine because script profiler is not shipped for WinCE.
2083+ jmp eax
2084+ }
2085+ }
2086+ #elif defined(_M_X64)
2087+ // Do nothing: the implementation of ScriptContext::WasmDeferredParseExternalThunk is declared (appropriately decorated) in
2088+ // Language\amd64\amd64_Thunks.asm.
2089+ #endif
2090+
2091+ JavascriptMethod ScriptContext::WasmDeferredParseEntryPoint (AsmJsScriptFunction** funcPtr, int internalCall)
2092+ {
2093+ AsmJsScriptFunction* func = *funcPtr;
2094+
2095+ WasmFunctionGenerateBytecode (func, false );
2096+ Js::FunctionEntryPointInfo * entypointInfo = (Js::FunctionEntryPointInfo*)func->GetEntryPointInfo ();
2097+ if (internalCall)
2098+ {
2099+ return entypointInfo->jsMethod ;
2100+ }
2101+ return func->GetDynamicType ()->GetEntryPoint ();
2102+ }
2103+
20142104 char16* lastWasmExceptionMessage = nullptr ;
20152105
20162106 Var ScriptContext::LoadWasmScript (const char16* script, SRCINFO const * pSrcInfo, CompileScriptException * pse, bool isExpression, bool disableDeferredParse, bool isForNativeCode, Utf8SourceInfo** ppSourceInfo, const bool isBinary, const uint lengthBytes, const char16 *rootDisplayName, Js::Var ffi, Js::Var* start)
@@ -2025,7 +2115,7 @@ if (!sourceList)
20252115
20262116 Assert (!this ->threadContext ->IsScriptActive ());
20272117 Assert (pse != nullptr );
2028- Wasm::WasmBytecodeGenerator *bytecodeGen = nullptr ;
2118+ Wasm::WasmModuleGenerator *bytecodeGen = nullptr ;
20292119 Js::Var exportObj = nullptr ;
20302120 try
20312121 {
@@ -2040,7 +2130,7 @@ if (!sourceList)
20402130 }
20412131
20422132 *ppSourceInfo = Utf8SourceInfo::New (this , (LPCUTF8)script, lengthBytes / sizeof (char16), lengthBytes, pSrcInfo, false );
2043- bytecodeGen = HeapNew (Wasm::WasmBytecodeGenerator , this , *ppSourceInfo, (byte*)script, lengthBytes);
2133+ bytecodeGen = HeapNew (Wasm::WasmModuleGenerator , this , *ppSourceInfo, (byte*)script, lengthBytes);
20442134 wasmModule = bytecodeGen->GenerateModule ();
20452135
20462136 Var* moduleMemoryPtr = RecyclerNewArrayZ (GetRecycler (), Var, wasmModule->memSize );
0 commit comments