From a4e3a157f6934b30ee4f6534c95e0f7a9e671018 Mon Sep 17 00:00:00 2001 From: Jonathan Worthington Date: Sun, 26 Sep 2010 18:12:11 +0200 Subject: [PATCH] Add various boxing/unboxing ops that work directly with the REPR API. They pretty much match what's in 6model on .Net/JVM (so can easily have them all behind an nqp::foo in the future). --- src/ops/nqp.ops | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/src/ops/nqp.ops b/src/ops/nqp.ops index 9ca3bb2..6aecbfb 100644 --- a/src/ops/nqp.ops +++ b/src/ops/nqp.ops @@ -125,3 +125,111 @@ inline op repr_defined(out INT, in PMC) :base_core { Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, "Can only use repr_defined on a RakudoObject"); } + +/* + +=item repr_unbox_str() + +Tries to unbox a native string using the REPR API. + +=cut + +*/ +inline op repr_unbox_str(out STR, in PMC) :base_core { + if ($2->vtable->base_type == ro_id) + $1 = REPR($2)->get_str(interp, REPR_PMC($2), $2); + else + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Can only use repr_unbox_str on a RakudoObject"); +} + +/* + +=item repr_unbox_int() + +Tries to unbox a native integer using the REPR API. + +=cut + +*/ +inline op repr_unbox_int(out INT, in PMC) :base_core { + if ($2->vtable->base_type == ro_id) + $1 = REPR($2)->get_int(interp, REPR_PMC($2), $2); + else + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Can only use repr_unbox_int on a RakudoObject"); +} + +/* + +=item repr_unbox_num() + +Tries to unbox a native floating pint number using the REPR API. + +=cut + +*/ +inline op repr_unbox_num(out NUM, in PMC) :base_core { + if ($2->vtable->base_type == ro_id) + $1 = REPR($2)->get_num(interp, REPR_PMC($2), $2); + else + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Can only use repr_unbox_num on a RakudoObject"); +} + +/* + +=item repr_box_str() + +Box a native string to an instance of the specified type. + +=cut + +*/ +inline op repr_box_str(out PMC, in STR, in PMC) :base_core { + if ($3->vtable->base_type == ro_id) { + $1 = REPR($3)->instance_of(interp, REPR_PMC($3), $3); + REPR($1)->set_str(interp, REPR_PMC($1), $1, $2); + } + else + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Can only use repr_box_str with a RakudoObject as the box target"); +} + +/* + +=item repr_box_int() + +Box a native int to an instance of the specified type. + +=cut + +*/ +inline op repr_box_int(out PMC, in INT, in PMC) :base_core { + if ($3->vtable->base_type == ro_id) { + $1 = REPR($3)->instance_of(interp, REPR_PMC($3), $3); + REPR($1)->set_int(interp, REPR_PMC($1), $1, $2); + } + else + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Can only use repr_box_int with a RakudoObject as the box target"); +} + +/* + +=item repr_box_num() + +Box a native floating point number to an instance of the specified type. + +=cut + +*/ +inline op repr_box_num(out PMC, in NUM, in PMC) :base_core { + if ($3->vtable->base_type == ro_id) { + $1 = REPR($3)->instance_of(interp, REPR_PMC($3), $3); + REPR($1)->set_num(interp, REPR_PMC($1), $1, $2); + } + else + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Can only use repr_box_num with a RakudoObject as the box target"); +}