Skip to content

Commit

Permalink
fix vec3/vec4 field access on stack
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Oct 11, 2023
1 parent cf6defa commit e446ab3
Show file tree
Hide file tree
Showing 5 changed files with 100,057 additions and 65 deletions.
18 changes: 10 additions & 8 deletions src/core/chuck_emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4157,9 +4157,9 @@ t_CKBOOL emit_engine_emit_exp_dot_member_special( Chuck_Emitter * emit,
string str = S_name(member->xid);
// check
if( str == "re" )
emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr, kindof_COMPLEX ) );
else if( str == "im" )
emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr, kindof_COMPLEX ) );
else
goto check_func;

Expand All @@ -4185,9 +4185,9 @@ t_CKBOOL emit_engine_emit_exp_dot_member_special( Chuck_Emitter * emit,
string str = S_name(member->xid);
// check
if( str == "mag" )
emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr, kindof_COMPLEX ) );
else if( str == "phase" )
emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr, kindof_COMPLEX ) );
else
goto check_func;

Expand All @@ -4196,6 +4196,8 @@ t_CKBOOL emit_engine_emit_exp_dot_member_special( Chuck_Emitter * emit,
}
else if( member->t_base->xid == te_vec3 || member->t_base->xid == te_vec4 )
{
// remember the kind
te_KindOf kind = member->t_base->xid == te_vec3 ? kindof_VEC3 : kindof_VEC4;
// mark to emit addr
if( member->base->s_meta == ae_meta_var )
member->base->emit_var = TRUE;
Expand All @@ -4214,13 +4216,13 @@ t_CKBOOL emit_engine_emit_exp_dot_member_special( Chuck_Emitter * emit,
string str = S_name(member->xid);
// check for .xyz[w] .rgb[a] .value/goal/slew
if( str == "x" || str == "r" || str == "value" )
emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr, kind ) );
else if( str == "y" || str == "g" || str == "goal" )
emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr, kind ) );
else if( str == "z" || str == "b" || str == "slew" )
emit->append( new Chuck_Instr_Dot_Cmp_Third( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_Third( member->base->s_meta == ae_meta_var, emit_addr, kind ) );
else if( member->t_base->xid == te_vec4 && ( str == "w" || str == "a" ) )
emit->append( new Chuck_Instr_Dot_Cmp_Fourth( member->base->s_meta == ae_meta_var, emit_addr ) );
emit->append( new Chuck_Instr_Dot_Cmp_Fourth( member->base->s_meta == ae_meta_var, emit_addr, kind ) );
else
goto check_func;

Expand Down
159 changes: 110 additions & 49 deletions src/core/chuck_instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6957,36 +6957,58 @@ void Chuck_Instr_Dot_Static_Func::execute( Chuck_VM * vm, Chuck_VM_Shred * shred

//-----------------------------------------------------------------------------
// name: execute()
// desc: ...
// desc: print the first field of a complex/polar/vec3/vec4 value
//-----------------------------------------------------------------------------
void Chuck_Instr_Dot_Cmp_First::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
{
// reg contains pointer to complex elsewhere
if( m_is_mem )
{
// stack
// pointer to var (regardless of value type)
t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr on
// push var addr or value?
if( m_emit_addr ) {
// t_CKFLOAT a = (*(t_CKCOMPLEX **)sp)->re;
// push addr (NOTE this works for complex/polar/vec3/vec4)
push_( sp, (t_CKUINT)(&((*(t_CKCOMPLEX **)sp)->re)) );
} else {
// push value
push_float( sp, (*(t_CKCOMPLEX **)sp)->re );
}
}
else
{
// stack
t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr, um we can't
if( m_emit_addr ) {
assert( FALSE );
} else {
push_float( sp, sp->re );
// make sure
assert( m_emit_addr == FALSE );

// which kind of datatype?
switch( m_kind )
{
// get corresponding value, pop that value, push field
case kindof_COMPLEX:
{
t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->re );
}
break;

case kindof_VEC3:
{
t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->x );
}
break;

case kindof_VEC4:
{
t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->x );
}
break;

// shouldn't get here
default: assert( FALSE ); break;
}
}
}
Expand All @@ -6996,35 +7018,58 @@ void Chuck_Instr_Dot_Cmp_First::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )

//-----------------------------------------------------------------------------
// name: execute()
// desc: ...
// desc: print the second field of a complex/polar/vec3/vec4 value
//-----------------------------------------------------------------------------
void Chuck_Instr_Dot_Cmp_Second::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
{
// reg contains pointer to complex elsewhere
if( m_is_mem )
{
// stack
// pointer to var (regardless of value type)
t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr on
// emit as var address or as value?
if( m_emit_addr ) {
// push addr (works for complex/polar/vec3/vec4)
push_( sp, (t_CKUINT)(&((*(t_CKCOMPLEX **)sp)->im)) );
} else {
// push value
push_float( sp, (*(t_CKCOMPLEX **)sp)->im );
}
}
else
{
// stack
t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr, um we can't
if( m_emit_addr ) {
assert( FALSE );
} else {
push_float( sp, sp->im );
// make sure
assert( m_emit_addr == FALSE );

// which kind of datatype?
switch( m_kind )
{
// get corresponding value, pop that value, push field
case kindof_COMPLEX:
{
t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->im );
}
break;

case kindof_VEC3:
{
t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->y );
}
break;

case kindof_VEC4:
{
t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->y );
}
break;

// shouldn't get here
default: assert( FALSE ); break;
}
}
}
Expand All @@ -7034,35 +7079,51 @@ void Chuck_Instr_Dot_Cmp_Second::execute( Chuck_VM * vm, Chuck_VM_Shred * shred

//-----------------------------------------------------------------------------
// name: execute()
// desc: ...
// desc: print the third field of a complex/polar/vec3/vec4 value
//-----------------------------------------------------------------------------
void Chuck_Instr_Dot_Cmp_Third::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
{
// reg contains pointer to complex elsewhere
if( m_is_mem )
{
// stack
// pointer
t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr on
// var addr or value?
if( m_emit_addr ) {
// push addr
push_( sp, (t_CKUINT)(&((*(t_CKVEC3 **)sp)->z)) );
} else {
// push value
push_float( sp, (*(t_CKVEC3 **)sp)->z );
}
}
else
{
// stack
t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr, um we can't
if( m_emit_addr ) {
assert( FALSE );
} else {
push_float( sp, sp->z );
// make sure
assert( m_emit_addr == FALSE );

// which kind of datatype?
switch( m_kind )
{
// get corresponding value, pop that value, push field
case kindof_VEC3:
{
t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->z );
}
break;

case kindof_VEC4:
{
t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
pop_( sp, 1 ); push_float( sp, sp->z );
}
break;

// shouldn't get here
default: assert( FALSE ); break;
}
}
}
Expand All @@ -7072,36 +7133,36 @@ void Chuck_Instr_Dot_Cmp_Third::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )

//-----------------------------------------------------------------------------
// name: execute()
// desc: ...
// desc: print the fourth field of a complex/polar/vec3/vec4 value
//-----------------------------------------------------------------------------
void Chuck_Instr_Dot_Cmp_Fourth::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
{
// reg contains pointer to complex elsewhere
if( m_is_mem )
{
// stack
// pointer
t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr on
// push var addr or value?
if( m_emit_addr ) {
// push addr
push_( sp, (t_CKUINT)(&((*(t_CKVEC4 **)sp)->w)) );
} else {
// push value
push_float( sp, (*(t_CKVEC4 **)sp)->w );
}
}
else
{
// stack
// make sure...
assert( m_emit_addr == FALSE );
assert( m_kind == kindof_VEC4 );

// get vec4 value, pop that value, push field
t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
// pop
pop_( sp, 1 );
// push the addr, um we can't
if( m_emit_addr ) {
assert( FALSE );
} else {
push_float( sp, sp->w );
}
push_float( sp, sp->w );
}
}

Expand Down Expand Up @@ -8480,7 +8541,7 @@ void Chuck_Instr_Gack::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
if( *(sp) == 0 )
CK_FPRINTF_STDERR( "null " );
else
CK_FPRINTF_STDERR( "0x%lx (refcount=%d)", *(sp), obj->m_ref_count );
CK_FPRINTF_STDERR( "0x%lx (refcount=%d) ", *(sp), obj->m_ref_count );
}
else
{
Expand Down
20 changes: 12 additions & 8 deletions src/core/chuck_instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -3547,8 +3547,8 @@ struct Chuck_Instr_Dot_Static_Func : public Chuck_Instr
struct Chuck_Instr_Dot_Cmp_First : public Chuck_Instr
{
public:
Chuck_Instr_Dot_Cmp_First( t_CKUINT is_mem, t_CKUINT emit_addr )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; }
Chuck_Instr_Dot_Cmp_First( t_CKUINT is_mem, t_CKUINT emit_addr, te_KindOf kind )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; m_kind = kind; }

public:
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
Expand All @@ -3560,6 +3560,7 @@ struct Chuck_Instr_Dot_Cmp_First : public Chuck_Instr
protected:
t_CKUINT m_is_mem;
t_CKUINT m_emit_addr;
te_KindOf m_kind;
};


Expand All @@ -3572,8 +3573,8 @@ struct Chuck_Instr_Dot_Cmp_First : public Chuck_Instr
struct Chuck_Instr_Dot_Cmp_Second : public Chuck_Instr
{
public:
Chuck_Instr_Dot_Cmp_Second( t_CKUINT is_mem, t_CKUINT emit_addr )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; }
Chuck_Instr_Dot_Cmp_Second( t_CKUINT is_mem, t_CKUINT emit_addr, te_KindOf kind )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; m_kind = kind; }

public:
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
Expand All @@ -3585,6 +3586,7 @@ struct Chuck_Instr_Dot_Cmp_Second : public Chuck_Instr
protected:
t_CKUINT m_is_mem;
t_CKUINT m_emit_addr;
te_KindOf m_kind;
};


Expand All @@ -3597,8 +3599,8 @@ struct Chuck_Instr_Dot_Cmp_Second : public Chuck_Instr
struct Chuck_Instr_Dot_Cmp_Third : public Chuck_Instr
{
public:
Chuck_Instr_Dot_Cmp_Third( t_CKUINT is_mem, t_CKUINT emit_addr )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; }
Chuck_Instr_Dot_Cmp_Third( t_CKUINT is_mem, t_CKUINT emit_addr, te_KindOf kind )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; m_kind = kind; }

public:
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
Expand All @@ -3610,6 +3612,7 @@ struct Chuck_Instr_Dot_Cmp_Third : public Chuck_Instr
protected:
t_CKUINT m_is_mem;
t_CKUINT m_emit_addr;
te_KindOf m_kind;
};


Expand All @@ -3622,8 +3625,8 @@ struct Chuck_Instr_Dot_Cmp_Third : public Chuck_Instr
struct Chuck_Instr_Dot_Cmp_Fourth : public Chuck_Instr
{
public:
Chuck_Instr_Dot_Cmp_Fourth( t_CKUINT is_mem, t_CKUINT emit_addr )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; }
Chuck_Instr_Dot_Cmp_Fourth( t_CKUINT is_mem, t_CKUINT emit_addr, te_KindOf kind )
{ m_is_mem = is_mem; m_emit_addr = emit_addr; m_kind = kind; }

public:
virtual void execute( Chuck_VM * vm, Chuck_VM_Shred * shred );
Expand All @@ -3635,6 +3638,7 @@ struct Chuck_Instr_Dot_Cmp_Fourth : public Chuck_Instr
protected:
t_CKUINT m_is_mem;
t_CKUINT m_emit_addr;
te_KindOf m_kind;
};


Expand Down
Loading

0 comments on commit e446ab3

Please sign in to comment.