Browse Source

Fixed reflect conversion to Value (fixes #32)

Dmitry Panov 8 years ago
parent
commit
d1f41622ac
2 changed files with 46 additions and 7 deletions
  1. 5 7
      runtime.go
  2. 41 0
      runtime_test.go

+ 5 - 7
runtime.go

@@ -18,6 +18,7 @@ const (
 
 var (
 	typeCallable = reflect.TypeOf(Callable(nil))
+	typeValue    = reflect.TypeOf((*Value)(nil)).Elem()
 )
 
 type global struct {
@@ -1121,6 +1122,10 @@ func (r *Runtime) toReflectValue(v Value, typ reflect.Type) (reflect.Value, erro
 		}
 	}
 
+	if typ.Implements(typeValue) {
+		return reflect.ValueOf(v), nil
+	}
+
 	et := v.ExportType()
 	if et == nil {
 		return reflect.Zero(typ), nil
@@ -1131,13 +1136,6 @@ func (r *Runtime) toReflectValue(v Value, typ reflect.Type) (reflect.Value, erro
 		return reflect.ValueOf(v.Export()).Convert(typ), nil
 	}
 
-	t := reflect.TypeOf(v)
-	if t.AssignableTo(typ) {
-		return reflect.ValueOf(v), nil
-	} else if t.ConvertibleTo(typ) {
-		return reflect.ValueOf(v).Convert(typ), nil
-	}
-
 	switch typ.Kind() {
 	case reflect.Slice:
 		if o, ok := v.(*Object); ok {

+ 41 - 0
runtime_test.go

@@ -893,6 +893,19 @@ func TestReflectCallVariadic(t *testing.T) {
 	}
 }
 
+func TestReflectNullValueArgument(t *testing.T) {
+	rt := New()
+	rt.Set("fn", func(v Value) {
+		if v == nil {
+			t.Error("null becomes nil")
+		}
+		if !IsNull(v) {
+			t.Error("null is not null")
+		}
+	})
+	rt.RunString(`fn(null);`)
+}
+
 /*
 func TestArrayConcatSparse(t *testing.T) {
 function foo(a,b,c)
@@ -915,3 +928,31 @@ function foo(a,b,c)
 	testScript1(SCRIPT, valueTrue, t)
 }
 */
+
+func BenchmarkCallReflect(b *testing.B) {
+	vm := New()
+	vm.Set("f", func(v Value) {
+
+	})
+
+	prg := MustCompile("test.js", "f(null)", true)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		vm.RunProgram(prg)
+	}
+}
+
+func BenchmarkCallNative(b *testing.B) {
+	vm := New()
+	vm.Set("f", func(call FunctionCall) (ret Value) {
+		return
+	})
+
+	prg := MustCompile("test.js", "f(null)", true)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		vm.RunProgram(prg)
+	}
+}