Browse Source

* Make sure TTextEncoder always operates on non-shared mem

Michael Van Canneyt 6 months ago
parent
commit
fa88ecbe08

+ 2 - 2
packages/job/src/job_browser.pp

@@ -360,7 +360,7 @@ begin
       enc:='utf-16be';
     FDecoderUTF16:=TJSTextDecoder.New(enc);
     end;
-  Result:=FDecoderUTF16.decode(Arr);
+  Result:=FDecoderUTF16.decode(SharedToNonShared(Arr));
 end;
 
 function TJSObjectBridge.DecodeUTF8Buffer(Arr: TJSUint8Array): String;
@@ -368,7 +368,7 @@ function TJSObjectBridge.DecodeUTF8Buffer(Arr: TJSUint8Array): String;
 begin
   if FDecoderUTF8=Nil then
     FDecoderUTF8:=TJSTextDecoder.New('utf8');
-  Result:=FDecoderUTF8.decode(Arr);
+  Result:=FDecoderUTF8.decode(SharedToNonShared(Arr));
 end;
 
 procedure TJSObjectBridge.SetArrayFromMem(ObjId: TJOBObjectID; Mem : TWasmPointer; aMaxLen : NativeInt);

+ 39 - 0
packages/rtl/src/js.pas

@@ -606,6 +606,7 @@ type
     property length : NativeInt Read FLength;
     property values[Index : NativeInt] : JSValue Read getValue Write SetValue; default;
   end;
+  TJSTypedArrayClass = Class of TJSTypedArray;
 
   { TJSInt8Array }
 
@@ -1207,6 +1208,10 @@ Type
 
 Function GetValueType(JS : JSValue) : TJSValueType;
 
+Function HaveSharedArrayBuffer : Boolean;
+Function SharedToNonShared(aBuffer : TJSAbstractArrayBuffer) : TJSArrayBuffer;
+Function SharedToNonShared(aArray : TJSTypedArray; aWordSized : Boolean = False) : TJSTypedArray;
+
 Const
   Null : JSValue; external name 'null';
   Undefined : JSValue; external name 'undefined';
@@ -1467,6 +1472,40 @@ begin
     end;
 end;
 
+Function HaveSharedArrayBuffer : Boolean; assembler;
+
+asm
+  return (typeof SharedArrayBuffer !== 'undefined');
+end;
+
+
+function SharedToNonShared(aBuffer: TJSAbstractArrayBuffer): TJSArrayBuffer;
+var
+  Src,Dest : TJSUint8Array;
+begin
+  if HaveSharedArrayBuffer and (aBuffer is TJSSharedArrayBuffer) then
+    begin
+    Result:=TJSArrayBuffer.new(aBuffer.byteLength);
+    Src:=TJSUint8Array.New(aBuffer);
+    Dest:=TJSUint8Array.New(Result);
+    Dest._set(Src);
+    end
+  else
+    Result:=TJSArrayBuffer(aBuffer);
+end;
+
+function SharedToNonShared(aArray : TJSTypedArray; aWordSized : Boolean = False): TJSTypedArray;
+
+begin
+  if HaveSharedArrayBuffer and (aArray.bufferObj is TJSSharedArrayBuffer) then
+    if aWordSized then
+      Result:=TJSUInt16Array.New(SharedToNonShared(aArray.bufferObj))
+    else
+      Result:=TJSUInt8Array.New(SharedToNonShared(aArray.bufferObj))
+  else
+    Result:=aArray;
+end;
+
 function Symbol : TJSSymbol; assembler;
 asm
   return Symbol();

+ 6 - 27
packages/wasi/src/wasienv.pas

@@ -2320,42 +2320,21 @@ end;
 function TPas2JSWASIEnvironment.GetUTF8StringFromArray(aSourceArray:TJSUint8Array): String;
 
 var
-  src : TJSSharedArrayBuffer;
-  tmpBuf: TJSAbstractArrayBuffer;
-  SrcBytes,tmpBytes : TJSUint8Array;
+ TmpBytes : TJSTypedArray;
 
 begin
-  if isDefined(Self_['SharedArrayBuffer']) and (aSourceArray.bufferObj is TJSSharedArrayBuffer) then
-    begin
-    src:=TJSSharedArrayBuffer(aSourceArray.bufferObj);
-    SrcBytes:=TJSUint8Array.new(src);
-    tmpBuf:=TJSArrayBuffer.new(Src.byteLength);
-    tmpBytes:=TJSUint8Array.new(tmpBuf);
-    tmpBytes._set(SrcBytes);
-    Result:=UTF8TextDecoder.Decode(tmpBytes);
-    end
-  else
-    Result:=UTF8TextDecoder.Decode(aSourceArray.Buffer);
+  TmpBytes:=SharedToNonShared(aSourceArray);
+  Result:=UTF8TextDecoder.Decode(tmpBytes);
 end;
 
 function TPas2JSWASIEnvironment.GetUTF8StringFromMem(aLoc, aLen: Longint): String;
 
 var
-  src,tmpBuf : TJSArrayBuffer;
-  SrcBytes,tmpBytes : TJSUint8Array;
+  tmpBuf : TJSArrayBuffer;
 
 begin
-  if isDefined(Self_['SharedArrayBuffer']) and (getModuleMemoryDataView.bufferObj is TJSSharedArrayBuffer) then
-    begin
-    src:=getModuleMemoryDataView.buffer.slice(aLoc,aLoc+alen);
-    SrcBytes:=TJSUint8Array.new(src);
-    tmpBuf:=TJSArrayBuffer.new(aLen);
-    tmpBytes:=TJSUint8Array.new(tmpBuf);
-    tmpBytes._set(SrcBytes);
-    Result:=UTF8TextDecoder.Decode(tmpBuf);
-    end
-  else
-    Result:=UTF8TextDecoder.Decode(getModuleMemoryDataView.buffer.slice(aLoc,aLoc+alen));
+  tmpBuf:=SharedToNonShared(getModuleMemoryDataView.buffer.slice(aLoc,aLoc+alen));
+  Result:=UTF8TextDecoder.Decode(tmpBuf);
 end;
 
 function TPas2JSWASIEnvironment.GetUTF8ByteLength(const AString: String) : Integer;

+ 1 - 1
packages/wasm-utils/src/wasm.pas2js.websocketapi.pas

@@ -444,7 +444,7 @@ begin
     lSocket.SendBinary(lData)
   else
     begin
-    lText:=FDecoder.Decode(lData);
+    lText:=FDecoder.Decode(SharedToNonShared(lData));
     lSocket.SendText(lText);
     end;
   Result:=WASMWS_RESULT_SUCCESS;