@@ -211,6 +211,7 @@ func ValueOf(x any) Value {
211
211
}
212
212
213
213
//go:wasmimport gojs syscall/js.stringVal
214
+ //go:noescape
214
215
func stringVal (x string ) ref
215
216
216
217
// Type represents the JavaScript type of a Value.
@@ -295,6 +296,7 @@ func (v Value) Get(p string) Value {
295
296
}
296
297
297
298
//go:wasmimport gojs syscall/js.valueGet
299
+ //go:noescape
298
300
func valueGet (v ref , p string ) ref
299
301
300
302
// Set sets the JavaScript property p of value v to ValueOf(x).
@@ -310,6 +312,7 @@ func (v Value) Set(p string, x any) {
310
312
}
311
313
312
314
//go:wasmimport gojs syscall/js.valueSet
315
+ //go:noescape
313
316
func valueSet (v ref , p string , x ref )
314
317
315
318
// Delete deletes the JavaScript property p of value v.
@@ -323,6 +326,7 @@ func (v Value) Delete(p string) {
323
326
}
324
327
325
328
//go:wasmimport gojs syscall/js.valueDelete
329
+ //go:noescape
326
330
func valueDelete (v ref , p string )
327
331
328
332
// Index returns JavaScript index i of value v.
@@ -354,15 +358,29 @@ func (v Value) SetIndex(i int, x any) {
354
358
//go:wasmimport gojs syscall/js.valueSetIndex
355
359
func valueSetIndex (v ref , i int , x ref )
356
360
357
- func makeArgs (args []any ) ([]Value , []ref ) {
358
- argVals := make ([]Value , len (args ))
359
- argRefs := make ([]ref , len (args ))
361
+ func makeArgs (args []any ) (argVals []Value , argRefs []ref ) {
362
+ // value chosen for being power of two, and enough to handle all web APIs
363
+ // in particular, note that WebGL2's texImage2D takes up to 10 arguments
364
+ const maxStackArgs = 16
365
+ if len (args ) <= maxStackArgs {
366
+ // as long as makeArgs is inlined, these will be stack-allocated
367
+ argVals = make ([]Value , len (args ), maxStackArgs )
368
+ argRefs = make ([]ref , len (args ), maxStackArgs )
369
+ } else {
370
+ // allocates on the heap, but exceeding maxStackArgs should be rare
371
+ argVals = make ([]Value , len (args ))
372
+ argRefs = make ([]ref , len (args ))
373
+ }
374
+ return
375
+ }
376
+
377
+ func storeArgs (args []any , argValsDst []Value , argRefsDst []ref ) {
378
+ // would go in makeArgs if the combined func was simple enough to inline
360
379
for i , arg := range args {
361
380
v := ValueOf (arg )
362
- argVals [i ] = v
363
- argRefs [i ] = v .ref
381
+ argValsDst [i ] = v
382
+ argRefsDst [i ] = v .ref
364
383
}
365
- return argVals , argRefs
366
384
}
367
385
368
386
// Length returns the JavaScript property "length" of v.
@@ -384,6 +402,7 @@ func valueLength(v ref) int
384
402
// The arguments get mapped to JavaScript values according to the ValueOf function.
385
403
func (v Value ) Call (m string , args ... any ) Value {
386
404
argVals , argRefs := makeArgs (args )
405
+ storeArgs (args , argVals , argRefs )
387
406
res , ok := valueCall (v .ref , m , argRefs )
388
407
runtime .KeepAlive (v )
389
408
runtime .KeepAlive (argVals )
@@ -401,13 +420,15 @@ func (v Value) Call(m string, args ...any) Value {
401
420
402
421
//go:wasmimport gojs syscall/js.valueCall
403
422
//go:nosplit
423
+ //go:noescape
404
424
func valueCall (v ref , m string , args []ref ) (ref , bool )
405
425
406
426
// Invoke does a JavaScript call of the value v with the given arguments.
407
427
// It panics if v is not a JavaScript function.
408
428
// The arguments get mapped to JavaScript values according to the ValueOf function.
409
429
func (v Value ) Invoke (args ... any ) Value {
410
430
argVals , argRefs := makeArgs (args )
431
+ storeArgs (args , argVals , argRefs )
411
432
res , ok := valueInvoke (v .ref , argRefs )
412
433
runtime .KeepAlive (v )
413
434
runtime .KeepAlive (argVals )
@@ -421,13 +442,15 @@ func (v Value) Invoke(args ...any) Value {
421
442
}
422
443
423
444
//go:wasmimport gojs syscall/js.valueInvoke
445
+ //go:noescape
424
446
func valueInvoke (v ref , args []ref ) (ref , bool )
425
447
426
448
// New uses JavaScript's "new" operator with value v as constructor and the given arguments.
427
449
// It panics if v is not a JavaScript function.
428
450
// The arguments get mapped to JavaScript values according to the ValueOf function.
429
451
func (v Value ) New (args ... any ) Value {
430
452
argVals , argRefs := makeArgs (args )
453
+ storeArgs (args , argVals , argRefs )
431
454
res , ok := valueNew (v .ref , argRefs )
432
455
runtime .KeepAlive (v )
433
456
runtime .KeepAlive (argVals )
@@ -597,4 +620,5 @@ func CopyBytesToJS(dst Value, src []byte) int {
597
620
}
598
621
599
622
//go:wasmimport gojs syscall/js.copyBytesToJS
623
+ //go:noescape
600
624
func copyBytesToJS (dst ref , src []byte ) (int , bool )
0 commit comments