Skip to content

Commit

Permalink
fix accessing local variables decl after funcion that uses the variable
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Dec 4, 2024
1 parent 9c3ee54 commit 4f27aef
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 6 deletions.
17 changes: 17 additions & 0 deletions VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
ChucK VERSIONS log
------------------

1.5.4.4
=======
(fixed) crash due to functions / classes references a local variable defined
at file-scope; code emission is now internally re-ordered to compile
file-scope code segments -> function definitions -> class definitions
(fixed) foreach `auto` variable typing for multi-dimenion array, e.g.,
--------
// two dim array
for( auto x : [[1,2],[3,4]] ) {
for( auto y : x ) {
// print
<<< y >>>;
}
}
--------


1.5.4.3 (December 2024)
=======
new ChuGL v0.2.5 (see ChuGL release notes below)
Expand Down
42 changes: 36 additions & 6 deletions src/core/chuck_emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ t_CKBOOL emit_engine_shutdown( Chuck_Emitter *& emit )

//-----------------------------------------------------------------------------
// name: emit_engine_emit_prog()
// desc: ...
// desc: emit a chuck program/AST into VM bytecode
//-----------------------------------------------------------------------------
Chuck_VM_Code * emit_engine_emit_prog( Chuck_Emitter * emit, a_Program prog,
te_HowMuch how_much )
Expand Down Expand Up @@ -208,6 +208,11 @@ Chuck_VM_Code * emit_engine_emit_prog( Chuck_Emitter * emit, a_Program prog,
// push global scope (added 1.3.0.0)
emit->push_scope();

// for separating out function defs and class defs | 1.5.4.4 (ge) added
// this is to re-order code emission by stmt_lists -> func defs -> class defs
vector<a_Func_Def> func_defs;
vector<a_Class_Def> class_defs;

// loop over the program sections
while( prog && ret )
{
Expand All @@ -223,17 +228,16 @@ Chuck_VM_Code * emit_engine_emit_prog( Chuck_Emitter * emit, a_Program prog,
case ae_section_func: // function definition
// check the compilation criteria | 1.5.2.5 (ge) added
if( !howMuch_criteria_match( how_much, prog->section->func_def ) ) break;
// check function definition
ret = emit_engine_emit_func_def( emit, prog->section->func_def );
// add function def for emission
func_defs.push_back( prog->section->func_def );
break;

case ae_section_class: // class definition
// 1.5.2.5 (ge) check the compilation criteria
// if( !howMuch_criteria_match( how_much, prog->section->class_def ) ) break;
// 1.5.4.0 (ge) commented out (see type_engine_prog0_scan() for explanation)

// emit class definition
ret = emit_engine_emit_class_def( emit, prog->section->class_def );
// add class def for emission
class_defs.push_back( prog->section->class_def );
break;

default: // bad
Expand All @@ -250,6 +254,32 @@ Chuck_VM_Code * emit_engine_emit_prog( Chuck_Emitter * emit, a_Program prog,
prog = prog->next;
}

// make sure we are good so far
if( ret )
{
// iterate over func defs
for( size_t i = 0; i < func_defs.size(); i++ )
{
// check function definition
ret = emit_engine_emit_func_def( emit, func_defs[i] );
// check success code
if( !ret ) break;
}
}

// make sure we are good so far
if( ret )
{
// iterate over func defs
for( size_t i = 0; i < class_defs.size(); i++ )
{
// emit class definition
ret = emit_engine_emit_class_def( emit, class_defs[i] );
// check success code
if( !ret ) break;
}
}

// 1.4.1.0 (jack): error-checking: was dac-replacement initted?
// (see chuck_compile.h for an explanation on replacement dacs)
if( emit->should_replace_dac )
Expand Down
3 changes: 3 additions & 0 deletions src/test/01-Basic/269-foreach-auto-arraylit.ck
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
for( auto x : [[1,2],[3,4]] )
for( auto y : x )
{ <<< y >>>; }
4 changes: 4 additions & 0 deletions src/test/01-Basic/269-foreach-auto-arraylit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1 :(int)
2 :(int)
3 :(int)
4 :(int)
20 changes: 20 additions & 0 deletions src/test/01-Basic/270-var-func-order.ck
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// test using a local variable declared after a function that uses that variable
//
// added 1.5.4.4; previously this would cause a crash because the emitter
// emitted foo() first, at which point the variable `osc` has not yet received
// it's stack offset, since `SinOsc osc(440);` appears later in the file
// fix: now code emisison is sorted for file-level code, function defs, class
// defs.

// function def
fun void foo()
{
// uses `osc`
if( Math.equal(osc.freq(),440) ) <<< "success" >>>;
}

// osc is declared
SinOsc osc(440);

// call foo
foo();

0 comments on commit 4f27aef

Please sign in to comment.