- allow defining native fields through scripts. Internally this only requires exporting the address, but not the entire field.
- added new VARF_Transient flag so that the decision whether to serialize a field does not depend solely on its native status. It may actually make a lot of sense to use the auto-serializer for native fields, too, as this would eliminate a lot of maintenance code. - defined (u)int8/16 as aliases to the byte and short types (Can't we not just get rid of this naming convention already...?) - exporting the fields of Actor revealed a few name clashes between them and some global types, so Actor.Sector was renamed to CurSector and Actor.Inventory was renamed to Actor.Inv.
This commit is contained in:
parent
ab5c11064a
commit
980c986305
22 changed files with 520 additions and 202 deletions
|
|
@ -1186,6 +1186,7 @@ void ZCCCompiler::CompileAllFields()
|
|||
// Create copies of the arrays which can be altered
|
||||
auto Classes = this->Classes;
|
||||
auto Structs = this->Structs;
|
||||
TMap<PClass*, bool> HasNativeChildren;
|
||||
|
||||
// first step: Look for native classes with native children.
|
||||
// These may not have any variables added to them because it'd clash with the native definitions.
|
||||
|
|
@ -1200,8 +1201,8 @@ void ZCCCompiler::CompileAllFields()
|
|||
{
|
||||
if (ac->ParentClass == c->Type() && ac->Size != TentativeClass)
|
||||
{
|
||||
Error(c->cls, "Trying to add fields to class '%s' with native children", c->Type()->TypeName.GetChars());
|
||||
Classes.Delete(i--);
|
||||
// Only set a marker here, so that we can print a better message when the actual fields get added.
|
||||
HasNativeChildren.Insert(ac, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1236,7 +1237,7 @@ void ZCCCompiler::CompileAllFields()
|
|||
type->Size = Classes[i]->Type()->ParentClass->Size;
|
||||
}
|
||||
}
|
||||
if (CompileFields(type, Classes[i]->Fields, nullptr, &Classes[i]->TreeNodes, false))
|
||||
if (CompileFields(type, Classes[i]->Fields, nullptr, &Classes[i]->TreeNodes, false, !!HasNativeChildren.CheckKey(type)))
|
||||
{
|
||||
// Remove from the list if all fields got compiled.
|
||||
Classes.Delete(i--);
|
||||
|
|
@ -1263,11 +1264,12 @@ void ZCCCompiler::CompileAllFields()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct)
|
||||
bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren)
|
||||
{
|
||||
while (Fields.Size() > 0)
|
||||
{
|
||||
auto field = Fields[0];
|
||||
FieldDesc *fd = nullptr;
|
||||
|
||||
PType *fieldtype = DetermineType(type, field, field->Names->Name, field->Type, true, true);
|
||||
|
||||
|
|
@ -1289,8 +1291,9 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fiel
|
|||
|
||||
if (field->Flags & ZCC_Native)
|
||||
{
|
||||
// todo: get the native address of this field.
|
||||
varflags |= VARF_Native | VARF_Transient;
|
||||
}
|
||||
|
||||
if (field->Flags & ZCC_Meta)
|
||||
{
|
||||
varflags |= VARF_ReadOnly; // metadata implies readonly
|
||||
|
|
@ -1312,8 +1315,32 @@ bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fiel
|
|||
{
|
||||
thisfieldtype = ResolveArraySize(thisfieldtype, name->ArraySize, &type->Symbols);
|
||||
}
|
||||
|
||||
type->AddField(name->Name, thisfieldtype, varflags);
|
||||
|
||||
if (varflags & VARF_Native)
|
||||
{
|
||||
fd = FindField(type, FName(name->Name).GetChars());
|
||||
if (fd == nullptr)
|
||||
{
|
||||
Error(field, "The member variable '%s.%s' has not been exported from the executable.", type->TypeName.GetChars(), FName(name->Name).GetChars());
|
||||
}
|
||||
else if (thisfieldtype->Size != fd->FieldSize)
|
||||
{
|
||||
Error(field, "The member variable '%s.%s' has mismatching sizes in internal and external declaration. (Internal = %d, External = %d)", type->TypeName.GetChars(), FName(name->Name).GetChars(), fd->FieldSize, thisfieldtype->Size);
|
||||
}
|
||||
// Q: Should we check alignment, too? A mismatch may be an indicator for bad assumptions.
|
||||
else
|
||||
{
|
||||
type->AddNativeField(name->Name, thisfieldtype, fd->FieldOffset, varflags, fd->BitValue);
|
||||
}
|
||||
}
|
||||
else if (hasnativechildren)
|
||||
{
|
||||
Error(field, "Cannot add field %s to %s. %s has native children which means it size may not change.", type->TypeName.GetChars(), fd->FieldSize, FName(name->Name).GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
type->AddField(name->Name, thisfieldtype, varflags);
|
||||
}
|
||||
}
|
||||
name = static_cast<ZCC_VarName*>(name->SiblingNext);
|
||||
} while (name != field->Names);
|
||||
|
|
@ -2133,7 +2160,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
afd = FindFunction(c->Type(), FName(f->Name).GetChars());
|
||||
if (afd == nullptr)
|
||||
{
|
||||
Error(f, "The function '%s' has not been exported from the executable.", FName(f->Name).GetChars());
|
||||
Error(f, "The function '%s.%s' has not been exported from the executable.", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue