{ This file is part of the Fresnel Library. Copyright (c) 2025 by the FPC & Lazarus teams. Pas2js Fresnel interface - Webassembly rendering API See the file COPYING.modifiedLGPL.txt, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} unit importextensionex.pas2js.wasmapi; {$mode ObjFPC} interface uses JS, WebOrWorker, wasienv, webassembly; type (* TImportExtension extended class that introduces - mechanism for cahing the DataView, to be extended with memory growth notification - methods to get/set utf16 strings from wasm memory without utf8 roundtrips *) { TImportExtensionEx } TImportExtensionEx = class (TImportExtension) private FWebAssemblyMemory : TJSArrayBuffer; FMemoryDataView : TJSDataView; FEnvMemoryDataView : TJSDataView; protected function GetUTF16FromMem(p : TWasmPointer; sizeInChars : Integer) : String; procedure SetUTF16ToMem(p : TWasmPointer; const text : String); procedure SetWebAssemblyMemory(aMemory : TJSArrayBuffer); function GetModuleMemoryDataView : TJSDataView; reintroduce; deprecated 'Use MemoryDataView'; function GetMemoryDataView : TJSDataView; public property MemoryDataView : TJSDataView read GetMemoryDataView; property WebAssemblyMemory : TJSArrayBuffer read FWebAssemblyMemory write SetWebAssemblyMemory; end; implementation { TImportExtensionEx } // GetUTF16FromMem // function TImportExtensionEx.GetUTF16FromMem(p: TWasmPointer; sizeInChars: Integer): String; begin Result:=Env.GetUTF16StringFromMem(P,SizeInChars); end; // SetUTF16ToMem // procedure TImportExtensionEx.SetUTF16ToMem(p: TWasmPointer; const text: String); begin Env.SetUTF16StringInMem(P,Text); end; // SetWebAssemblyMemory // procedure TImportExtensionEx.SetWebAssemblyMemory(aMemory: TJSArrayBuffer); begin if FWebAssemblyMemory = aMemory then Exit; FWebAssemblyMemory := aMemory; if aMemory <> nil then FMemoryDataView := TJSDataView.New(aMemory) else FMemoryDataView := nil; end; // GetModuleMemoryDataView // function TImportExtensionEx.GetModuleMemoryDataView: TJSDataView; begin Result := inherited getModuleMemoryDataView; end; // GetMemoryDataView // function TImportExtensionEx.GetMemoryDataView: TJSDataView; var envMemory : JSValue; envWebAssemblyMemory : TJSWebAssemblyMemory absolute envMemory; begin if FWebAssemblyMemory = nil then begin envMemory := InstanceExports.Memory; if envMemory then begin if (FEnvMemoryDataView = nil) or (FEnvMemoryDataView.buffer <> envWebAssemblyMemory.buffer) then FEnvMemoryDataView := TJSDataView.New(envWebAssemblyMemory.buffer); Exit(FEnvMemoryDataView); end else Console.error('Memory not accessible from this call chain'); end; Result := FMemoryDataView; end; end.