示例#1
0
func ReflectedSignature(ctx *Environment, f interface{}) (sig types.MethodSignature, err error) {
	sig.Return = types.Basic(types.UnspecKind)

	ftype := reflect.TypeOf(f)
	sig.Params = make([]types.Typed, 0)
	if ftype.Kind() != reflect.Func {
		err = errors.New("ReflectedSignature: f is not a function")
	}
	if err == nil && ftype.NumIn() < 2 {
		err = errors.New("ReflectedSignature: f is not a callback (insufficient args)")
	}
	if err == nil && ftype.NumOut() > 1 {
		err = errors.New("ReflectedSignature: f is not a callback (too many returns)")
	}
	if err == nil && ftype.In(0) != reflect.TypeOf(&Environment{}) {
		err = errors.New("bad first-arg Type: must be *Environment")
	}
	if err == nil && ftype.In(1) != reflect.TypeOf(&Object{}) {
		err = errors.New("bad second-arg Type: must be *Object")
	}
	if err != nil {
		return
	}
	for i := 2; i < ftype.NumIn(); i++ {
		var k types.Typed
		if ftype.In(i).Kind() == reflect.Ptr {
			if ftype.In(i) == reflect.TypeOf(&Object{}) {
				k = types.Class{types.JavaLangObject}
			} else {
				itype := ftype.In(i).Elem()
				pobj := reflect.New(itype).Interface()
				k, err = TypeOf(ctx, pobj)
			}
		} else {
			k, err = TypeOf(ctx, reflect.New(ftype.In(i)).Interface())
		}
		if err != nil {
			break
		}
		sig.Params = append(sig.Params, k)
	}
	if ftype.NumOut() == 1 {
		var k types.Typed
		k, err = reflectedType(ctx, reflect.New(ftype.Out(0)).Interface())
		if err == nil {
			sig.Return = k
		}
	} else {
		sig.Return = types.Basic(types.VoidKind)
	}
	return
}
示例#2
0
func reflectedType(env *Environment, v interface{}) (k types.Typed, err error) {
	vtype := reflect.TypeOf(v)
	vkind := vtype.Kind()
	switch vkind {
	case reflect.Ptr:
		k, err = TypeOf(env, reflect.Indirect(reflect.ValueOf(v)).Interface())
	case reflect.Bool:
		k = types.Basic(types.BoolKind)
	case reflect.Uint8, reflect.Int8:
		k = types.Basic(types.ByteKind)
	case reflect.Int16, reflect.Uint16:
		k = types.Basic(types.ShortKind)
	case reflect.Int32, reflect.Uint32:
		k = types.Basic(types.IntKind)
	case reflect.Uint64, reflect.Int64:
		k = types.Basic(types.LongKind)
	case reflect.Int, reflect.Uint:
		k = types.Basic(types.IntKind)
	case reflect.Float32:
		k = types.Basic(types.FloatKind)
	case reflect.Float64:
		k = types.Basic(types.DoubleKind)
	case reflect.Struct:
		k = types.Class{[]string{"golang", vkind.String()}}
	case reflect.String:
		k = types.Class{types.JavaLangString}
	case reflect.Slice, reflect.Array:
		sltype := vtype.Elem()
		switch sltype.Kind() {
		case reflect.Uint8:
			k = types.Array{types.Basic(types.ByteKind)}
		case reflect.String:
			k = types.Array{types.Class{types.JavaLangString}}
		default:
			err = errors.New("Unhandled slice type " + sltype.String())
		}
	default:
		switch T := v.(type) {
		default:
			err = errors.New(fmt.Sprintf("Unsure how to TypeOf '%s'/%T", vkind.String(), T))
		}
	}
	return
}
示例#3
0
func TestJVMTrivialClass(t *testing.T) {
	env := setupJVM(t)
	for i, test := range trivialClassTests {
		form, err := FormFor(env, types.Basic(types.VoidKind), test.ConstArgs...)
		fatalIf(t, err != nil, "[%d] Error generating formFor: %v", i, err)
		fatalIf(t, form == "", "Got nil form")
		klass, err := env.NewInstanceStr(TrivialClass, test.ConstArgs...)
		fatalIf(t, err != nil, "[%d] Error generating formFor: %v", i, err)
		kused, _, err := klass.CallString(env, false, "getConstructorUsed")
		fatalIf(t, err != nil, "[%d] Error getting constructor used: %v", i, err)
		fatalIf(t, kused != form, "[%d] Constructor called was wrong (Exp: %s, got: %s)", form, kused)

	}
}
示例#4
0
func (self *Environment) callVoid(z interface{}, static bool, name string, params ...interface{}) (err error) {
	jval, meth, args, localStack, err := self.getMethod(z, static, name, types.Basic(types.VoidKind), params...)
	if err != nil {
		return
	}
	defer blowStack(self, localStack)
	if static {
		C.envCallStaticVoidMethodA(self.env, C.valObject(jval), meth.method, args.Ptr())
	} else {
		C.envCallVoidMethodA(self.env, C.valObject(jval), meth.method, args.Ptr())
	}
	if self.ExceptionCheck() {
		err = self.ExceptionOccurred()
	}
	return
}
示例#5
0
/*
	returns a new *Object of type *Class, using the constructor identified by []params
*/
func (self *Environment) NewInstance(c *Class, params ...interface{}) (o *Object, err error) {
	meth, alp, localStack, err := self.getClassMethod(c, false, "<init>", types.Basic(types.VoidKind), params...)
	//	meth, alp, err := self.getObjectMethod(newObject(self, c, C.jobject( c.class)), "<init>", BasicType(JavaVoidKind), params...)
	if err != nil {
		return
	}
	defer blowStack(self, localStack)
	obj := C.envNewObjectA(self.env, c.class, meth.method, alp.Ptr())
	if obj != nil {
		obj = C.envNewGlobalRef(self.env, obj)
		o = newObject(obj)
	} else {
		err = self.ExceptionOccurred()
	}
	return
}
示例#6
0
func (self *Environment) ToString(strobj *Object) (str string, isNull bool, err error) {
	var bytesObj *Object
	bytesObj, err = self.CallObjectObj(strobj, false, "getBytes", types.Array{types.Basic(types.ByteKind)}, self.utf8())
	if err == nil && bytesObj == nil {
		isNull = true
		return
	}
	if err == nil {
		defer self.DeleteLocalRef(bytesObj)
		alen := C.envGetArrayLength(self.env, bytesObj.object)
		_false := C.jboolean(C.JNI_FALSE)
		ptr := C.envGetByteArrayElements(self.env, bytesObj.object, &_false)
		defer C.envReleaseByteArrayElements(self.env, bytesObj.object, ptr, 0)
		str = string(C.GoBytes(unsafe.Pointer(ptr), C.int(alen)))
	}
	return
}
示例#7
0
func (self *Environment) callFloat(z interface{}, static bool, name string, params ...interface{}) (v float32, err error) {
	jval, meth, args, localStack, err := self.getMethod(z, static, name, types.Basic(types.FloatKind), params...)
	if err != nil {
		return
	}
	defer blowStack(self, localStack)
	var ji C.jfloat
	if static {
		ji = C.envCallStaticFloatMethodA(self.env, C.valObject(jval), meth.method, args.Ptr())
	} else {
		ji = C.envCallFloatMethodA(self.env, C.valObject(jval), meth.method, args.Ptr())
	}
	if self.ExceptionCheck() {
		err = self.ExceptionOccurred()
	}
	v = float32(ji)
	return
}
示例#8
0
func (self *Environment) callShort(z interface{}, static bool, name string, params ...interface{}) (v int16, err error) {
	jval, meth, args, localStack, err := self.getMethod(z, static, name, types.Basic(types.ShortKind), params...)
	if err != nil {
		return
	}
	defer blowStack(self, localStack)
	var oval C.jshort
	if static {
		oval = C.envCallStaticShortMethodA(self.env, C.valObject(jval), meth.method, args.Ptr())
	} else {
		oval = C.envCallShortMethodA(self.env, C.valObject(jval), meth.method, args.Ptr())
	}
	if self.ExceptionCheck() {
		err = self.ExceptionOccurred()
	}
	if err == nil {
		v = int16(oval)
	}
	return
}
示例#9
0
package gojvm

import (
	"gojvm/types"
	"testing"
)

type formForTest struct {
	rtype  types.Typed
	params []interface{}
	eform  string
	eerror error
}

var formOfTests = []formForTest{
	formForTest{types.Basic(types.VoidKind), []interface{}{}, "()V", nil},
	formForTest{types.Basic(types.VoidKind), []interface{}{int(5)}, "(I)V", nil},
	formForTest{types.Basic(types.VoidKind), []interface{}{int16(5)}, "(S)V", nil},
	formForTest{types.Basic(types.VoidKind), []interface{}{int64(5)}, "(J)V", nil},
	formForTest{types.Basic(types.VoidKind), []interface{}{"5"}, "(Ljava/lang/String;)V", nil},
	formForTest{types.Basic(types.VoidKind), []interface{}{"5", &Object{}}, "(Ljava/lang/String;Ljava/lang/Object;)V", nil},
	formForTest{types.Basic(types.ShortKind), []interface{}{int64(5)}, "(J)S", nil},
	formForTest{types.Basic(types.BoolKind), []interface{}{int(0)}, "(I)Z", nil},
	formForTest{types.Class{types.JavaLangObject}, []interface{}{int(0)}, "(I)Ljava/lang/Object;", nil},
	formForTest{types.Array{types.Basic(types.ByteKind)}, []interface{}{[]byte{1, 2, 3}}, "([B)[B", nil},
}

func TestTrivialFormFor(t *testing.T) {
	env := setupJVM(t)
	for i, test := range formOfTests {
		form, err := FormFor(env, test.rtype, test.params...)