@@ -357,23 +357,26 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
357
357
vm .push (out )
358
358
359
359
case OpCall1 :
360
- args := vm .getArgsForFunc (& fnArgsBuf , program , 1 )
360
+ var args []any
361
+ args , fnArgsBuf = vm .getArgsForFunc (fnArgsBuf , program , 1 )
361
362
out , err := program .functions [arg ](args ... )
362
363
if err != nil {
363
364
panic (err )
364
365
}
365
366
vm .push (out )
366
367
367
368
case OpCall2 :
368
- args := vm .getArgsForFunc (& fnArgsBuf , program , 2 )
369
+ var args []any
370
+ args , fnArgsBuf = vm .getArgsForFunc (fnArgsBuf , program , 2 )
369
371
out , err := program .functions [arg ](args ... )
370
372
if err != nil {
371
373
panic (err )
372
374
}
373
375
vm .push (out )
374
376
375
377
case OpCall3 :
376
- args := vm .getArgsForFunc (& fnArgsBuf , program , 3 )
378
+ var args []any
379
+ args , fnArgsBuf = vm .getArgsForFunc (fnArgsBuf , program , 3 )
377
380
out , err := program .functions [arg ](args ... )
378
381
if err != nil {
379
382
panic (err )
@@ -382,7 +385,8 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
382
385
383
386
case OpCallN :
384
387
fn := vm .pop ().(Function )
385
- args := vm .getArgsForFunc (& fnArgsBuf , program , arg )
388
+ var args []any
389
+ args , fnArgsBuf = vm .getArgsForFunc (fnArgsBuf , program , arg )
386
390
out , err := fn (args ... )
387
391
if err != nil {
388
392
panic (err )
@@ -391,12 +395,14 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
391
395
392
396
case OpCallFast :
393
397
fn := vm .pop ().(func (... any ) any )
394
- args := vm .getArgsForFunc (& fnArgsBuf , program , arg )
398
+ var args []any
399
+ args , fnArgsBuf = vm .getArgsForFunc (fnArgsBuf , program , arg )
395
400
vm .push (fn (args ... ))
396
401
397
402
case OpCallSafe :
398
403
fn := vm .pop ().(SafeFunction )
399
- args := vm .getArgsForFunc (& fnArgsBuf , program , arg )
404
+ var args []any
405
+ args , fnArgsBuf = vm .getArgsForFunc (fnArgsBuf , program , arg )
400
406
out , mem , err := fn (args ... )
401
407
if err != nil {
402
408
panic (err )
@@ -601,13 +607,13 @@ func (vm *VM) scope() *Scope {
601
607
// take "needed" elements from the buffer and populate them with vm.pop() in
602
608
// reverse order. Because the estimation can fall short, this function can
603
609
// occasionally make a new allocation.
604
- func (vm * VM ) getArgsForFunc (bufPtr * []any , program * Program , needed int ) []any {
605
- if needed == 0 || bufPtr == nil && program == nil {
606
- return nil
610
+ func (vm * VM ) getArgsForFunc (argsBuf []any , program * Program , needed int ) ( args []any , argsBufOut [] any ) {
611
+ if needed == 0 || program == nil {
612
+ return nil , argsBuf
607
613
}
608
614
609
615
// Step 1: fix estimations and preallocate
610
- if * bufPtr == nil {
616
+ if argsBuf == nil {
611
617
estimatedFnArgsCount := estimateFnArgsCount (program )
612
618
if estimatedFnArgsCount < needed {
613
619
// in the case that the first call is for example OpCallN with a large
@@ -617,24 +623,24 @@ func (vm *VM) getArgsForFunc(bufPtr *[]any, program *Program, needed int) []any
617
623
}
618
624
619
625
// in the case that we are preparing the arguments for the first
620
- // function call of the program, then *bufPtr will be nil, so we
626
+ // function call of the program, then argsBuf will be nil, so we
621
627
// initialize it. We delay this initial allocation here because a
622
628
// program could have many function calls but exit earlier than the
623
629
// first call, so in that case we avoid allocating unnecessarily
624
- * bufPtr = make ([]any , estimatedFnArgsCount )
630
+ argsBuf = make ([]any , estimatedFnArgsCount )
625
631
}
626
632
627
633
// Step 2: get the final slice that will be returned
628
634
var buf []any
629
- if len (* bufPtr ) >= needed {
635
+ if len (argsBuf ) >= needed {
630
636
// in this case, we are successfully using the single preallocation. We
631
637
// use the full slice expression [low : high : max] because in that way
632
638
// a function that receives this slice as variadic arguments will not be
633
639
// able to make modifications to contiguous elements with append(). If
634
640
// they call append on their variadic arguments they will make a new
635
641
// allocation.
636
- buf = (* bufPtr )[:needed :needed ]
637
- * bufPtr = (* bufPtr )[needed :] // advance the buffer
642
+ buf = (argsBuf )[:needed :needed ]
643
+ argsBuf = (argsBuf )[needed :] // advance the buffer
638
644
} else {
639
645
// if we have been making calls to something like OpCallN with many more
640
646
// arguments than what we estimated, then we will need to allocate
@@ -647,7 +653,7 @@ func (vm *VM) getArgsForFunc(bufPtr *[]any, program *Program, needed int) []any
647
653
copy (buf , vm .Stack [len (vm .Stack )- needed :])
648
654
vm .Stack = vm .Stack [:len (vm .Stack )- needed ]
649
655
650
- return buf
656
+ return buf , argsBuf
651
657
}
652
658
653
659
func (vm * VM ) Step () {
0 commit comments