Skip to content

Commit

Permalink
fix: prevent losing struct instance reference on assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
hlolli committed Dec 13, 2022
1 parent c02b518 commit c8cfe37
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 16 deletions.
10 changes: 5 additions & 5 deletions Engine/csound_orc_optimize.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ static inline int same_type(char *var, char ty)
else return var[0]==ty;
}
*/
static inline int same_type(char *var, char ty)
{
if (var[0]=='g') return var[1]==ty;
else return var[0]==ty;
}
// static inline int same_type(char *var, char ty)
// {
// if (var[0]=='g') return var[1]==ty;
// else return var[0]==ty;
// }

#define PARSER_DEBUG1 (0)
//static TREE* remove_excess_assigns(CSOUND *csound, TREE* root)
Expand Down
15 changes: 15 additions & 0 deletions Engine/csound_orc_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -2098,6 +2098,21 @@ void initializeStructVar(CSOUND* csound, CS_VARIABLE* var, MYFLT* mem) {
CS_STRUCT_VAR* structVar = (CS_STRUCT_VAR*)mem;
CS_TYPE* type = var->varType;
CONS_CELL* members = type->members;

// if it's an assignment from one user defined object to another
// we create a reference to it instead of initializing new struct
if (var->varType->userDefinedType && var->next != NULL &&
strcmp(var->varType->varTypeName, var->next->varType->varTypeName) == 0) {
var->next->refCount += 1;
var->varType = var->next->varType;
var->memBlock = var->next->memBlock;
var->memBlockSize = var->next->memBlockSize;
var->memBlockIndex = var->next->memBlockIndex;
var->dimensions = var->next->dimensions;
var->subType = var->next->subType;
var->updateMemBlockSize = var->next->updateMemBlockSize;
}

int len = cs_cons_length(members);
int i;

Expand Down
54 changes: 43 additions & 11 deletions tests/commandline/structs/test_structs.csd
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,32 @@ ksmps = 1
nchnls = 2
0dbfs = 1
struct MyType imaginary:k, real:k, kimaginary, kreal
struct MyType imaginary:k, real:k, kimaginary, kreal
struct MyType2 x:i, y:i
opcode processMyType(in:MyType):(MyType)
retVal:MyType init 0, 0, 0, 0
retVal.imaginary = in.imaginary + 1
retVal.real = in.real + 1
retVal.imaginary = in.imaginary + 1
retVal.real = in.real + 1
retVal.kimaginary = in.kimaginary + 1
retVal.kreal = in.kreal + 1
retVal.kreal = in.kreal + 1
xout retVal
endop
instr 1
instr 1
var0:MyType init 1, 2, 3, 4
var0:MyType init 1, 2, 3, 4
;var1:MyType = init:MyType(0, 0, 1, 1)
var0.imaginary init 5
var0.real init 6
var0.kimaginary init 7
var0.kreal init 9
var0.imaginary += 1
var0.real += 2
var0.kimaginary += 3
var0.kreal += 4
var0.imaginary += 1
var0.real += 2
var0.kimaginary += 3
var0.kreal += 4
var2:MyType processMyType var0
Expand All @@ -42,12 +43,43 @@ printks "\ti %d r %d ki %d kr %d\n", 0.2, var2.imaginary, var2.real, var2.kimagi
endin
;; make sure that struct references
;; refer correctly to their original pointer
instr 2
iexitCode = 0
var1:MyType2 init 1, 2
var2:MyType2 = var1
var2.x = 6
var2.y = 7
iexpect6 = var1.x
iexpect7 = var1.y
if iexpect6 != 6 then
iexitCode = 1
endif
if iexpect7 != 7 then
iexitCode = 1
endif
if iexitCode == 0 then
prints "struct reference test success\n"
else
prints "struct reference test failed!\n"
exitnow 1
endif
endin
</CsInstruments>
; ==============================================
<CsScore>
i1 0 0.5
i2 + 0
</CsScore>
</CsoundSynthesizer>

0 comments on commit c8cfe37

Please sign in to comment.