// private static native Object invoke0(Method method, Object o, Object[] os);
// (Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
func invoke0(frame *rtda.Frame) {
	stack := frame.OperandStack()
	if stack.IsEmpty() {
		frame.RevertNextPC()
		_invokeMethod(frame)
	} else {
		returnType := frame.LocalVars().Get(0).(*rtc.FieldType)
		if returnType.IsBaseType() && !returnType.IsVoidType() {
			primitiveDescriptor := returnType.Descriptor()[0]
			box.Box(frame, primitiveDescriptor) // todo
		}
	}
}
Example #2
0
// public static native Object get(Object array, int index)
//         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
// (Ljava/lang/Object;I)Ljava/lang/Object;
func get(frame *rtda.Frame) {
	vars := frame.LocalVars()
	arr := vars.GetRef(0)
	index := vars.GetInt(1)

	if arr == nil {
		frame.Thread().ThrowNPE()
		return
	}
	if !arr.IsArray() {
		frame.Thread().ThrowIllegalArgumentException("Argument is not an array")
		return
	}
	if index < 0 || index >= heap.ArrayLength(arr) {
		frame.Thread().ThrowArrayIndexOutOfBoundsExceptionNoMsg()
		return
	}

	if !arr.IsPrimitiveArray() {
		obj := arr.Refs()[index]
		frame.OperandStack().PushRef(obj)
		return
	}

	// primitive array
	stack := frame.OperandStack()
	primitiveDescriptor := arr.Class().Name()[1]
	switch primitiveDescriptor {
	case 'Z':
		stack.PushBoolean(arr.Booleans()[index] == 1)
	case 'B':
		stack.PushInt(int32(arr.Bytes()[index]))
	case 'C':
		stack.PushInt(int32(arr.Chars()[index]))
	case 'S':
		stack.PushInt(int32(arr.Shorts()[index]))
	case 'I':
		stack.PushInt(arr.Ints()[index])
	case 'J':
		stack.PushLong(arr.Longs()[index])
	case 'F':
		stack.PushFloat(arr.Floats()[index])
	case 'D':
		stack.PushDouble(arr.Doubles()[index])
	}

	// boxing
	box.Box(frame, primitiveDescriptor)
}