Permalink
Browse files

Properly handle non-Sixmodel objects in dyncall ops.

Two issues:
- decontainerize in nqp_dyncall.ops was out of sync with decontainerize in
  sixmodelobject.c (didn't consider possibility of non-SMO arguments)
- unmarshalling code (to int/float types) need to dispatch to VTABLE_get_* in
  case of non-SMO arguments.

FROGGS++ for uncovering the problem.
  • Loading branch information...
1 parent c223607 commit a886a77147788c5ce340fe814d40722ff5f69014 @arnsholt arnsholt committed Aug 26, 2012
Showing with 57 additions and 18 deletions.
  1. +57 −18 src/ops/nqp_dyncall.ops
View
@@ -90,6 +90,7 @@ static INTVAL cs_repr_id = 0;
static INTVAL cp_repr_id = 0;
static INTVAL ca_repr_id = 0;
static INTVAL cstr_repr_id = 0;
+static INTVAL smo_id = 0;
PMC *callback_cache = NULL;
@@ -331,41 +332,58 @@ make_carray_result(PARROT_INTERP, PMC *type, void *carray) {
static DCchar
unmarshal_char(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DCchar) VTABLE_get_integer(interp, value);
return (DCchar)REPR(value)->box_funcs->get_int(interp, STABLE(value), OBJECT_BODY(value));
}
static DCshort
unmarshal_short(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DCshort) VTABLE_get_integer(interp, value);
return (DCshort)REPR(value)->box_funcs->get_int(interp, STABLE(value), OBJECT_BODY(value));
}
static DCint
unmarshal_int(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DCint) VTABLE_get_integer(interp, value);
return (DCint)REPR(value)->box_funcs->get_int(interp, STABLE(value), OBJECT_BODY(value));
}
static DClong
unmarshal_long(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DClong) VTABLE_get_integer(interp, value);
return (DClong)REPR(value)->box_funcs->get_int(interp, STABLE(value), OBJECT_BODY(value));
}
static DClonglong
unmarshal_longlong(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DClonglong) VTABLE_get_integer(interp, value);
return (DClonglong)REPR(value)->box_funcs->get_int(interp, STABLE(value), OBJECT_BODY(value));
}
static DCfloat
unmarshal_float(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DCfloat) VTABLE_get_number(interp, value);
return (DCfloat)REPR(value)->box_funcs->get_num(interp, STABLE(value), OBJECT_BODY(value));
}
static DCdouble
unmarshal_double(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ return (DCdouble) VTABLE_get_number(interp, value);
return (DCdouble)REPR(value)->box_funcs->get_num(interp, STABLE(value), OBJECT_BODY(value));
}
static char *
unmarshal_string(PARROT_INTERP, PMC *value, INTVAL type, INTVAL *free) {
+ if (value->vtable->base_type != smo_id)
+ return Parrot_str_to_encoded_cstring(interp, VTABLE_get_string(interp, value), Parrot_utf8_encoding_ptr);
+
if (IS_CONCRETE(value)) {
char *str;
PMC *meth = VTABLE_find_method(interp, STABLE(value)->WHAT,
@@ -404,11 +422,15 @@ unmarshal_string(PARROT_INTERP, PMC *value, INTVAL type, INTVAL *free) {
else {
return NULL;
}
-return NULL;
+ return NULL;
}
static void *
unmarshal_cstruct(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "Can't unmarshal non-sixmodel PMC to struct");
+
if (!IS_CONCRETE(value))
return NULL;
else if (REPR(value)->ID == cs_repr_id)
@@ -420,6 +442,10 @@ unmarshal_cstruct(PARROT_INTERP, PMC *value) {
static void *
unmarshal_carray(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "Can't unmarshal non-sixmodel PMC to array");
+
if (!IS_CONCRETE(value))
return NULL;
else if (REPR(value)->ID == ca_repr_id)
@@ -431,6 +457,10 @@ unmarshal_carray(PARROT_INTERP, PMC *value) {
static void *
unmarshal_cpointer(PARROT_INTERP, PMC *value) {
+ if (value->vtable->base_type != smo_id)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "Can't unmarshal non-sixmodel PMC to opaque pointer");
+
if (!IS_CONCRETE(value))
return NULL;
else if (REPR(value)->ID == cp_repr_id)
@@ -444,6 +474,11 @@ static void *
unmarshal_callback(PARROT_INTERP, PMC *value, PMC *info) {
PMC *callback_data;
+ if (value->vtable->base_type != smo_id)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "Can't unmarshal non-sixmodel PMC to callback");
+
+
if (!IS_CONCRETE(value)) {
return NULL;
}
@@ -510,23 +545,25 @@ unmarshal_callback(PARROT_INTERP, PMC *value, PMC *info) {
}
PMC * decontainerize(PARROT_INTERP, PMC *var) {
- ContainerSpec *spec = STABLE(var)->container_spec;
- if (spec && IS_CONCRETE(var)) {
- if (!PMC_IS_NULL(spec->value_slot.class_handle)) {
- /* Just get slot. */
- return VTABLE_get_attr_keyed(interp, var, spec->value_slot.class_handle,
- spec->value_slot.attr_name);
- }
- else {
- /* Invoke FETCH method. */
- PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
- PMC *meth = spec->fetch_method;
- PMC *cappy = Parrot_pmc_new(interp, enum_class_CallContext);
- VTABLE_push_pmc(interp, cappy, var);
- Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
- cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
- Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
- return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
+ if (var->vtable->base_type == smo_id) {
+ ContainerSpec *spec = STABLE(var)->container_spec;
+ if (spec && IS_CONCRETE(var)) {
+ if (!PMC_IS_NULL(spec->value_slot.class_handle)) {
+ /* Just get slot. */
+ return VTABLE_get_attr_keyed(interp, var, spec->value_slot.class_handle,
+ spec->value_slot.attr_name);
+ }
+ else {
+ /* Invoke FETCH method. */
+ PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
+ PMC *meth = spec->fetch_method;
+ PMC *cappy = Parrot_pmc_new(interp, enum_class_CallContext);
+ VTABLE_push_pmc(interp, cappy, var);
+ Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
+ cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
+ Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
+ return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
+ }
}
}
return var;
@@ -782,6 +819,8 @@ inline op nqp_native_call_setup() :base_core {
cstr_repr_id = REGISTER_DYNAMIC_REPR(interp,
Parrot_str_new_constant(interp, "CStr"),
CStr_initialize);
+ if (!smo_id)
+ smo_id = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "SixModelObject", 0));
}

0 comments on commit a886a77

Please sign in to comment.