-
-
Notifications
You must be signed in to change notification settings - Fork 655
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial newArray and getArray helpers to loader
Essentially creates an unmanaged typed array in memory that one can work with and free again respectively obtain from the AS side. No support for GC or generic arrays yet, and is likely to change substentially once WASM GC becomes a thing.
- Loading branch information
Showing
11 changed files
with
132 additions
and
9 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,9 @@ function instantiate(module, imports) { | |
// Instantiate the module and obtain its (flat) exports | ||
var instance = new WebAssembly.Instance(module, imports); | ||
var exports = instance.exports; | ||
var memory_allocate = exports["memory.allocate"]; | ||
var memory_fill = exports["memory.fill"]; | ||
var memory_free = exports["memory.free"]; | ||
|
||
// Provide views for all sorts of basic values | ||
var mem, I8, U8, I16, U16, I32, U32, F32, F64, I64, U64; | ||
|
@@ -45,7 +48,7 @@ function instantiate(module, imports) { | |
/** Allocates a new string in the module's memory and returns its pointer. */ | ||
function newString(str) { | ||
var dataLength = str.length; | ||
var ptr = exports["memory.allocate"](4 + (dataLength << 1)); | ||
var ptr = memory_allocate(4 + (dataLength << 1)); | ||
var dataOffset = (4 + ptr) >>> 1; | ||
checkMem(); | ||
U32[ptr >>> 2] = dataLength; | ||
|
@@ -71,6 +74,62 @@ function instantiate(module, imports) { | |
return parts.join("") + String.fromCharCode.apply(String, U16.subarray(dataOffset, dataOffset + dataRemain)); | ||
} | ||
|
||
function computeBufferSize(byteLength) { | ||
const HEADER_SIZE = 8; | ||
return 1 << (32 - Math.clz32(byteLength + HEADER_SIZE - 1)); | ||
} | ||
|
||
/** Creates a new typed array in the module's memory and returns its pointer. */ | ||
function newArray(view, length, unsafe) { | ||
var ctor = view.constructor; | ||
if (ctor === Function) { // TypedArray constructor created in memory | ||
ctor = view; | ||
view = null; | ||
} else { // TypedArray instance copied into memory | ||
if (length === undefined) length = view.length; | ||
} | ||
var elementSize = ctor.BYTES_PER_ELEMENT; | ||
if (!elementSize) throw Error("not a typed array"); | ||
var byteLength = elementSize * length; | ||
var ptr = memory_allocate(12); // TypedArray header | ||
var buf = memory_allocate(computeBufferSize(byteLength)); // ArrayBuffer | ||
checkMem(); | ||
U32[ ptr >>> 2] = buf; // .buffer | ||
U32[(ptr + 4) >>> 2] = 0; // .byteOffset | ||
U32[(ptr + 8) >>> 2] = byteLength; // .byteLength | ||
U32[ buf >>> 2] = byteLength; // .byteLength | ||
U32[(buf + 4) >>> 2] = 0; // 0 | ||
if (view) { | ||
new ctor(mem, buf + 8, length).set(view); | ||
if (view.length < length && !unsafe) { | ||
let setLength = elementSize * view.length; | ||
memory_fill(buf + 8 + setLength, 0, byteLength - setLength); | ||
} | ||
} else if (!unsafe) { | ||
memory_fill(buf + 8, 0, byteLength); | ||
} | ||
return ptr; | ||
} | ||
|
||
/** Gets a view on a typed array in the module's memory by its pointer. */ | ||
function getArray(ctor, ptr) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
dcodeIO
Author
Member
|
||
var elementSize = ctor.BYTES_PER_ELEMENT; | ||
if (!elementSize) throw Error("not a typed array"); | ||
checkMem(); | ||
var buf = U32[ ptr >>> 2]; | ||
var byteOffset = U32[(ptr + 4) >>> 2]; | ||
var byteLength = U32[(ptr + 8) >>> 2]; | ||
return new ctor(mem, buf + 8 + byteOffset, (byteLength - byteOffset) / elementSize); | ||
} | ||
|
||
/** Frees a typed array in the module's memory. Must not be accessed anymore afterwards. */ | ||
function freeArray(ptr) { | ||
checkMem(); | ||
var buf = U32[ptr >>> 2]; | ||
memory_free(buf); | ||
memory_free(ptr); | ||
} | ||
|
||
// Demangle exports and provide the usual utility on the prototype | ||
return demangle(exports, { | ||
get I8() { checkMem(); return I8; }, | ||
|
@@ -84,7 +143,10 @@ function instantiate(module, imports) { | |
get F32() { checkMem(); return F32; }, | ||
get F64() { checkMem(); return F64; }, | ||
newString, | ||
getString | ||
getString, | ||
newArray, | ||
getArray, | ||
freeArray | ||
}); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Interesting that this method does not work with Uint32Arrays/Float64Arrays on my side.
The code I have is:
→
Whereas the version suggested by @vdeturckheim works fine
Maybe there should be test-cases for that?
@dcodeIO