Skip to content

Commit

Permalink
Added support for native functions with *Runtime as a parameter. See #…
Browse files Browse the repository at this point in the history
  • Loading branch information
dop251 committed Jan 13, 2021
1 parent 952c20e commit 06e9948
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
14 changes: 14 additions & 0 deletions runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,8 @@ func(FunctionCall) Value is treated as a native JavaScript function. This increa
automatic argument and return value type conversions (which involves reflect). Attempting to use
the function as a constructor will result in a TypeError.
func(FunctionCall, *Runtime) Value is treated as above, except the *Runtime is also passed as a parameter.
func(ConstructorCall) *Object is treated as a native constructor, allowing to use it with the new
operator:
Expand Down Expand Up @@ -1327,6 +1329,8 @@ When a native constructor is called directly (without the new operator) its beha
this value: if it's an Object, it is passed through, otherwise a new one is created exactly as
if it was called with the new operator. In either case call.NewTarget will be nil.
func(ConstructorCall, *Runtime) *Object is treated as above, except the *Runtime is also passed as a parameter.
Any other Go function is wrapped so that the arguments are automatically converted into the required Go types and the
return value is converted to a JavaScript value (using this method). If conversion is not possible, a TypeError is
thrown.
Expand Down Expand Up @@ -1449,9 +1453,19 @@ func (r *Runtime) ToValue(i interface{}) Value {
case func(FunctionCall) Value:
name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
return r.newNativeFunc(i, nil, name, nil, 0)
case func(FunctionCall, *Runtime) Value:
name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
return r.newNativeFunc(func(call FunctionCall) Value {
return i(call, r)
}, nil, name, nil, 0)
case func(ConstructorCall) *Object:
name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
return r.newNativeConstructor(i, name, 0)
case func(ConstructorCall, *Runtime) *Object:
name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
return r.newNativeConstructor(func(call ConstructorCall) *Object {
return i(call, r)
}, name, 0)
case int:
return intToValue(int64(i))
case int8:
Expand Down
17 changes: 17 additions & 0 deletions runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,23 @@ func TestRuntime_SetParserOptions_Eval(t *testing.T) {
}
}

func TestNativeCallWithRuntimeParameter(t *testing.T) {
vm := New()
vm.Set("f", func(_ FunctionCall, r *Runtime) Value {
if r == vm {
return valueTrue
}
return valueFalse
})
ret, err := vm.RunString(`f()`)
if err != nil {
t.Fatal(err)
}
if ret != valueTrue {
t.Fatal(ret)
}
}

/*
func TestArrayConcatSparse(t *testing.T) {
function foo(a,b,c)
Expand Down

0 comments on commit 06e9948

Please sign in to comment.