Skip to content

Commit

Permalink
[binder] Hoisted several constant Parrot STRINGs.
Browse files Browse the repository at this point in the history
  • Loading branch information
chromatic committed Sep 4, 2010
1 parent 29fcf8e commit 6b1b030
Showing 1 changed file with 52 additions and 28 deletions.
80 changes: 52 additions & 28 deletions src/binder/bind.c
Expand Up @@ -17,17 +17,29 @@ static INTVAL lls_id = 0;
static INTVAL p6s_id = 0;
static STRING *ACCEPTS = NULL;
static STRING *HOW = NULL;
static STRING *DO_str = NULL;
static STRING *RW_str = NULL;
static STRING *PUN_str = NULL;
static STRING *HASH_str = NULL;
static STRING *LIST_str = NULL;
static STRING *SELF_str = NULL;
static STRING *PERL_str = NULL;
static STRING *ARRAY_str = NULL;
static STRING *HASH_str = NULL;
static STRING *SELECT_str = NULL;
static STRING *PUN_str = NULL;
static STRING *BLOCK_str = NULL;
static STRING *STORE_str = NULL;
static STRING *CREATE_str = NULL;
static STRING *SCALAR_str = NULL;
static STRING *SELECT_str = NULL;
static STRING *CAPTURE_str = NULL;
static STRING *SNAPCAP_str = NULL;
static STRING *STORAGE_str = NULL;
static STRING *JUNCTION_str = NULL;
static STRING *P6_SCALAR_str = NULL;
static STRING *SHORTNAME_str = NULL;
static STRING *HASH_SIGIL_str = NULL;
static STRING *ARRAY_SIGIL_str = NULL;
static STRING *BANG_TWIGIL_str = NULL;
static STRING *CALLCONTEXT_str = NULL;
static STRING *SCALAR_SIGIL_str = NULL;
static PMC *HashPunned = NULL;

Expand All @@ -38,18 +50,30 @@ static void setup_binder_statics(PARROT_INTERP) {

ACCEPTS = Parrot_str_new_constant(interp, "ACCEPTS");
HOW = Parrot_str_new_constant(interp, "HOW");
DO_str = Parrot_str_new_constant(interp, "$!do");
RW_str = Parrot_str_new_constant(interp, "rw");
PUN_str = Parrot_str_new_constant(interp, "!pun");
PERL_str = Parrot_str_new_constant(interp, "perl");
HASH_str = Parrot_str_new_constant(interp, "Hash");
LIST_str = Parrot_str_new_constant(interp, "List");
SELF_str = Parrot_str_new_constant(interp, "self");
ARRAY_str = Parrot_str_new_constant(interp, "Array");
HASH_str = Parrot_str_new_constant(interp, "Hash");
SELECT_str = Parrot_str_new_constant(interp, "!select");
PUN_str = Parrot_str_new_constant(interp, "!pun");
BLOCK_str = Parrot_str_new_constant(interp, "Block");
STORE_str = Parrot_str_new_constant(interp, "!STORE");
CREATE_str = Parrot_str_new_constant(interp, "CREATE");
SCALAR_str = Parrot_str_new_constant(interp, "scalar");
SELECT_str = Parrot_str_new_constant(interp, "!select");
CAPTURE_str = Parrot_str_new_constant(interp, "Capture");
SNAPCAP_str = Parrot_str_new_constant(interp, "!snapshot_capture");
STORAGE_str = Parrot_str_new_constant(interp, "$!storage");
JUNCTION_str = Parrot_str_new_constant(interp, "Junction");
P6_SCALAR_str = Parrot_str_new_constant(interp, "Perl6Scalar");
SHORTNAME_str = Parrot_str_new_constant(interp, "shortname");
HASH_SIGIL_str = Parrot_str_new_constant(interp, "%");
ARRAY_SIGIL_str = Parrot_str_new_constant(interp, "@");
SCALAR_SIGIL_str = Parrot_str_new_constant(interp, "$");
BANG_TWIGIL_str = Parrot_str_new_constant(interp, "!");
P6_SCALAR_str = Parrot_str_new_constant(interp, "Perl6Scalar");
CALLCONTEXT_str = Parrot_str_new_constant(interp, "CallContext");
SCALAR_SIGIL_str = Parrot_str_new_constant(interp, "$");

or_id = pmc_type(interp, Parrot_str_new(interp, "ObjectRef", 0));
lls_id = pmc_type(interp, Parrot_str_new(interp, "P6LowLevelSig", 0));
Expand Down Expand Up @@ -246,19 +270,19 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, llsig_element *sig_inf
* Callable and the thingy we have matches those enough. */
/* XXX TODO: Implement language interop checks. */
if (error) {
STRING * const perl = Parrot_str_new(interp, "perl", 0);
STRING * const perl = PERL_str;
PMC * perl_meth = VTABLE_find_method(interp, type_obj, perl);
PMC * how_meth = VTABLE_find_method(interp, value, HOW);
STRING * expected, * got;
PMC * value_how, * value_type;
Parrot_ext_call(interp, perl_meth, "Pi->S", type_obj, &expected);
Parrot_ext_call(interp, how_meth, "Pi->P", value, &value_how);
value_type = VTABLE_get_attr_str(interp, value_how, Parrot_str_new(interp, "shortname", 0));
value_type = VTABLE_get_attr_str(interp, value_how, SHORTNAME_str);
got = VTABLE_get_string(interp, value_type);
*error = Parrot_sprintf_c(interp, "Nominal type check failed for parameter '%S'; expected %S but got %S instead",
sig_info->variable_name, expected, got);
}
if (VTABLE_isa(interp, value, Parrot_str_new(interp, "Junction", 0)))
if (VTABLE_isa(interp, value, JUNCTION_str))
return BIND_RESULT_JUNCTION;
else
return BIND_RESULT_FAIL;
Expand All @@ -282,7 +306,7 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, llsig_element *sig_inf
PMC * value_how, * value_type;
STRING * got;
Parrot_ext_call(interp, how_meth, "Pi->P", value, &value_how);
value_type = VTABLE_get_attr_str(interp, value_how, Parrot_str_new(interp, "shortname", 0));
value_type = VTABLE_get_attr_str(interp, value_how, SHORTNAME_str);
got = VTABLE_get_string(interp, value_type);
*error = Parrot_sprintf_c(interp,
"Unable to coerce value for '%S' from %S to %S; no coercion method defined",
Expand Down Expand Up @@ -312,22 +336,20 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, llsig_element *sig_inf
if (!STRING_IS_NULL(sig_info->variable_name)) {
PMC *copy, *ref, *store_meth;
if (sig_info->flags & SIG_ELEM_ARRAY_SIGIL) {
STRING *STORE = Parrot_str_new(interp, "!STORE", 0);
copy = Rakudo_binding_create_positional(interp, PMCNULL, ARRAY_str);
store_meth = VTABLE_find_method(interp, copy, STORE);
store_meth = VTABLE_find_method(interp, copy, STORE_str);
Parrot_ext_call(interp, store_meth, "PiP", copy, value);
}
else if (sig_info->flags & SIG_ELEM_HASH_SIGIL) {
STRING *STORE = Parrot_str_new(interp, "!STORE", 0);
copy = Rakudo_binding_create_hash(interp, pmc_new(interp, enum_class_Hash));
store_meth = VTABLE_find_method(interp, copy, STORE);
store_meth = VTABLE_find_method(interp, copy, STORE_str);
Parrot_ext_call(interp, store_meth, "PiP", copy, value);
}
else {
copy = pmc_new_init(interp, p6s_id, value);
VTABLE_setprop(interp, copy, Parrot_str_new(interp, "scalar", 0), copy);
VTABLE_setprop(interp, copy, SCALAR_str, copy);
}
VTABLE_setprop(interp, copy, Parrot_str_new(interp, "rw", 0), copy);
VTABLE_setprop(interp, copy, RW_str, copy);
VTABLE_set_pmc_keyed_str(interp, lexpad, sig_info->variable_name, copy);
}
}
Expand All @@ -336,15 +358,15 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, llsig_element *sig_inf
if (!STRING_IS_NULL(sig_info->variable_name)) {
PMC *ref = pmc_new_init(interp, or_id, value);
if (!(sig_info->flags & (SIG_ELEM_ARRAY_SIGIL | SIG_ELEM_HASH_SIGIL)))
VTABLE_setprop(interp, ref, Parrot_str_new(interp, "scalar", 0), ref);
VTABLE_setprop(interp, ref, SCALAR_str, ref);
VTABLE_set_pmc_keyed_str(interp, lexpad, sig_info->variable_name, ref);
}
}
}

/* Is it the invocant? If so, also have to bind to self lexical. */
if (sig_info->flags & SIG_ELEM_INVOCANT)
VTABLE_set_pmc_keyed_str(interp, lexpad, Parrot_str_new(interp, "self", 0), value);
VTABLE_set_pmc_keyed_str(interp, lexpad, SELF_str, value);

/* Handle any constraint types (note that they may refer to the parameter by
* name, so we need to have bound it already). */
Expand All @@ -356,9 +378,9 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, llsig_element *sig_inf
for (i = 0; i < num_constraints; i++) {
PMC *cons_type = VTABLE_get_pmc_keyed_int(interp, constraints, i);
PMC *accepts_meth = VTABLE_find_method(interp, cons_type, ACCEPTS);
if (VTABLE_isa(interp, cons_type, Parrot_str_new(interp, "Block", 0)))
Parrot_capture_lex(interp, VTABLE_get_attr_str(interp, cons_type,
Parrot_str_new(interp, "$!do", 0)));
if (VTABLE_isa(interp, cons_type, BLOCK_str))
Parrot_capture_lex(interp,
VTABLE_get_attr_str(interp, cons_type, DO_str));
Parrot_ext_call(interp, accepts_meth, "PiP->P", cons_type, value, &result);
if (!VTABLE_get_bool(interp, result)) {
if (error)
Expand Down Expand Up @@ -479,7 +501,7 @@ Rakudo_binding_bind_llsig(PARROT_INTERP, PMC *lexpad, PMC *llsig,
STRING **error) {
INTVAL i;
INTVAL bind_fail;
INTVAL cur_pos_arg = 0;
INTVAL cur_pos_arg = 0;
INTVAL num_pos_args = VTABLE_elements(interp, capture);
PMC *named_names = PMCNULL;
llsig_element **elements;
Expand All @@ -502,9 +524,11 @@ Rakudo_binding_bind_llsig(PARROT_INTERP, PMC *lexpad, PMC *llsig,
/* Check that we have a valid signature and pull the bits out of it. */
if (!lls_id)
setup_binder_statics(interp);

if (llsig->vtable->base_type != lls_id)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Internal Error: Rakudo_binding_bind_llsig passed invalid signature");

GETATTR_P6LowLevelSig_elements(interp, llsig, elements);
GETATTR_P6LowLevelSig_num_elements(interp, llsig, num_elements);
GETATTR_P6LowLevelSig_named_to_pos_cache(interp, llsig, named_to_pos_cache);
Expand Down Expand Up @@ -548,11 +572,11 @@ Rakudo_binding_bind_llsig(PARROT_INTERP, PMC *lexpad, PMC *llsig,
/* If we've got a CallContext, just has an attribute with list of named
* parameter names. Otherwise, it's a Capture and we need to do .hash and
* grab out the keys. */
if (capture->vtable->base_type == enum_class_CallContext ||
VTABLE_isa(interp, capture, Parrot_str_new(interp, "CallContext", 0))) {
if (capture->vtable->base_type == enum_class_CallContext
|| VTABLE_isa(interp, capture, CALLCONTEXT_str)) {
named_names = VTABLE_get_attr_str(interp, capture, Parrot_str_new(interp, "named", 0));
}
else if (VTABLE_isa(interp, capture, Parrot_str_new(interp, "Capture", 0))) {
else if (VTABLE_isa(interp, capture, CAPTURE_str)) {
PMC *meth = VTABLE_find_method(interp, capture, Parrot_str_new(interp, "!PARROT_NAMEDS", 0));
PMC *hash = PMCNULL;
PMC *iter;
Expand Down Expand Up @@ -601,7 +625,7 @@ Rakudo_binding_bind_llsig(PARROT_INTERP, PMC *lexpad, PMC *llsig,
* For now, we don't have that, so we just build off the current
* capture. */
PMC *ns = Parrot_get_ctx_HLL_namespace(interp);
PMC *snapper = Parrot_ns_get_global(interp, ns, Parrot_str_new(interp, "!snapshot_capture", 0));
PMC *snapper = Parrot_ns_get_global(interp, ns, SNAPCAP_str);
PMC *snapshot = PMCNULL;
Parrot_ext_call(interp, snapper, "PiIP->P", capture, cur_pos_arg, named_args_copy, &snapshot);
bind_fail = Rakudo_binding_bind_one_param(interp, lexpad, elements[i], snapshot,
Expand Down

0 comments on commit 6b1b030

Please sign in to comment.