- added per-channel access for color variables. However, since they are locally stored in registers, it required a minor bit of fudging for this case.

- make sure that a PFunction's implementation is always initialized before starting the code generator.
This commit is contained in:
Christoph Oelckers 2016-11-21 12:38:39 +01:00
parent 393bcf9e91
commit de2eb18727
6 changed files with 48 additions and 1 deletions

View file

@ -5652,6 +5652,10 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
SAFE_RESOLVE(Object, ctx);
// allow accessing the color chanels by mapping the type to a matching struct which defines them.
if (Object->ValueType == TypeColor)
Object->ValueType = TypeColorStruct;
if (Object->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
{
auto ptype = static_cast<PPointer *>(Object->ValueType)->PointedType;
@ -6305,6 +6309,26 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
delete this;
return locvar;
}
else if (classx->ExprType == EFX_LocalVariable && classx->ValueType == TypeColorStruct)
{
// This needs special treatment because it'd require accessing the register via address.
// Fortunately this is the only place where this kind of access is ever needed so an explicit handling is acceptable.
int bits;
switch (membervar->SymbolName.GetIndex())
{
case NAME_a: bits = 24; break;
case NAME_r: bits = 16; break;
case NAME_g: bits = 8; break;
case NAME_b: default: bits = 0; break;
}
classx->ValueType = TypeColor; // need to set it back.
FxExpression *x = classx;
if (bits > 0) x = new FxShift(TK_URShift, x, new FxConstant(bits, ScriptPosition));
x = new FxBitOp('&', x, new FxConstant(255, ScriptPosition));
classx = nullptr;
delete this;
return x->Resolve(ctx);
}
else
{
if (!(classx->RequestAddress(ctx, &AddressWritable)))

View file

@ -785,6 +785,8 @@ VMFunction *FFunctionBuildList::AddFunction(PFunction *functype, FxExpression *c
it.StateIndex = stateindex;
it.StateCount = statecount;
it.Lump = lumpnum;
assert(it.Func->Variants.Size() == 1);
it.Func->Variants[0].Implementation = it.Function;
// set prototype for named functions.
if (it.Func->SymbolName != NAME_None)

View file

@ -2272,7 +2272,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
auto code = ConvertAST(c->Type(), f->Body);
if (code != nullptr)
{
sym->Variants[0].Implementation = FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
FunctionBuildList.AddFunction(sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
}
}
}