Author: kjs
Date: Sun Dec 14 08:50:39 2008
New Revision: 33891
Modified:
trunk/compilers/pirc/new/pircompunit.c
trunk/compilers/pirc/t/heredoc.t
Log:
[pirc] don't generate leaving instructions in a sub if there's already a
'returncc' or 'end'. Update test as well. I think other branching instructions
should be added to this check as well, or possibly a check on the
opinfo->flags, which would be neater. TODO: check this out.
Modified: trunk/compilers/pirc/new/pircompunit.c
==============================================================================
--- trunk/compilers/pirc/new/pircompunit.c (original)
+++ trunk/compilers/pirc/new/pircompunit.c Sun Dec 14 08:50:39 2008
@@ -1862,7 +1862,7 @@
return;
}
else {
- int numargs = 0;
+
argiter = args;
do {
int flag = 0;
@@ -2347,23 +2347,18 @@
/*
-=item C<void
-close_sub(lexer_state * const lexer)>
-
-Finalize the subroutine. Generate the final instructions in the current
-subroutine; if the C<:main> flag was set on the subroutine, this is the
-C<end> instruction; otherwise, a I<normal> C<return> sequence is generated.
+=item C<static void
+emit_sub_leaving_instructions(lexer_state * const lexer)>
-Then, all local labels are fixed up; i.e., all label identifiers are converted
-into their offsets.
+Emit final instructions for the current subroutine. In case
+this is a C<:main> sub, the "end" instruction is emitted,
+otherwise it's a standard return sequence.
=cut
*/
-void
-close_sub(lexer_state * const lexer) {
- int opcode;
-
+static void
+emit_sub_leaving_instructions(lexer_state * const lexer) {
/* a :main-marked sub ends with the "end" instruction;
* otherwise it's this pair:
*
@@ -2381,6 +2376,43 @@
new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
new_sub_instr(lexer, PARROT_OP_returncc, "returncc");
}
+}
+
+/*
+
+=item C<void
+close_sub(lexer_state * const lexer)>
+
+Finalize the subroutine. Generate the final instructions in the current
+subroutine; if the C<:main> flag was set on the subroutine, this is the
+C<end> instruction; otherwise, a I<normal> C<return> sequence is generated.
+
+Then, all local labels are fixed up; i.e., all label identifiers are converted
+into their offsets.
+
+=cut
+
+*/
+void
+close_sub(lexer_state * const lexer) {
+ int need_leaving_instr = 1;
+
+ /* don't generate leaving instructions if the last instruction was already
+ * leaving the sub.
+ */
+ if (CURRENT_INSTRUCTION(lexer)) {
+ switch (CURRENT_INSTRUCTION(lexer)->opcode) {
+ case PARROT_OP_end:
+ case PARROT_OP_returncc:
+ need_leaving_instr = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (need_leaving_instr)
+ emit_sub_leaving_instructions(lexer);
/* fix up all local branch labels */
fixup_local_labels(lexer);
Modified: trunk/compilers/pirc/t/heredoc.t
==============================================================================
--- trunk/compilers/pirc/t/heredoc.t (original)
+++ trunk/compilers/pirc/t/heredoc.t Sun Dec 14 08:50:39 2008
@@ -58,8 +58,6 @@
yield
set_returns "\n Some text returned through return\n"
returncc
- set_returns
- returncc
OUTPUT
pirc_2_pasm_is(<<'CODE', <<'OUTPUT', "heredoc string assignment");