summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2011-11-13 00:44:57 +0000
committerAdrian Thurston <thurston@complang.org>2011-11-13 00:44:57 +0000
commit562a05797e143a1f7294230766bd87225fd9821f (patch)
tree9d0b6712b61d7b6c5ea14769bb5f71ab7717d1df
parent1c848101d8fa37b3bf3a04fc5602a8c34f21949d (diff)
downloadcolm-562a05797e143a1f7294230766bd87225fd9821f.tar.gz
Eliminated recursive call to bytecode loop in parse finish WC 3.
refs #332.
-rw-r--r--colm/bytecode.c88
-rw-r--r--colm/bytecode.h13
-rw-r--r--colm/compile.cc23
3 files changed, 109 insertions, 15 deletions
diff --git a/colm/bytecode.c b/colm/bytecode.c
index 3ba41326..fb97bd81 100644
--- a/colm/bytecode.c
+++ b/colm/bytecode.c
@@ -2365,7 +2365,6 @@ again:
break;
}
-
case IN_PARSE_FRAG_BKT: {
Tree *accum;
Tree *input;
@@ -2495,32 +2494,97 @@ again:
FsmRun *fsmRun = ((Accum*)accum)->fsmRun;
long pcr = parseFinish( &result, prg, sp, (Accum*)accum, stream, false, PcrStart );
- while ( pcr == PcrReduction ) {
- Execution exec2;
- Execution *exec = &exec2;
+
+ vm_push( (SW)pdaRun );
+ vm_push( (SW)fsmRun );
+ vm_push( (SW)pcr );
+ vm_push( result );
+
+ vm_push( (Tree*)stream );
+ vm_push( accum );
+ break;
+ }
+
+ case IN_PARSE_FINISH_WC2: {
+ debug( REALM_BYTECODE, "IN_PARSE_FINISH_WC2\n" );
+
+ Tree *accum = vm_pop();
+ Tree *stream = vm_pop();
+
+ Tree *result = vm_pop();
+ long pcr = (long)vm_pop();
+ FsmRun *fsmRun = (FsmRun*)vm_pop();
+ PdaRun *pdaRun = (PdaRun*)vm_pop();
+
+ if ( pcr == PcrReduction ) {
+ /* Push the execution. */
+ vm_pushn( SIZEOF_WORD * 20 );
+ Execution *pushedExec = (Execution*)vm_ptop();
+ memcpy( pushedExec, exec, sizeof(Execution) );
pdaRun->exec = exec;
- debug( REALM_BYTECODE, "reduction in finish\n" );
/* Execution environment for the reduction code. */
initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect,
pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId,
pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark );
+ vm_push( (SW)pdaRun );
+ vm_push( (SW)fsmRun );
+ vm_push( (SW)pcr );
+ vm_push( result );
+
+ vm_push( stream );
+ vm_push( accum );
+
/* Push the instruction. */
- vm_push( 0 ) ;//(SW)instr );
+ vm_push( (SW)instr );
/* Push the LHS onto the stack. */
vm_push( exec->lhs );
- /* Execution loop. */
- sp = executeCode( exec, sp, exec->code );
+ /* Call execution. */
+ instr = exec->code;
+ }
+ else {
+ instr += SIZEOF_CODE;
- pcr = parseFinish( &result, prg, sp, (Accum*)accum, stream, false, PcrReduction );
+ vm_push( result );
+ treeDownref( prg, sp, accum );
+ if ( prg->induceExit )
+ goto out;
}
+ break;
+ }
+
+ case IN_PARSE_FINISH_WC3: {
+ debug( REALM_BYTECODE, "IN_PARSE_FINISH_WC3\n" );
+
+ Tree *accum = vm_pop();
+ Tree *stream = vm_pop();
+
+ Tree *result = vm_pop();
+ long pcr = (long)vm_pop();
+ FsmRun *fsmRun = (FsmRun*)vm_pop();
+ PdaRun *pdaRun = (PdaRun*)vm_pop();
+
+ pcr = parseFinish( &result, prg, sp, (Accum*)accum, stream, false, PcrReduction );
+
+ /* Pop the saved execution. */
+ Execution *pushedExec = (Execution*)vm_ptop();
+ memcpy( exec, pushedExec, sizeof(Execution) );
+ vm_popn( SIZEOF_WORD * 20 );
+
+ vm_push( (SW)pdaRun );
+ vm_push( (SW)fsmRun );
+ vm_push( (SW)pcr );
vm_push( result );
- treeDownref( prg, sp, accum );
- if ( prg->induceExit )
- goto out;
+
+ vm_push( stream );
+ vm_push( accum );
+
+ instr -= SIZEOF_CODE;
+ instr -= SIZEOF_CODE;
+
break;
}
case IN_PARSE_FINISH_WV: {
diff --git a/colm/bytecode.h b/colm/bytecode.h
index 7d3c5936..011e4380 100644
--- a/colm/bytecode.h
+++ b/colm/bytecode.h
@@ -230,10 +230,11 @@ typedef unsigned char uchar;
#define IN_PARSE_FRAG_WC 0xc0
#define IN_PARSE_FRAG_WC2 0xe0
#define IN_PARSE_FRAG_WC3 0xe1
-#define IN_RED_RET 0xe3
+
#define IN_PARSE_FRAG_WV 0xc1
#define IN_PARSE_FRAG_WV2 0xe2
#define IN_PARSE_FRAG_WV3 0xe4
+
#define IN_PARSE_FRAG_BKT 0xc2
#define IN_PARSE_FRAG_BKT2 0xe5
#define IN_PARSE_FRAG_BKT3 0xe6
@@ -249,8 +250,18 @@ typedef unsigned char uchar;
#define IN_STREAM_APPEND_BKT 0xc8
#define IN_PARSE_FINISH_WC 0x9d
+#define IN_PARSE_FINISH_WC2 0xe7
+#define IN_PARSE_FINISH_WC3 0xea
+
#define IN_PARSE_FINISH_WV 0xbd
+#define IN_PARSE_FINISH_WV2 0xe8
+#define IN_PARSE_FINISH_WV3 0xeb
+
#define IN_PARSE_FINISH_BKT 0xbf
+#define IN_PARSE_FINISH_BKT2 0xe9
+#define IN_PARSE_FINISH_BKT3 0xec
+
+#define IN_RED_RET 0xe3
#define IN_PARSE_EXTRACT_INPUT
diff --git a/colm/compile.cc b/colm/compile.cc
index 209fa5d9..ec4028a8 100644
--- a/colm/compile.cc
+++ b/colm/compile.cc
@@ -1059,10 +1059,16 @@ void LangVarRef::callOperation( ParseData *pd, CodeVect &code, VarRefLookup &loo
bool revert = lookup.lastPtrInQual >= 0 || !isLocalRef(pd);
/* The call instruction. */
- if ( pd->revertOn && revert )
+ if ( pd->revertOn && revert ) {
code.append( lookup.objMethod->opcodeWV );
- else
+ }
+ else {
code.append( lookup.objMethod->opcodeWC );
+ if ( lookup.objMethod->opcodeWC == IN_PARSE_FINISH_WC ) {
+ code.append( IN_PARSE_FINISH_WC2 );
+ code.append( IN_PARSE_FINISH_WC3 );
+ }
+ }
if ( lookup.objMethod->useFuncId )
code.appendHalf( lookup.objMethod->funcId );
@@ -1467,6 +1473,19 @@ UniqueType *LangTerm::evaluateParse( ParseData *pd, CodeVect &code, bool stop )
else
code.append( IN_PARSE_FINISH_WC );
+ if ( pd->revertOn )
+ {//code.append( IN_PARSE_FINISH_WV2 );
+ }
+ else
+ code.append( IN_PARSE_FINISH_WC2 );
+
+ if ( pd->revertOn )
+ {//code.append( IN_PARSE_FINISH_WV3 );
+ }
+ else
+ code.append( IN_PARSE_FINISH_WC3 );
+
+
/* Lookup the type of the replacement and store it in the replacement
* object so that replacement parsing has a target. */
replacement->langEl = generic->langEl;