Skip to content

Commit

Permalink
fix support for builtin ctor overloads
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Nov 17, 2023
1 parent 7dfee32 commit 02dcfa6
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 28 deletions.
15 changes: 13 additions & 2 deletions src/core/chuck_emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4870,8 +4870,19 @@ t_CKBOOL emit_engine_pre_constructor( Chuck_Emitter * emit, Chuck_Type * type, a
emit->append( new Chuck_Instr_Reg_Push_Code( ctor_info->func->code ) );
// push local stack depth corresponding to local variables
emit->append( new Chuck_Instr_Reg_Push_Imm( emit->code->frame->curr_offset ) );
// push offset
emit->append( new Chuck_Instr_Func_Call( CK_FUNC_CALL_THIS_IN_FRONT ) );

// code format (native or in-language)
if( ctor_info->func->code->native_func )
{
// append instruction
emit->append( new Chuck_Instr_Func_Call_Member( kindof_VOID, ctor_info->func,
CK_FUNC_CALL_THIS_IN_FRONT ) );
}
else
{
// push offset
emit->append( new Chuck_Instr_Func_Call( CK_FUNC_CALL_THIS_IN_FRONT ) );
}
}
else if( type->ctor_default ) // emit base constructor, if there is one
{
Expand Down
66 changes: 62 additions & 4 deletions src/core/chuck_instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5207,6 +5207,21 @@ void Chuck_Instr_Func_Call::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )



//-----------------------------------------------------------------------------
// for printing
//-----------------------------------------------------------------------------
const char * Chuck_Instr_Func_Call_Member::params() const
{
static char buffer[CK_PRINT_BUF_LENGTH];
snprintf( buffer, CK_PRINT_BUF_LENGTH, "%s, %s",
m_func_ref ? m_func_ref->signature(FALSE,FALSE).c_str() : "[null]",
m_arg_convention == CK_FUNC_CALL_THIS_IN_BACK ? "this:back" : "this:front" );
return buffer;
}




//-----------------------------------------------------------------------------
// name: execute()
// desc: imported member function call with return
Expand Down Expand Up @@ -5255,8 +5270,15 @@ void Chuck_Instr_Func_Call_Member::execute( Chuck_VM * vm, Chuck_VM_Shred * shre
// need this
if( func->need_this )
{
// copy this from end of arguments to the front
*mem_sp2++ = *(reg_sp2 + stack_depth - 1);
// check convention | 1.5.1.9 (ge) added
if( m_arg_convention == CK_FUNC_CALL_THIS_IN_BACK )
{
// copy this from end of arguments to the front
*mem_sp2++ = *(reg_sp2 + stack_depth - 1);
} else {
// copy this from start of arguments
*mem_sp2++ = *reg_sp2++;
}
// one less word to copy
stack_depth--;
}
Expand Down Expand Up @@ -5354,6 +5376,21 @@ void Chuck_Instr_Func_Call_Member::execute( Chuck_VM * vm, Chuck_VM_Shred * shre



//-----------------------------------------------------------------------------
// for printing
//-----------------------------------------------------------------------------
const char * Chuck_Instr_Func_Call_Static::params() const
{
static char buffer[CK_PRINT_BUF_LENGTH];
snprintf( buffer, CK_PRINT_BUF_LENGTH, "%s, %s",
m_func_ref ? m_func_ref->signature(FALSE,FALSE).c_str() : "[null]",
m_arg_convention == CK_FUNC_CALL_THIS_IN_BACK ? "this:back" : "this:front" );
return buffer;
}




//-----------------------------------------------------------------------------
// name: execute()
// desc: imported static function call with return
Expand Down Expand Up @@ -5402,8 +5439,15 @@ void Chuck_Instr_Func_Call_Static::execute( Chuck_VM * vm, Chuck_VM_Shred * shre
// need type
if( func->is_static )
{
// copy this from end of arguments to the front
*mem_sp2++ = *(reg_sp2 + stack_depth - 1);
// check convention | 1.5.1.9 (ge) added
if( m_arg_convention == CK_FUNC_CALL_THIS_IN_BACK )
{
// copy this from end of arguments to the front
*mem_sp2++ = *(reg_sp2 + stack_depth - 1);
} else {
// copy this from start of arguments
*mem_sp2++ = *reg_sp2++;
}
// one less word to copy
stack_depth--;
}
Expand Down Expand Up @@ -5490,6 +5534,20 @@ void Chuck_Instr_Func_Call_Static::execute( Chuck_VM * vm, Chuck_VM_Shred * shre



//-----------------------------------------------------------------------------
// for printing
//-----------------------------------------------------------------------------
const char * Chuck_Instr_Func_Call_Global::params() const
{
static char buffer[CK_PRINT_BUF_LENGTH];
snprintf( buffer, CK_PRINT_BUF_LENGTH, "%s",
m_func_ref ? m_func_ref->signature(FALSE,FALSE).c_str() : "[null]" );
return buffer;
}




//-----------------------------------------------------------------------------
// name: execute() | 1.5.1.5
// desc: imported global function call with return
Expand Down
32 changes: 26 additions & 6 deletions src/core/chuck_instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3328,14 +3328,22 @@ struct Chuck_Instr_Func_Call : public Chuck_Instr
struct Chuck_Instr_Func_Call_Member : public Chuck_Instr_Unary_Op
{
public:
Chuck_Instr_Func_Call_Member( t_CKUINT ret_size, Chuck_Func * func_ref )
{ this->set( ret_size ); m_func_ref = func_ref; }
Chuck_Instr_Func_Call_Member( t_CKUINT ret_size, Chuck_Func * func_ref,
ck_Func_Call_Arg_Convention arg_convention = CK_FUNC_CALL_THIS_IN_BACK )
{ this->set( ret_size ); m_func_ref = func_ref; m_arg_convention = arg_convention; }

public:
// for carrying out instruction
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
// for printing
virtual const char * params() const;

public:
Chuck_Func * m_func_ref; // 1.5.0.0 (ge) | added for arg list cleanup
// 1.5.0.0 (ge) | added for arg list cleanup
Chuck_Func * m_func_ref;
// when applicable, this flag indicates whether this/type is at the
// beginning or at the end of the argument block on the reg stack
ck_Func_Call_Arg_Convention m_arg_convention;
};


Expand All @@ -3348,14 +3356,22 @@ struct Chuck_Instr_Func_Call_Member : public Chuck_Instr_Unary_Op
struct Chuck_Instr_Func_Call_Static : public Chuck_Instr_Unary_Op
{
public:
Chuck_Instr_Func_Call_Static( t_CKUINT ret_size, Chuck_Func * func_ref )
{ this->set( ret_size ); m_func_ref = func_ref; }
Chuck_Instr_Func_Call_Static( t_CKUINT ret_size, Chuck_Func * func_ref,
ck_Func_Call_Arg_Convention arg_convention = CK_FUNC_CALL_THIS_IN_BACK )
{ this->set( ret_size ); m_func_ref = func_ref; m_arg_convention = arg_convention; }

public:
// for carrying out instruction
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
// for printing
virtual const char * params() const;

public:
Chuck_Func * m_func_ref; // 1.5.0.0 (ge) | added for arg list cleanup
// 1.5.0.0 (ge) | added for arg list cleanup
Chuck_Func * m_func_ref;
// when applicable, this flag indicates whether this/type is at the
// beginning or at the end of the argument block on the reg stack
ck_Func_Call_Arg_Convention m_arg_convention;
};


Expand All @@ -3372,9 +3388,13 @@ struct Chuck_Instr_Func_Call_Global : public Chuck_Instr_Unary_Op
{ this->set( ret_size ); m_func_ref = func_ref; }

public:
// for carrying out instruction
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
// for printing
virtual const char * params() const;

public:
// 1.5.0.0 (ge) | added for arg list cleanup
Chuck_Func * m_func_ref;
};

Expand Down
21 changes: 21 additions & 0 deletions src/core/ugen_xxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,12 @@ DLL_QUERY xxx_query( Chuck_DL_Query * QUERY )

if( !type_engine_import_add_ex( env, "basic/i-robot.ck" ) ) goto error;

// add ctrl: fprob
func = make_new_mfun( "void", "Gain", gain_ctor_1 );
func->doc = "Create a Gain with default value.";
func->add_arg( "float", "gain" );
if( !type_engine_import_mfun( env, func ) ) goto error;

// end import
if( !type_engine_import_class_end( env ) )
return FALSE;
Expand Down Expand Up @@ -1859,6 +1865,21 @@ CK_DLL_TICK( bunghole_tick )



//-----------------------------------------------------------------------------
// name: Gain( float gain )
// desc: Gain constructor that takes a float
//-----------------------------------------------------------------------------
CK_DLL_MFUN( gain_ctor_1 )
{
// get ugen
Chuck_UGen * ugen = (Chuck_UGen *)SELF;
// set from constructor arg
ugen->m_gain = GET_NEXT_FLOAT(ARGS);
}




//-----------------------------------------------------------------------------
// name: pan2_ctor()
// desc: ...
Expand Down
5 changes: 4 additions & 1 deletion src/core/ugen_xxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ CK_DLL_DTOR( pan2_dtor );
CK_DLL_CTRL( pan2_ctrl_value );
CK_DLL_CGET( pan2_cget_value );

// MIX2
// Mix2
CK_DLL_CTOR( mix2_ctor );
CK_DLL_CTOR( mix2_dtor );
CK_DLL_CTRL( mix2_ctrl_value );
CK_DLL_CGET( mix2_cget_value );

// Gain
CK_DLL_MFUN( gain_ctor_1 );

// noise
CK_DLL_TICK( noise_tick );

Expand Down
17 changes: 2 additions & 15 deletions src/core/ulib_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,26 +726,13 @@ CK_DLL_SFUN( isnan_impl )

// equal( x, y ) -- 1.4.1.1 (added ge)
// returns whether x and y (floats) are considered equal
//
// Knuth, Donald E., /The Art of Computer Programming
// Volume II: Seminumerical Algorithms/, Addison-Wesley, 1969.
// based on Knuth section 4.2.2 pages 217-218
// https://www.cs.technion.ac.il/users/yechiel/c++-faq/floating-point-arith.html
CK_DLL_SFUN( equal_impl )
{
const t_CKFLOAT epsilon = .00000001; // a small number 1e-8
// get arguments
t_CKFLOAT x = GET_CK_FLOAT(ARGS);
t_CKFLOAT y = *((t_CKFLOAT *)ARGS + 1);
// absolute values
t_CKFLOAT abs_x = (x >= 0.0 ? x : -x);
t_CKFLOAT abs_y = (y >= 0.0 ? y : -y);
// smaller of the two absolute values (this step added by ge; ensures symmetry)
t_CKFLOAT min = abs_x < abs_y ? abs_x : abs_y;
// absolute value of the difference
t_CKFLOAT v = x-y; t_CKFLOAT abs_v = (v >= 0.0 ? v : -v);
// test whether difference is less/equal to episilon * smaller of two abs values
RETURN->v_int = (abs_v <= (epsilon * min));
// equal
RETURN->v_int = ck_equals(x,y);
}

// floatMax
Expand Down
26 changes: 26 additions & 0 deletions src/core/util_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,32 @@ unsigned long ck_ensurepow2( unsigned long n )



//-----------------------------------------------------------------------------
// equal( x, y ) -- 1.4.1.1 (added ge)
// returns whether x and y (floats) are considered equal
//
// Knuth, Donald E., /The Art of Computer Programming
// Volume II: Seminumerical Algorithms/, Addison-Wesley, 1969.
// based on Knuth section 4.2.2 pages 217-218
// https://www.cs.technion.ac.il/users/yechiel/c++-faq/floating-point-arith.html
//-----------------------------------------------------------------------------
t_CKBOOL ck_equals( t_CKFLOAT x, t_CKFLOAT y )
{
const t_CKFLOAT epsilon = .00000001; // a small number 1e-8
// absolute values
t_CKFLOAT abs_x = (x >= 0.0 ? x : -x);
t_CKFLOAT abs_y = (y >= 0.0 ? y : -y);
// smaller of the two absolute values (this step added by ge; ensures symmetry)
t_CKFLOAT min = abs_x < abs_y ? abs_x : abs_y;
// absolute value of the difference
t_CKFLOAT v = x-y; t_CKFLOAT abs_v = (v >= 0.0 ? v : -v);
// test whether difference is less/equal to episilon * smaller of two abs values
return abs_v <= (epsilon * min);
}




//-----------------------------------------------------------------------------
// name: ck_complex_magnitude()
// desc: magnitude of complex number
Expand Down
2 changes: 2 additions & 0 deletions src/core/util_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ unsigned long ck_nextpow2( unsigned long i );
// ensurepow2
unsigned long ck_ensurepow2( unsigned long i );

// floating point equals
t_CKBOOL ck_equals( t_CKFLOAT lhs, t_CKFLOAT rhs );
// magnitude of complex number
t_CKFLOAT ck_complex_magnitude( const t_CKCOMPLEX & cmp );
// phase of complex number
Expand Down
6 changes: 6 additions & 0 deletions src/test/01-Basic/241-ctor-builtin.ck
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// constructor
SinOsc foo => Gain g(.5) => dac;

// test
if( Math.equal(g.gain(),.5) )
<<< "success" >>>;

0 comments on commit 02dcfa6

Please sign in to comment.