Skip to content

Commit

Permalink
Add nqp::assignunchecked(...).
Browse files Browse the repository at this point in the history
Used for the case when the compiler (probably the optimizer) already
concluded that the assignment is safe.
  • Loading branch information
jnthn committed Mar 19, 2013
1 parent 8e570d8 commit 335e5c9
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/6model/containers.c
Expand Up @@ -89,6 +89,7 @@ static ContainerConfigurer * initialize_code_pair_spec(PARROT_INTERP) {
code_pair_spec->name = Parrot_str_new_constant(interp, "code_pair");
code_pair_spec->fetch = code_pair_fetch;
code_pair_spec->store = code_pair_store;
code_pair_spec->store_unchecked = code_pair_store;
code_pair_spec->gc_mark_data = code_pair_gc_mark_data;
code_pair_spec->gc_free_data = code_pair_gc_free_data;
code_pair_spec->serialize = code_pair_serialize;
Expand Down
5 changes: 5 additions & 0 deletions src/6model/sixmodelobject.h
Expand Up @@ -41,6 +41,11 @@ typedef struct {
/* Stores a value in a container. Used for assignment. */
void (*store) (PARROT_INTERP, PMC *cont, PMC *obj);

/* Stores a value in a container, without any checking of it (this
* assumes an optimizer or something else already did it). Used for
* assignment. */
void (*store_unchecked) (PARROT_INTERP, PMC *cont, PMC *obj);

/* Name of this container specification. */
STRING *name;

Expand Down
1 change: 1 addition & 0 deletions src/QAST/Operations.nqp
Expand Up @@ -1855,6 +1855,7 @@ QAST::Operations.add_core_pirop_mapping('setcontspec', 'set_container_spec', '0P
QAST::Operations.add_core_pirop_mapping('iscont', 'is_container', 'IP', :inlinable(1));
QAST::Operations.add_core_pirop_mapping('decont', 'nqp_decontainerize', 'PP', :inlinable(1));
QAST::Operations.add_core_pirop_mapping('assign', 'nqp_assign', '0PP', :inlinable(1));
QAST::Operations.add_core_pirop_mapping('assignunchecked', 'nqp_assignunchecked', '0PP', :inlinable(1));

# lexical related opcodes
QAST::Operations.add_core_pirop_mapping('getlex', 'find_lex', 'Ps');
Expand Down
29 changes: 29 additions & 0 deletions src/ops/nqp.ops
Expand Up @@ -2261,6 +2261,35 @@ inline op nqp_assign(invar PMC, invar PMC) :base_core {
}


/*

=item nqp_assignunchecked

If the thing in $2 is a container, does a decontainerizing operation
and puts the contained value in $1. Indicates that the type checking of
the assignment was already done at compile time, so no checks are needed
here.

=cut

*/
inline op nqp_assignunchecked(invar PMC, invar PMC) :base_core {
PMC *cont = $1;
PMC *value = decontainerize(interp, $2);
INTVAL ok = 0;
if (cont->vtable->base_type == smo_id) {
ContainerSpec *spec = STABLE(cont)->container_spec;
if (spec) {
spec->store_unchecked(interp, cont, value);
ok = 1;
}
}
if (!ok)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Cannot assign to an immutable value");
}


/*

=item set_container_spec
Expand Down

0 comments on commit 335e5c9

Please sign in to comment.