[svn:parrot] r41775 - branches/pcc_reapply/src/call
allison at svn.parrot.org
allison at svn.parrot.org
Fri Oct 9 22:57:52 UTC 2009
Author: allison
Date: Fri Oct 9 22:57:51 2009
New Revision: 41775
URL: https://trac.parrot.org/parrot/changeset/41775
Log:
[pcc] Basic rework of logic for fill_results function to use a temporary hash
for named returns. Greatly simplifies the code, and keeps it more parallel with
fill_params.
Modified:
branches/pcc_reapply/src/call/args.c
Modified: branches/pcc_reapply/src/call/args.c
==============================================================================
--- branches/pcc_reapply/src/call/args.c Fri Oct 9 22:38:11 2009 (r41774)
+++ branches/pcc_reapply/src/call/args.c Fri Oct 9 22:57:51 2009 (r41775)
@@ -1355,6 +1355,7 @@
ASSERT_ARGS(fill_results)
PMC *ctx = CURRENT_CONTEXT(interp);
PMC *named_used_list = PMCNULL;
+ PMC *named_return_list = PMCNULL;
INTVAL return_count = VTABLE_elements(interp, raw_sig);
INTVAL result_count;
INTVAL positional_returns = 0; /* initialized by a loop later */
@@ -1391,12 +1392,14 @@
result_count = PMC_IS_NULL(result_list) ? 0 : VTABLE_elements(interp, result_list);
/* the call obj doesn't have the returns as positionals, so instead we loop
- * over raw_sig and count the number of non-named
+ * over raw_sig and count the number of returns before the first named return.
*/
for (i = 0; i < return_count; i++) {
INTVAL flags = VTABLE_get_integer_keyed_int(interp, raw_sig, i);
- if (!(flags & PARROT_ARG_NAME))
- positional_returns++;
+ if (flags & PARROT_ARG_NAME)
+ break;
+
+ positional_returns++;
}
/*
@@ -1410,14 +1413,13 @@
INTVAL result_flags;
INTVAL return_flags;
PMC *result_item;
- INTVAL constant;
/* Check if we've used up all the returns. */
- if (return_index >= return_count) {
- if (result_index >= result_count) {
- /* We've used up all the positional returns and results, we're
- * done with this loop. */
- break;
+ if (result_index >= result_count) {
+ if (return_index >= return_count) {
+ /* We've used up all returns and results, we're
+ * done with the whole process. */
+ return;
}
else if (err_check) {
/* We've used up all the results, but have extra positional
@@ -1442,7 +1444,6 @@
result_flags = VTABLE_get_integer_keyed_int(interp, result_sig, result_index);
return_flags = VTABLE_get_integer_keyed_int(interp, raw_sig, return_index);
result_item = VTABLE_get_pmc_keyed_int(interp, result_list, result_index);
- constant = PARROT_ARG_CONSTANT_ISSET(return_flags);
/* If the result is slurpy, collect all remaining positional
* returns into an array.*/
@@ -1462,6 +1463,7 @@
Parrot_get_ctx_HLL_type(interp, enum_class_ResizablePMCArray));
/* Iterate over all positional arguments in the returns list. */
while (!(return_flags & PARROT_ARG_NAME)) {
+ INTVAL constant;
return_flags = VTABLE_get_integer_keyed_int(interp, raw_sig, return_index);
constant = PARROT_ARG_CONSTANT_ISSET(return_flags);
switch (PARROT_ARG_TYPE_MASK_MASK(return_flags)) {
@@ -1498,7 +1500,7 @@
}
/* We have a positional return, fill the result with it. */
- if (result_index < result_count) {
+ if (return_index < positional_returns) {
/* Fill a named result with a positional return. */
if (result_flags & PARROT_ARG_NAME) {
@@ -1506,19 +1508,18 @@
if (!(result_flags & PARROT_ARG_STRING))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"named results must have a name specified");
- result_name = PARROT_ARG_CONSTANT_ISSET(result_flags)
- ? accessor->string_constant(interp, return_info, result_index)
- : *accessor->string(interp, return_info, result_index);
+ result_name = VTABLE_get_string(interp, result_item);
named_count++;
result_index++;
if (result_index >= result_count)
continue;
- result_flags = VTABLE_get_integer_keyed_int(interp,
- raw_sig, result_index);
+ result_flags = VTABLE_get_integer_keyed_int(interp, result_sig, result_index);
+ result_item = VTABLE_get_pmc_keyed_int(interp, result_list, result_index);
/* Mark the name as used, cannot be filled again. */
if (PMC_IS_NULL(named_used_list)) /* Only created if needed. */
- named_used_list = pmc_new(interp, enum_class_Hash);
+ named_used_list = pmc_new(interp,
+ Parrot_get_ctx_HLL_type(interp, enum_class_Hash));
VTABLE_set_integer_keyed_str(interp, named_used_list, result_name, 1);
}
else if (named_count > 0) {
@@ -1530,6 +1531,7 @@
/* Go ahead and fill the result with a positional return. */
switch (PARROT_ARG_TYPE_MASK_MASK(return_flags)) {
+ INTVAL constant = PARROT_ARG_CONSTANT_ISSET(return_flags);
case PARROT_ARG_INTVAL:
if (constant)
VTABLE_set_integer_native(interp, result_item,
@@ -1577,6 +1579,8 @@
raw_sig, result_index + 1);
if (next_result_flags & PARROT_ARG_OPT_FLAG) {
result_index++;
+ result_item = VTABLE_get_pmc_keyed_int(interp, result_list,
+ result_index);
VTABLE_set_integer_native(interp, result_item, 1);
}
}
@@ -1598,9 +1602,11 @@
* with a default value. */
if (result_index + 1 < result_count) {
next_result_flags = VTABLE_get_integer_keyed_int(interp,
- raw_sig, result_index + 1);
+ result_sig, result_index + 1);
if (next_result_flags & PARROT_ARG_OPT_FLAG) {
result_index++;
+ result_item = VTABLE_get_pmc_keyed_int(interp, result_list,
+ result_index);
VTABLE_set_integer_native(interp, result_item, 0);
}
}
@@ -1623,7 +1629,43 @@
result_index++;
}
- /* Now iterate over the named returns and results. */
+ for (; return_index < return_count; return_index++) {
+ STRING *return_name;
+ INTVAL return_flags;
+
+ /* All remaining returns must be named. */
+ if (!(return_flags & PARROT_ARG_NAME))
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "named returns must follow all positional returns");
+
+ if (VTABLE_exists_keyed_str(interp, named_used_list, return_name))
+ continue;
+
+ return_flags = VTABLE_get_integer_keyed_int(interp, raw_sig, return_index);
+
+ if (!(return_flags & PARROT_ARG_STRING))
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "named results must have a name specified");
+
+ return_name = PARROT_ARG_CONSTANT_ISSET(return_flags)
+ ? accessor->string_constant(interp, return_info, return_index)
+ : *accessor->string(interp, return_info, return_index);
+ named_count++;
+ return_index++;
+ if (result_index >= result_count)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "named returns must have a value");
+
+ return_flags = VTABLE_get_integer_keyed_int(interp, raw_sig, return_index);
+
+ if (PMC_IS_NULL(named_return_list)) /* Only created if needed. */
+ named_return_list = pmc_new(interp,
+ Parrot_get_ctx_HLL_type(interp, enum_class_Hash));
+ VTABLE_set_integer_keyed_str(interp, named_used_list, result_name, 1);
+ }
+
+ /* Now iterate over the named results, filling them from the
+ * temporary hash of named returns. */
while (1) {
STRING *result_name = NULL;
PMC *result_item;
@@ -1634,99 +1676,66 @@
if (result_index >= result_count)
break;
- result_flags = VTABLE_get_integer_keyed_int(interp, raw_sig, result_index);
- result_item = VTABLE_get_pmc_keyed_int(interp, result_list, result_index);
+ result_flags = VTABLE_get_integer_keyed_int(interp, result_sig, result_index);
+ result_item = VTABLE_get_pmc_keyed_int(interp, result_list, result_index);
/* All remaining results must be named. */
- if (!(result_flags & PARROT_ARG_NAME)) {
+ if (!(result_flags & PARROT_ARG_NAME))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"named results must follow all positional results");
- }
/* Collected ("slurpy") named result */
if (result_flags & PARROT_ARG_SLURPY_ARRAY) {
- PMC * const collect_named = pmc_new(interp,
- Parrot_get_ctx_HLL_type(interp, enum_class_Hash));
- PMC *named_return_list = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "named"));
- if (!PMC_IS_NULL(named_return_list)) {
- INTVAL named_return_count = VTABLE_elements(interp, named_return_list);
- INTVAL named_return_index;
- PMC *named_key = pmc_new(interp, enum_class_Key);
- VTABLE_set_integer_native(interp, named_key, 0);
- SETATTR_Key_next_key(interp, named_key, (PMC *)INITBucketIndex);
-
- /* Low-level hash iteration. */
- for (named_return_index = 0;
- named_return_index < named_return_count;
- named_return_index++) {
- if (!PMC_IS_NULL(named_key)) {
- STRING *name = (STRING *)parrot_hash_get_idx(interp,
- (Hash *)VTABLE_get_pointer(interp, named_return_list), named_key);
- PARROT_ASSERT(name);
- if ((PMC_IS_NULL(named_used_list)) ||
- !VTABLE_exists_keyed_str(interp, named_used_list, name)) {
- VTABLE_set_pmc_keyed_str(interp, collect_named, name,
- VTABLE_get_pmc_keyed_str(interp, call_object, name));
- /* Mark the name as used, cannot be filled again. */
- if (PMC_IS_NULL(named_used_list)) /* Only created if needed. */
- named_used_list = pmc_new(interp, enum_class_Hash);
- VTABLE_set_integer_keyed_str(interp, named_used_list, name, 1);
- named_count++;
- }
- }
- }
- }
+ if (PMC_IS_NULL(named_return_list))
+ named_return_list = pmc_new(interp,
+ Parrot_get_ctx_HLL_type(interp, enum_class_Hash));
- VTABLE_set_pmc(interp, result_item, collect_named);
+ VTABLE_set_pmc(interp, result_item, named_return_list);
break; /* End of named results. */
}
/* Store the name. */
- if (!(result_flags & PARROT_ARG_STRING))
+ if (!(result_flags & PARROT_ARG_STRING))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"named results must have a name specified");
- result_name = PARROT_ARG_CONSTANT_ISSET(result_flags)
- ? accessor->string_constant(interp, return_info, result_index)
- : *accessor->string(interp, return_info, result_index);
+ result_name = VTABLE_get_string(interp, result_item);
if (!STRING_IS_NULL(result_name)) {
/* The next result is the actual value. */
result_index++;
if (result_index >= result_count)
continue;
- result_flags = VTABLE_get_integer_keyed_int(interp, raw_sig, result_index);
+ result_flags = VTABLE_get_integer_keyed_int(interp, result_sig, result_index);
+ result_item = VTABLE_get_pmc_keyed_int(interp, result_list, result_index);
- if (VTABLE_exists_keyed_str(interp, call_object, result_name)) {
+ if (VTABLE_exists_keyed_str(interp, named_return_list, result_name)) {
- /* Mark the name as used, cannot be filled again. */
- if (PMC_IS_NULL(named_used_list)) /* Only created if needed. */
- named_used_list = pmc_new(interp, enum_class_Hash);
- VTABLE_set_integer_keyed_str(interp, named_used_list, result_name, 1);
named_count++;
/* Fill the named result. */
switch (PARROT_ARG_TYPE_MASK_MASK(result_flags)) {
case PARROT_ARG_INTVAL:
VTABLE_set_integer_native(interp, result_item,
- *accessor->intval(interp, return_info, result_index));
+ VTABLE_get_integer_keyed_str(interp, named_return_list, result_name));
break;
case PARROT_ARG_FLOATVAL:
VTABLE_set_number_native(interp, result_item,
- *accessor->numval(interp, return_info, result_index));
+ VTABLE_get_number_keyed_str(interp, named_return_list, result_name));
break;
case PARROT_ARG_STRING:
VTABLE_set_string_native(interp, result_item,
- *accessor->string(interp, return_info, result_index));
+ VTABLE_get_string_keyed_str(interp, named_return_list, result_name));
break;
case PARROT_ARG_PMC:
VTABLE_set_pmc(interp, result_item,
- *accessor->pmc(interp, return_info, result_index));
+ VTABLE_get_pmc_keyed_str(interp, named_return_list, result_name));
break;
default:
Parrot_ex_throw_from_c_args(interp, NULL,
EXCEPTION_INVALID_OPERATION, "invalid result type");
break;
}
+ VTABLE_delete_keyed_str(interp, named_return_list, result_name);
/* Mark the option flag for the filled result. */
if (result_flags & PARROT_ARG_OPTIONAL) {
@@ -1737,6 +1746,8 @@
raw_sig, result_index + 1);
if (next_result_flags & PARROT_ARG_OPT_FLAG) {
result_index++;
+ result_item = VTABLE_get_pmc_keyed_int(interp,
+ result_list, result_index);
VTABLE_set_integer_native(interp, result_item, 1);
}
}
@@ -1751,7 +1762,7 @@
* with a default value. */
if (result_index + 1 < result_count) {
next_result_flags = VTABLE_get_integer_keyed_int(interp,
- raw_sig, result_index + 1);
+ result_sig, result_index + 1);
if (next_result_flags & PARROT_ARG_OPT_FLAG) {
result_index++;
result_item = VTABLE_get_pmc_keyed_int(interp,
@@ -1760,7 +1771,7 @@
}
}
}
- /* We don't have an return for the result, and it's not optional,
+ /* We don't have a return for the result, and it's not optional,
* so it's an error. */
else {
if (err_check)
@@ -1775,40 +1786,12 @@
/* Double check that all named returns were assigned to results. */
if (err_check) {
- PMC *named_return_list = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "named"));
if (!PMC_IS_NULL(named_return_list)) {
INTVAL named_return_count = VTABLE_elements(interp, named_return_list);
- if (PMC_IS_NULL(named_used_list))
+ if (named_return_count > 0)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "too many named returns: %d passed, 0 used",
- named_return_count);
- if (named_return_count > named_count) {
- /* At this point we know we have named returns that weren't
- * assigned to results. We're going to throw an exception
- * anyway, so spend a little extra effort to tell the user *which*
- * named return is extra. */
- INTVAL named_return_index;
- PMC *named_key = pmc_new(interp, enum_class_Key);
- VTABLE_set_integer_native(interp, named_key, 0);
- SETATTR_Key_next_key(interp, named_key, (PMC *)INITBucketIndex);
-
- /* Low-level hash iteration. */
- for (named_return_index = 0;
- named_return_index < named_return_count;
- named_return_index++) {
- if (!PMC_IS_NULL(named_key)) {
- STRING *name = (STRING *)parrot_hash_get_idx(interp,
- (Hash *)VTABLE_get_pointer(interp, named_return_list), named_key);
- PARROT_ASSERT(name);
- if (!VTABLE_exists_keyed_str(interp, named_used_list, name)) {
- Parrot_ex_throw_from_c_args(interp, NULL,
- EXCEPTION_INVALID_OPERATION,
- "too many named returns: '%S' not used",
- name);
- }
- }
- }
- }
+ "too many named returns: %d passed, %d used",
+ named_return_count + named_count, named_count);
}
}
More information about the parrot-commits
mailing list