summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/d5/tengo/runtime/vm.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/d5/tengo/runtime/vm.go')
-rw-r--r--vendor/github.com/d5/tengo/runtime/vm.go63
1 files changed, 54 insertions, 9 deletions
diff --git a/vendor/github.com/d5/tengo/runtime/vm.go b/vendor/github.com/d5/tengo/runtime/vm.go
index dde52db5..07f6e530 100644
--- a/vendor/github.com/d5/tengo/runtime/vm.go
+++ b/vendor/github.com/d5/tengo/runtime/vm.go
@@ -642,9 +642,31 @@ func (v *VM) run() {
switch callee := value.(type) {
case *objects.Closure:
+ if callee.Fn.VarArgs {
+ // if the closure is variadic,
+ // roll up all variadic parameters into an array
+ realArgs := callee.Fn.NumParameters - 1
+ varArgs := numArgs - realArgs
+ if varArgs >= 0 {
+ numArgs = realArgs + 1
+ args := make([]objects.Object, varArgs)
+ spStart := v.sp - varArgs
+ for i := spStart; i < v.sp; i++ {
+ args[i-spStart] = v.stack[i]
+ }
+ v.stack[spStart] = &objects.Array{Value: args}
+ v.sp = spStart + 1
+ }
+ }
+
if numArgs != callee.Fn.NumParameters {
- v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
- callee.Fn.NumParameters, numArgs)
+ if callee.Fn.VarArgs {
+ v.err = fmt.Errorf("wrong number of arguments: want>=%d, got=%d",
+ callee.Fn.NumParameters-1, numArgs)
+ } else {
+ v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
+ callee.Fn.NumParameters, numArgs)
+ }
return
}
@@ -674,9 +696,31 @@ func (v *VM) run() {
v.sp = v.sp - numArgs + callee.Fn.NumLocals
case *objects.CompiledFunction:
+ if callee.VarArgs {
+ // if the closure is variadic,
+ // roll up all variadic parameters into an array
+ realArgs := callee.NumParameters - 1
+ varArgs := numArgs - realArgs
+ if varArgs >= 0 {
+ numArgs = realArgs + 1
+ args := make([]objects.Object, varArgs)
+ spStart := v.sp - varArgs
+ for i := spStart; i < v.sp; i++ {
+ args[i-spStart] = v.stack[i]
+ }
+ v.stack[spStart] = &objects.Array{Value: args}
+ v.sp = spStart + 1
+ }
+ }
+
if numArgs != callee.NumParameters {
- v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
- callee.NumParameters, numArgs)
+ if callee.VarArgs {
+ v.err = fmt.Errorf("wrong number of arguments: want>=%d, got=%d",
+ callee.NumParameters-1, numArgs)
+ } else {
+ v.err = fmt.Errorf("wrong number of arguments: want=%d, got=%d",
+ callee.NumParameters, numArgs)
+ }
return
}
@@ -707,9 +751,7 @@ func (v *VM) run() {
case objects.Callable:
var args []objects.Object
- for _, arg := range v.stack[v.sp-numArgs : v.sp] {
- args = append(args, arg)
- }
+ args = append(args, v.stack[v.sp-numArgs:v.sp]...)
ret, e := callee.Call(args...)
v.sp -= numArgs + 1
@@ -817,9 +859,12 @@ func (v *VM) run() {
val := v.stack[v.sp-numSelectors-1]
v.sp -= numSelectors + 1
- sp := v.curFrame.basePointer + localIndex
+ dst := v.stack[v.curFrame.basePointer+localIndex]
+ if obj, ok := dst.(*objects.ObjectPtr); ok {
+ dst = *obj.Value
+ }
- if e := indexAssign(v.stack[sp], val, selectors); e != nil {
+ if e := indexAssign(dst, val, selectors); e != nil {
v.err = e
return
}