-fixed type handling for varargs (i.e. A_Jump.)

This commit is contained in:
Christoph Oelckers 2016-10-26 14:15:11 +02:00
parent 7c759f9fcf
commit a166183ab4

View file

@ -1067,6 +1067,7 @@ FxTypeCast::FxTypeCast(FxExpression *x, PType *type, bool nowarn)
{
basex = x;
ValueType = type;
assert(ValueType != nullptr);
}
//==========================================================================
@ -5410,9 +5411,19 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
if (ArgList != NULL)
{
bool foundvarargs = false;
PType * type = nullptr;
for (unsigned i = 0; i < ArgList->Size(); i++)
{
FxExpression *x = new FxTypeCast((*ArgList)[i], argtypes[i + implicit], false);
// Varargs must all have the same type as the last typed argument. A_Jump is the only function using it.
if (!foundvarargs)
{
if (argtypes[i + implicit] == nullptr) foundvarargs = true;
else type = argtypes[i + implicit];
}
assert(type != nullptr);
FxExpression *x = new FxTypeCast((*ArgList)[i], type, false);
x = x->Resolve(ctx);
failed |= (x == nullptr);
(*ArgList)[i] = x;
@ -7062,57 +7073,6 @@ ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
return dest;
}
//==========================================================================
//
//
//
//==========================================================================
FxDamageValue::FxDamageValue(FxExpression *v)
: FxExpression(EFX_DamageValue, v->ScriptPosition)
{
val = v;
ValueType = TypeVoid;
}
FxDamageValue::~FxDamageValue()
{
SAFE_DELETE(val);
}
FxExpression *FxDamageValue::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
SAFE_RESOLVE(val, ctx)
if (!val->IsNumeric())
{
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
delete this;
return NULL;
}
return this;
}
// This is a highly-specialized "expression" type that emits a complete function.
ExpEmit FxDamageValue::Emit(VMFunctionBuilder *build)
{
if (val->isConstant())
{
build->EmitRetInt(0, false, static_cast<FxConstant *>(val)->GetValue().Int);
}
else
{
ExpEmit emitval = val->Emit(build);
assert(emitval.RegType == REGT_INT);
build->Emit(OP_RET, 0, REGT_INT | (emitval.Konst ? REGT_KONST : 0), emitval.RegNum);
}
build->Emit(OP_RETI, 1 | RET_FINAL, true);
return ExpEmit();
}
//==========================================================================
//
// declares a single local variable (no arrays)