//------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #include "RuntimeLanguagePch.h" #include "WebAssemblySource.h" #ifdef ENABLE_WASM namespace Js { WebAssemblySource::WebAssemblySource(Var source, bool createNewContext, ScriptContext * scriptContext) : buffer(nullptr), bufferLength(0), sourceInfo(nullptr) { ReadBufferSource(source, scriptContext); CreateSourceInfo(createNewContext, scriptContext); } WebAssemblySource::WebAssemblySource(byte* source, uint bufferLength, bool createNewContext, ScriptContext* scriptContext): buffer(source), bufferLength(bufferLength) { CreateSourceInfo(createNewContext, scriptContext); } void WebAssemblySource::ReadBufferSource(Var val, ScriptContext * scriptContext) { BYTE* srcBuffer; if (Js::TypedArrayBase::Is(val)) { Js::TypedArrayBase* array = Js::TypedArrayBase::FromVar(val); srcBuffer = array->GetByteBuffer(); bufferLength = array->GetByteLength(); } else if (Js::ArrayBuffer::Is(val)) { Js::ArrayBuffer* arrayBuffer = Js::ArrayBuffer::FromVar(val); srcBuffer = arrayBuffer->GetBuffer(); bufferLength = arrayBuffer->GetByteLength(); } else { // The buffer was not a TypedArray nor an ArrayBuffer JavascriptError::ThrowTypeError(scriptContext, WASMERR_NeedBufferSource); } Assert(srcBuffer || bufferLength == 0); if (bufferLength > 0) { // copy buffer so external changes to it don't cause issues when defer parsing buffer = RecyclerNewArrayLeaf(scriptContext->GetRecycler(), byte, bufferLength); js_memcpy_s(buffer, bufferLength, srcBuffer, bufferLength); } } void WebAssemblySource::CreateSourceInfo(bool createNewContext, ScriptContext* scriptContext) { SRCINFO si = { /* sourceContextInfo */ nullptr, /* dlnHost */ 0, /* ulColumnHost */ 0, /* lnMinHost */ 0, /* ichMinHost */ 0, /* ichLimHost */ 0, /* ulCharOffset */ 0, /* mod */ 0, /* grfsi */ 0 }; SRCINFO const * srcInfo = scriptContext->Cache()->noContextGlobalSourceInfo; if (createNewContext && CONFIG_FLAG(WasmAssignModuleID)) { // It is not legal to assign a SourceContextInfo on dynamic code, but it is usefull for debugging // Only do it if the specified as a test config si.sourceContextInfo = scriptContext->CreateSourceContextInfo(scriptContext->GetNextSourceContextId(), nullptr, 0, nullptr); srcInfo = &si; } // Note: We don't have real "source info" for Wasm. Following are just placeholders. // Hack: Wasm handles debugging differently. Fake this as "LibraryCode" so that // normal script debugging code ignores this source info and its functions. const int32 cchLength = static_cast(bufferLength / sizeof(char16)); sourceInfo = Utf8SourceInfo::NewWithNoCopy( scriptContext, (LPCUTF8)buffer, cchLength, bufferLength, srcInfo, /*isLibraryCode*/true); scriptContext->SaveSourceNoCopy(sourceInfo, cchLength, /*isCesu8*/false); } } #endif