Fix struct over header boundaries

This commit is contained in:
drmortalwombat 2021-09-19 20:00:36 +02:00
parent 3ce8796beb
commit 10bb751449
9 changed files with 116 additions and 37 deletions

View File

@ -1035,6 +1035,25 @@ __asm inp_store_frame_32
#pragma bytecode(BC_STORE_FRAME_32, inp_store_frame_32) #pragma bytecode(BC_STORE_FRAME_32, inp_store_frame_32)
__asm inp_lea_frame
{
lda (ip), y
tax
iny
clc
lda (ip), y
adc sp
sta $00, x
iny
lda (ip), y
adc sp + 1
sta $01, x
iny
jmp startup.exec
}
#pragma bytecode(BC_LEA_FRAME, inp_lea_frame)
__asm inp_op_negate_16 __asm inp_op_negate_16
{ {
sec sec

View File

@ -61,6 +61,8 @@ enum ByteCode
BC_STORE_FRAME_16, BC_STORE_FRAME_16,
BC_STORE_FRAME_32, BC_STORE_FRAME_32,
BC_LEA_FRAME,
BC_LOAD_ADDR_8, BC_LOAD_ADDR_8,
BC_LOAD_ADDR_U8, BC_LOAD_ADDR_U8,
BC_LOAD_ADDR_I8, BC_LOAD_ADDR_I8,

View File

@ -86,7 +86,7 @@ bool ByteCodeInstruction::LoadsRegister(uint32 reg) const
return true; return true;
if (mCode >= BC_CONST_8 && mCode <= BC_CONST_32) if (mCode >= BC_CONST_8 && mCode <= BC_CONST_32)
return true; return true;
if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL) if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL || mCode == BC_LEA_FRAME)
return true; return true;
} }
@ -136,7 +136,7 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true; return true;
if (mCode >= BC_CONST_8 && mCode <= BC_CONST_32) if (mCode >= BC_CONST_8 && mCode <= BC_CONST_32)
return true; return true;
if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL) if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL || mCode == BC_LEA_FRAME)
return true; return true;
if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_MULI8_16) if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_MULI8_16)
return true; return true;
@ -302,6 +302,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
break; break;
case BC_LEA_LOCAL: case BC_LEA_LOCAL:
case BC_LEA_FRAME:
block->PutCode(generator, mCode); block->PutCode(generator, mCode);
block->PutByte(mRegister); block->PutByte(mRegister);
block->PutWord(uint16(mValue)); block->PutWord(uint16(mValue));
@ -621,6 +622,13 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
bins.mValue = ins->mIntValue + ins->mVarIndex + proc->mLocalSize + 2; bins.mValue = ins->mIntValue + ins->mVarIndex + proc->mLocalSize + 2;
mIns.Push(bins); mIns.Push(bins);
} }
else if (ins->mMemory == IM_FRAME)
{
ByteCodeInstruction bins(BC_LEA_FRAME);
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
bins.mValue = ins->mVarIndex + ins->mSIntConst[1] + 2;
mIns.Push(bins);
}
else if (ins->mMemory == IM_PROCEDURE) else if (ins->mMemory == IM_PROCEDURE)
{ {
ByteCodeInstruction bins(BC_CONST_16); ByteCodeInstruction bins(BC_CONST_16);
@ -3240,6 +3248,11 @@ void ByteCodeProcedure::Disassemble(FILE * file, ByteCodeGenerator * generator,
i += 3; i += 3;
break; break;
case BC_LEA_FRAME:
fprintf(file, "LEA\t%s, %d(SP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2]));
i += 3;
break;
case BC_STORE_FRAME_8: case BC_STORE_FRAME_8:
fprintf(file, "MOVB\t%d(SP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc)); fprintf(file, "MOVB\t%d(SP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
i += 2; i += 2;

View File

@ -50,6 +50,8 @@ enum ByteCode
BC_STORE_FRAME_16, BC_STORE_FRAME_16,
BC_STORE_FRAME_32, BC_STORE_FRAME_32,
BC_LEA_FRAME,
BC_LOAD_ADDR_8, BC_LOAD_ADDR_8,
BC_LOAD_ADDR_U8, BC_LOAD_ADDR_U8,
BC_LOAD_ADDR_I8, BC_LOAD_ADDR_I8,

View File

@ -405,7 +405,12 @@ bool Declaration::IsSame(const Declaration* dec) const
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID) else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true; return true;
else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM) else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM)
return false; {
if (mIdent == dec->mIdent)
return true;
else
return false;
}
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return mBase->IsSame(dec->mBase); return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_FUNCTION) else if (mType == DT_TYPE_FUNCTION)
@ -459,6 +464,10 @@ bool Declaration::CanAssign(const Declaration* fromType) const
{ {
return true; return true;
} }
else if (mBase->mType == DT_TYPE_VOID && fromType->mType == DT_TYPE_FUNCTION)
{
return true;
}
} }
return false; return false;

View File

@ -1435,37 +1435,66 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock); vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock);
if (vr.mType->mType != DT_TYPE_ARRAY) if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)
vr = Dereference(proc, block, vr);
if (pdec)
{ {
if (!pdec->mBase->CanAssign(vr.mType)) if (pdec && !pdec->mBase->CanAssign(vr.mType))
mErrors->Error(texp->mLocation, "Cannot assign incompatible types"); mErrors->Error(texp->mLocation, "Cannot assign incompatible types");
vr = CoerceType(proc, block, vr, pdec->mBase);
}
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
{
vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration);
}
InterInstruction * wins = new InterInstruction(); vr = Dereference(proc, block, vr, 1);
wins->mCode = IC_STORE;
wins->mMemory = IM_INDIRECT; if (vr.mReference != 1)
wins->mSType[0] = InterTypeOf(vr.mType);; mErrors->Error(exp->mLeft->mLocation, "Not an adressable expression");
wins->mSTemp[0] = vr.mTemp;
wins->mSType[1] = IT_POINTER; InterInstruction* cins = new InterInstruction();
wins->mSTemp[1] = ains->mTTemp; cins->mCode = IC_COPY;
if (pdec) cins->mMemory = IM_INDIRECT;
wins->mOperandSize = pdec->mSize; cins->mSType[0] = IT_POINTER;
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY) cins->mSTemp[0] = vr.mTemp;
wins->mOperandSize = vr.mType->mSize; cins->mSType[1] = IT_POINTER;
cins->mSTemp[1] = ains->mTTemp;
cins->mOperandSize = vr.mType->mSize;
block->Append(cins);
atotal += cins->mOperandSize;
}
else else
wins->mOperandSize = 2; {
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
vr = Dereference(proc, block, vr, 1);
else
vr = Dereference(proc, block, vr);
block->Append(wins); if (pdec)
{
if (!pdec->mBase->CanAssign(vr.mType))
mErrors->Error(texp->mLocation, "Cannot assign incompatible types");
vr = CoerceType(proc, block, vr, pdec->mBase);
}
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
{
vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration);
}
InterInstruction* wins = new InterInstruction();
wins->mCode = IC_STORE;
wins->mMemory = IM_INDIRECT;
wins->mSType[0] = InterTypeOf(vr.mType);;
wins->mSTemp[0] = vr.mTemp;
wins->mSType[1] = IT_POINTER;
wins->mSTemp[1] = ains->mTTemp;
if (pdec)
wins->mOperandSize = pdec->mSize;
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY)
wins->mOperandSize = vr.mType->mSize;
else
wins->mOperandSize = 2;
block->Append(wins);
atotal += wins->mOperandSize;
}
atotal += wins->mOperandSize;
if (pdec) if (pdec)
pdec = pdec->mNext; pdec = pdec->mNext;
} }
@ -1541,6 +1570,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (cexp->mAsmInsType != ASMIT_BYTE) if (cexp->mAsmInsType != ASMIT_BYTE)
{ {
int opcode = AsmInsOpcodes[cexp->mAsmInsType][cexp->mAsmInsMode]; int opcode = AsmInsOpcodes[cexp->mAsmInsType][cexp->mAsmInsMode];
if (opcode < 0)
mErrors->Error(cexp->mLocation, "Invalid opcode adressing mode");
d[offset++] = opcode; d[offset++] = opcode;
} }

View File

@ -40,8 +40,11 @@ Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
} }
} }
dec->mIdent = structName; if (!dec->mIdent || !dec->mScope)
dec->mScope = new DeclarationScope(nullptr); {
dec->mIdent = structName;
dec->mScope = new DeclarationScope(nullptr);
}
if (mScanner->mToken == TK_OPEN_BRACE) if (mScanner->mToken == TK_OPEN_BRACE)
{ {

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,29,0 FILEVERSION 1,0,30,0
PRODUCTVERSION 1,0,29,0 PRODUCTVERSION 1,0,30,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.0.29.0" VALUE "FileVersion", "1.0.30.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.0.29.0" VALUE "ProductVersion", "1.0.30.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -512,15 +512,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{F445EC12-D294-4466-A17F-16892657646C}" "ProductCode" = "8:{3661BD30-0CEA-48FD-9F79-F3EE87E35F13}"
"PackageCode" = "8:{C263EE73-C81E-4C63-9EEA-4FD3EA106F58}" "PackageCode" = "8:{E524D01A-EAC6-47DD-A7F3-1E088056634C}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.0.29" "ProductVersion" = "8:1.0.30"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"