Browse Source

Added support for native functions with *Runtime as a parameter. See #243

Dmitry Panov 4 years ago
parent
commit
06e99480d2
2 changed files with 31 additions and 0 deletions
  1. 14 0
      runtime.go
  2. 17 0
      runtime_test.go

+ 14 - 0
runtime.go

@@ -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
 automatic argument and return value type conversions (which involves reflect). Attempting to use
 the function as a constructor will result in a TypeError.
 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
 func(ConstructorCall) *Object is treated as a native constructor, allowing to use it with the new
 operator:
 operator:
 
 
@@ -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
 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.
 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
 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
 return value is converted to a JavaScript value (using this method).  If conversion is not possible, a TypeError is
 thrown.
 thrown.
@@ -1449,9 +1453,19 @@ func (r *Runtime) ToValue(i interface{}) Value {
 	case func(FunctionCall) Value:
 	case func(FunctionCall) Value:
 		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
 		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
 		return r.newNativeFunc(i, nil, name, nil, 0)
 		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:
 	case func(ConstructorCall) *Object:
 		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
 		name := unistring.NewFromString(runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name())
 		return r.newNativeConstructor(i, name, 0)
 		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:
 	case int:
 		return intToValue(int64(i))
 		return intToValue(int64(i))
 	case int8:
 	case int8:

+ 17 - 0
runtime_test.go

@@ -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) {
 func TestArrayConcatSparse(t *testing.T) {
 function foo(a,b,c)
 function foo(a,b,c)