dibyendumajumdar / ravi

Ravi is a dialect of Lua, featuring limited optional static typing, JIT and AOT compilers
http://ravilang.github.io/
Other
1.16k stars 60 forks source link

Wrong Type Deduction for BNOT #209

Open XmiliaH opened 3 years ago

XmiliaH commented 3 years ago

In the case where BNOT receives a float as input, it will deduce that the output is a float too. However, this is wrong since at runtime BNOT will cast the float to an integer first and return an integer. The problem seems to be in the parser near https://github.com/dibyendumajumdar/ravi/blob/56a59a1f3117a8bc88206305b94398678de1bdff/src/lcode.c#L1580

To demonstrate the issue the following code will fail with src/lvm.c:2422: luaV_execute: Assertion `((((rb))->tt_) == (((3) | ((0) << 4))))' failed.

local function f()
    local x:number = 1.0
    return (~x) + 1
end
print(f())

The bytecode from function f is

1       [2]     LOADK           0 -1    ; 1.0
2       [3]     BNOT            1 0
3       [3]     ADDFI           1 1 -2  ; - 1
4       [3]     RETURN          1 2
5       [4]     RETURN          0 1

with the unexpected ADDFI.

dibyendumajumdar commented 3 years ago

Thank you for the report. I will check

dibyendumajumdar commented 3 years ago

The problem seems to be that BNOT will convert floats that have no decimal to int, so ADDFI fails because it was expecting a float.

dibyendumajumdar commented 3 years ago

I have a fix but I need to test it

dibyendumajumdar commented 3 years ago

I have pushed some fixes for this and the others you reported. Please check and let me know if the issues reported are now fixed

XmiliaH commented 3 years ago

The LEN one ist not fully fixed. I noticed that it didn't fail the way I intended since the array indexing was put in parenthesis. So the following will fail with the given description:

debug.setmetatable(1, {
    __len = function()
        return "123"
    end
})

local function f(x:integer[])
    return #x[1] + 1
end

print(f(table.intarray(2)))

The others looked good to me, but I noticed that in ravi_resize_array the t->size + 10 could overflow.

dibyendumajumdar commented 3 years ago

Okay looks like you found a different bug here - the expression #x results in int but then int[1] is not correctly being handled

XmiliaH commented 3 years ago

The problem here is that https://github.com/dibyendumajumdar/ravi/blob/fe7c76fff50c098f38470757acaed3cafdf47ff1/src/lcode.c#L1270 can change the result of e->ravi_type. You need to swap this and the first line of the function.

dibyendumajumdar commented 3 years ago

I think you are correct. Thank you!