aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/common/whwasmutil.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/common/whwasmutil.js')
-rw-r--r--ext/wasm/common/whwasmutil.js37
1 files changed, 22 insertions, 15 deletions
diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js
index 8cb483324..9bce82f1a 100644
--- a/ext/wasm/common/whwasmutil.js
+++ b/ext/wasm/common/whwasmutil.js
@@ -725,11 +725,12 @@ self.WhWasmUtilInstaller = function(target){
Expects ptr to be a pointer into the WASM heap memory which
refers to a NUL-terminated C-style string encoded as UTF-8.
Returns the length, in bytes, of the string, as for `strlen(3)`.
- As a special case, if !ptr then it it returns `null`. Throws if
- ptr is out of range for target.heap8u().
+ As a special case, if !ptr or if it's not a pointer then it
+ returns `null`. Throws if ptr is out of range for
+ target.heap8u().
*/
target.cstrlen = function(ptr){
- if(!ptr) return null;
+ if(!ptr || !target.isPtr(ptr)) return null;
const h = heapWrappers().HEAP8U;
let pos = ptr;
for( ; h[pos] !== 0; ++pos ){}
@@ -753,7 +754,7 @@ self.WhWasmUtilInstaller = function(target){
refers to a NUL-terminated C-style string encoded as UTF-8. This
function counts its byte length using cstrlen() then returns a
JS-format string representing its contents. As a special case, if
- ptr is falsy, `null` is returned.
+ ptr is falsy or not a pointer, `null` is returned.
*/
target.cstringToJs = function(ptr){
const n = target.cstrlen(ptr);
@@ -1081,10 +1082,9 @@ self.WhWasmUtilInstaller = function(target){
// impl for allocMainArgv() and scopedAllocMainArgv().
const __allocMainArgv = function(isScoped, list){
- if(!list.length) toss("Cannot allocate empty array.");
const pList = target[
isScoped ? 'scopedAlloc' : 'alloc'
- ](list.length * target.ptrSizeof);
+ ]((list.length + 1) * target.ptrSizeof);
let i = 0;
list.forEach((e)=>{
target.setPtrValue(pList + (target.ptrSizeof * i++),
@@ -1092,26 +1092,33 @@ self.WhWasmUtilInstaller = function(target){
isScoped ? 'scopedAllocCString' : 'allocCString'
](""+e));
});
+ target.setPtrValue(pList + (target.ptrSizeof * i), 0);
return pList;
};
/**
Creates an array, using scopedAlloc(), suitable for passing to a
C-level main() routine. The input is a collection with a length
- property and a forEach() method. A block of memory list.length
- entries long is allocated and each pointer-sized block of that
- memory is populated with a scopedAllocCString() conversion of the
- (""+value) of each element. Returns a pointer to the start of the
- list, suitable for passing as the 2nd argument to a C-style
- main() function.
-
- Throws if list.length is falsy or scopedAllocPush() is not active.
+ property and a forEach() method. A block of memory
+ (list.length+1) entries long is allocated and each pointer-sized
+ block of that memory is populated with a scopedAllocCString()
+ conversion of the (""+value) of each element, with the exception
+ that the final entry is a NULL pointer. Returns a pointer to the
+ start of the list, suitable for passing as the 2nd argument to a
+ C-style main() function.
+
+ Throws if scopedAllocPush() is not active.
+
+ Design note: the returned array is allocated with an extra NULL
+ pointer entry to accommodate certain APIs, but client code which
+ does not need that functionality should treat the returned array
+ as list.length entries long.
*/
target.scopedAllocMainArgv = (list)=>__allocMainArgv(true, list);
/**
Identical to scopedAllocMainArgv() but uses alloc() instead of
- scopedAllocMainArgv
+ scopedAlloc().
*/
target.allocMainArgv = (list)=>__allocMainArgv(false, list);