When you use a boolean expression inside of a binary operation like addition, subtraction, multiplication or modulo, the compiler will convert it into an int, but mistreats it as double for the binary operation, which can cause games to crash upon execution with an error "Malformed variable".
The boolean to int conversion (conv.b.i) is followed by a variable-double addition (add.d.v). However, it should actually be a variable-int addition (add.i.v) since the boolean was converted to int, not double.
This issue lies in the implementation of Compiler::AssemblyWriter::ConvertTypeToBinaryOp:
private static void ConvertTypeForBinaryOp(CodeWriter cw, Lexer.Token.TokenKind kind)
{
var type = cw.typeStack.Peek();
switch (kind)
{
// ...
case Lexer.Token.TokenKind.Plus:
case Lexer.Token.TokenKind.Minus:
case Lexer.Token.TokenKind.Times:
case Lexer.Token.TokenKind.Div:
case Lexer.Token.TokenKind.Mod:
if (type == DataType.BOOLEAN)
{
cw.typeStack.pop();
cw.Emit(Opcode.Conv, type, DataType.Int32);
cw.typeStack.Push(DataType.Double); // Wrongly pushes double as a data type after converting to int
}
break;
// ...
}
}
Reproducing steps
Go into any code inside of any GameMaker game
Add the following statements at the end:
a = 1 + (a > 0)
Go to the end of the disassembly tab
The assembly will wrongly contain conv.b.i followed by add.d.i
Describe the bug
When you use a boolean expression inside of a binary operation like addition, subtraction, multiplication or modulo, the compiler will convert it into an int, but mistreats it as double for the binary operation, which can cause games to crash upon execution with an error "Malformed variable".
Example:
gets compiled into:
The boolean to int conversion (
conv.b.i
) is followed by a variable-double addition (add.d.v
). However, it should actually be a variable-int addition (add.i.v
) since the boolean was converted to int, not double.This issue lies in the implementation of
Compiler::AssemblyWriter::ConvertTypeToBinaryOp
:Reproducing steps
conv.b.i
followed byadd.d.i
Setup Details