}
else if (imeth != 0) // it could be abstract
{
- _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (im);
+ _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
clz->methods[i].ncode = im->ncode ();
}
}
+ (sizeof (void*) * (vtable_count)));
vtable->clas = clz;
- /* copy super class' vtable entries (index 0 goes unused). */
- memcpy ((void*)&vtable->method[1],
- (void*)&super_class->vtable->method[1],
- sizeof (void*) * super_class->vtable_method_count);
+ {
+ jclass effective_superclass = super_class;
+
+ /* If super_class is abstract or an interface it has no vtable.
+ We need to find a real one... */
+ while (effective_superclass && effective_superclass->vtable == NULL)
+ effective_superclass = effective_superclass->superclass;
+
+ /* copy super class' vtable entries (index 0 goes unused). */
+ if (effective_superclass && effective_superclass->vtable)
+ memcpy ((void*)&vtable->method[1],
+ (void*)&effective_superclass->vtable->method[1],
+ sizeof (void*) * effective_superclass->vtable_method_count);
+ }
/* now, install our own vtable entries, reprise... */
for (int i = 0; i < clz->method_count; i++)
int arg_count,
jboolean staticp,
ffi_cif *cif,
- ffi_type **arg_types)
+ ffi_type **arg_types,
+ ffi_type **rtype_p)
{
unsigned char *ptr = (unsigned char*) signature->data;
arg_count, rtype, arg_types) != FFI_OK)
throw_internal_error ("ffi_prep_cif failed");
+ if (rtype_p != NULL)
+ *rtype_p = rtype;
+
return item_count;
}
arg_count,
staticp,
&closure->cif,
- &closure->arg_types[0]);
+ &closure->arg_types[0],
+ NULL);
ffi_closure_fun fun;
(ncode_closure*)_Jv_AllocBytesChecked (sizeof (ncode_closure)
+ arg_count * sizeof (ffi_type*));
+ ffi_type *rtype;
init_cif (self->signature,
arg_count,
staticp,
&closure->cif,
- &closure->arg_types[0]);
+ &closure->arg_types[0],
+ &rtype);
ffi_closure_fun fun;
+ args_raw_size = ffi_raw_size (&closure->cif);
+
+ // Initialize the argument types and CIF that represent the actual
+ // underlying JNI function.
+ int extra_args = 1;
+ if ((self->accflags & Modifier::STATIC))
+ ++extra_args;
+ jni_arg_types = (ffi_type **) _Jv_Malloc ((extra_args + arg_count)
+ * sizeof (ffi_type *));
+ int offset = 0;
+ jni_arg_types[offset++] = &ffi_type_pointer;
+ if ((self->accflags & Modifier::STATIC))
+ jni_arg_types[offset++] = &ffi_type_pointer;
+ memcpy (&jni_arg_types[offset], &closure->arg_types[0],
+ arg_count * sizeof (ffi_type *));
+
+ if (ffi_prep_cif (&jni_cif, FFI_DEFAULT_ABI,
+ extra_args + arg_count, rtype,
+ jni_arg_types) != FFI_OK)
+ throw_internal_error ("ffi_prep_cif failed for JNI function");
+
JvAssert ((self->accflags & Modifier::NATIVE) != 0);
// FIXME: for now we assume that all native methods for
fun,
(void*) this);
- self->ncode = (void*)closure;
+ self->ncode = (void *) closure;
return self->ncode;
}
arg_count,
staticp,
&result->cif,
- &result->arg_types[0]);
+ &result->arg_types[0],
+ NULL);
result->vtable_index = vtable_index;
result->method = method;