Skip to content

Commit 7ca7a40

Browse files
committed
Add new nqp::setcontspec and an nqp::assign op.
1 parent 6037461 commit 7ca7a40

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

src/QAST/Operations.nqp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,8 +1816,6 @@ QAST::Operations.add_core_pirop_mapping('attrinited', 'repr_is_attr_initialized'
18161816
QAST::Operations.add_core_pirop_mapping('create', 'repr_instance_of', 'PP', :inlinable(1));
18171817
QAST::Operations.add_core_pirop_mapping('clone', 'repr_clone', 'PP', :inlinable(1));
18181818
QAST::Operations.add_core_pirop_mapping('isconcrete', 'repr_defined', 'IP', :inlinable(1));
1819-
QAST::Operations.add_core_pirop_mapping('iscont', 'is_container', 'IP', :inlinable(1));
1820-
QAST::Operations.add_core_pirop_mapping('decont', 'nqp_decontainerize', 'PP', :inlinable(1));
18211819
QAST::Operations.add_core_pirop_mapping('isnull', 'isnull', 'IP', :inlinable(1));
18221820
QAST::Operations.add_core_pirop_mapping('isnull_s', 'isnull', 'IS', :inlinable(1));
18231821
QAST::Operations.add_core_pirop_mapping('istrue', 'istrue', 'IP', :inlinable(1));
@@ -1852,6 +1850,12 @@ QAST::Operations.add_core_pirop_mapping('settypecache', 'publish_type_check_cach
18521850
QAST::Operations.add_core_pirop_mapping('objprimspec', 'repr_get_primitive_type_spec', 'IP', :inlinable(1));
18531851
QAST::Operations.add_core_pirop_mapping('setinvokespec', 'set_invocation_spec', '0PPsP', :inlinable(1));
18541852

1853+
# container related
1854+
QAST::Operations.add_core_pirop_mapping('setcontspec', 'set_container_spec', '0PsP', :inlinable(1));
1855+
QAST::Operations.add_core_pirop_mapping('iscont', 'is_container', 'IP', :inlinable(1));
1856+
QAST::Operations.add_core_pirop_mapping('decont', 'nqp_decontainerize', 'PP', :inlinable(1));
1857+
QAST::Operations.add_core_pirop_mapping('assign', 'nqp_assign', '0PP', :inlinable(1));
1858+
18551859
# lexical related opcodes
18561860
QAST::Operations.add_core_pirop_mapping('getlex', 'find_lex', 'Ps');
18571861
QAST::Operations.add_core_pirop_mapping('getlex_i', 'find_lex', 'Is');

src/ops/nqp.ops

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,6 +2233,67 @@ inline op nqp_decontainerize(out PMC, invar PMC) :base_core {
22332233
$1 = decontainerize(interp, $2);
22342234
}
22352235

2236+
2237+
/*
2238+
2239+
=item nqp_assign
2240+
2241+
If the thing in $2 is a container, does a decontainerizing operation
2242+
and puts the contained value in $1.
2243+
2244+
=cut
2245+
2246+
*/
2247+
inline op nqp_assign(invar PMC, invar PMC) :base_core {
2248+
PMC *cont = $1;
2249+
PMC *value = decontainerize(interp, $2);
2250+
INTVAL ok = 0;
2251+
if (cont->vtable->base_type == smo_id) {
2252+
ContainerSpec *spec = STABLE(cont)->container_spec;
2253+
if (spec) {
2254+
spec->store(interp, cont, value);
2255+
ok = 1;
2256+
}
2257+
}
2258+
if (!ok)
2259+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
2260+
"Cannot assign to an immutable value");
2261+
}
2262+
2263+
2264+
/*
2265+
2266+
=item set_container_spec
2267+
2268+
Sets the container spec for the type in $1. $2 is the name of the container
2269+
specification to put in place. $2 is (possibly optional) configuration for
2270+
the container specification selected.
2271+
2272+
=cut
2273+
2274+
*/
2275+
inline op set_container_spec(in PMC, in STR, in PMC) :base_core {
2276+
PMC *target = decontainerize(interp, $1);
2277+
if ($1->vtable->base_type == smo_id) {
2278+
STable *st = STABLE($1);
2279+
ContainerConfigurer *cc = SixModelObject_get_container_config(interp, $2);
2280+
2281+
if (st->container_spec)
2282+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
2283+
"Cannot change a type's container specification");
2284+
2285+
cc->set_container_spec(interp, st);
2286+
cc->configure_container_spec(interp, st, $3);
2287+
2288+
PARROT_GC_WRITE_BARRIER(interp, STABLE_PMC($1));
2289+
}
2290+
else {
2291+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
2292+
"Can only use set_container_spec with a SixModelObject");
2293+
}
2294+
}
2295+
2296+
22362297
/*
22372298

22382299
=item set_invocation_spec

0 commit comments

Comments
 (0)