Front page | perl.cvs.parrot |
Postings from January 2009
[svn:parrot] r35045 - trunk/compilers/pirc/src
From:
kjs
Date:
January 6, 2009 08:21
Subject:
[svn:parrot] r35045 - trunk/compilers/pirc/src
Message ID:
20090106162143.1E2FBCB9F9@x12.develooper.com
Author: kjs
Date: Tue Jan 6 08:21:42 2009
New Revision: 35045
Modified:
trunk/compilers/pirc/src/pirpcc.c
trunk/compilers/pirc/src/pirsymbol.c
Log:
[pirc] improve handling of different cases for invoking a .sub: .local, global_label and find-during-runtime options. (Too complex for a commit message, but it fixes some innocent bugs).
Modified: trunk/compilers/pirc/src/pirpcc.c
==============================================================================
--- trunk/compilers/pirc/src/pirpcc.c (original)
+++ trunk/compilers/pirc/src/pirpcc.c Tue Jan 6 08:21:42 2009
@@ -125,6 +125,7 @@
*/
static target *
generate_unique_pir_reg(lexer_state * const lexer, pir_type type) {
+ fprintf(stderr, "unique reg of type %d: %d\n", type, lexer->pir_reg_generator - 1);
return new_reg(lexer, type, --lexer->pir_reg_generator);
}
@@ -395,48 +396,66 @@
=item C<static target *
get_invoked_sub(lexer_state * const lexer, target * const sub)>
+Return a C<target> node that represents the sub to invoke.
+If C<sub> is a register, that is returned. If it's a declared C<.local>,
+then a target node representing that symbol is returned. If it's
+just the name of a .sub, then there's 2 possibilities: either the
+sub was already parsed, in which case it's stored as a global_label,
+or the sub was not parsed yet, in which case a runtime resolving
+instruction is emitted.
+
=cut
*/
static target *
get_invoked_sub(lexer_state * const lexer, target * const sub) {
- target *subreg = NULL;
+ target *subreg = NULL;
+ symbol *sym = NULL;
+ global_label *glob = NULL;
/* if the target is a register, invoke that. */
- if (TEST_FLAG(sub->flags, TARGET_FLAG_IS_REG)) {
- subreg = new_reg(lexer, PMC_TYPE, sub->info->color);
- }
- else { /* find the global label in the current file, or find it during runtime */
- global_label *glob = find_global_label(lexer, sub->info->id.name);
- subreg = generate_unique_pir_reg(lexer, PMC_TYPE);
-
- if (glob) {
- new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc", 0);
- add_operands(lexer, "%T%i", subreg, glob->const_table_index);
- }
- else { /* find it during runtime (hopefully, otherwise exception) */
- new_sub_instr(lexer, PARROT_OP_find_sub_not_null_p_sc, "find_sub_not_null_p_sc", 0);
+ if (TEST_FLAG(sub->flags, TARGET_FLAG_IS_REG))
+ return sub;
- add_operands(lexer, "%T%s", subreg, sub->info->id.name);
- /* save the current instruction in a list; entries in this list will be
- * fixed up, if possible, after the parsing phase.
- *
- * Instead of the instruction
- *
- * set_p_pc
- *
- * that is generated when the global label C<glob> was found (see above),
- * another instructions is generated. After the parse, we'll re-try
- * to find the global label that is referenced. For now, just generate
- * this instruction to do the resolving of the label during runtime:
- *
- * find_sub_not_null_p_sc
- */
- save_global_reference(lexer, CURRENT_INSTRUCTION(lexer), sub->info->id.name);
- }
+ /* find the global label in the current file, or find it during runtime */
+ sym = find_symbol(lexer, sub->info->id.name);
+
+ /* if the invoked object was declared as a .local, return that */
+ if (sym)
+ return target_from_symbol(lexer, sym);
+ /* it was not a .local, so check whether it's a declared .sub */
+ glob = find_global_label(lexer, sub->info->id.name);
+ subreg = generate_unique_pir_reg(lexer, PMC_TYPE);
+
+ if (glob) {
+ new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc", 0);
+ add_operands(lexer, "%T%i", subreg, glob->const_table_index);
+ return subreg;
}
+
+ /* find it during runtime (hopefully, otherwise exception) */
+ new_sub_instr(lexer, PARROT_OP_find_sub_not_null_p_sc, "find_sub_not_null_p_sc", 0);
+
+ add_operands(lexer, "%T%s", subreg, sub->info->id.name);
+
+ /* save the current instruction in a list; entries in this list will be
+ * fixed up, if possible, after the parsing phase.
+ *
+ * Instead of the instruction
+ *
+ * set_p_pc
+ *
+ * that is generated when the global label C<glob> was found (see above),
+ * another instructions is generated. After the parse, we'll re-try
+ * to find the global label that is referenced. For now, just generate
+ * this instruction to do the resolving of the label during runtime:
+ *
+ * find_sub_not_null_p_sc
+ */
+ save_global_reference(lexer, CURRENT_INSTRUCTION(lexer), sub->info->id.name);
+
return subreg;
}
Modified: trunk/compilers/pirc/src/pirsymbol.c
==============================================================================
--- trunk/compilers/pirc/src/pirsymbol.c (original)
+++ trunk/compilers/pirc/src/pirsymbol.c Tue Jan 6 08:21:42 2009
@@ -95,6 +95,7 @@
static int
next_register(NOTNULL(lexer_state * const lexer), pir_type type) {
CURRENT_SUB(lexer)->info.regs_used[type]++; /* count number of registers used */
+ /* fprintf(stderr, "vanilla reg: %d of type %d\n", lexer->curregister[type], type); */
return lexer->curregister[type]++;
}
@@ -112,6 +113,9 @@
void
assign_vanilla_register(NOTNULL(lexer_state * const lexer), symbol * const sym) {
sym->info.color = next_register(lexer, sym->info.type);
+ /* fprintf(stderr, "assigning vanilla reg %d to symbol %s\n", sym->info.color,
+ sym->info.id.name);
+ */
if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC)) {
sym->info.interval = new_live_interval(lexer->lsr, lexer->stmt_counter, sym->info.type);
@@ -257,7 +261,7 @@
bucket_symbol(b) = iter;
store_bucket(table, b, hash);
iter->info.type = type;
- fprintf(stderr, "declare_local(): [%s]\n", iter->info.id.name);
+ /* fprintf(stderr, "declare_local(): [%s]\n", iter->info.id.name); */
}
iter = iter->next;
@@ -333,9 +337,10 @@
if (STREQ(sym->info.id.name, name)) {
- if (sym->info.color == NO_REG_ALLOCATED) /* no PASM register assigned yet */
+ if (sym->info.color == NO_REG_ALLOCATED) { /* no PASM register assigned yet */
/* get a new reg from vanilla reg. allocator */
assign_vanilla_register(lexer, sym);
+ }
else /* update end point of interval */
if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC)) {
sym->info.interval->endpoint = lexer->stmt_counter;
@@ -535,7 +540,9 @@
* a new PASM register through the vanilla reg. allocator and
* store the register as "used".
*/
- return use_register(lexer, type, regno, next_register(lexer, type));
+ int nextreg = next_register(lexer, type);
+ fprintf(stderr, "mapping reg %d to %d\n", regno, nextreg);
+ return use_register(lexer, type, regno, nextreg);
}
}
-
[svn:parrot] r35045 - trunk/compilers/pirc/src
by kjs