mherkender / lua.js

An ECMAscript framework to compile and run Lua code, allowing Lua to run in a browser or in Flash
http://blog.brokenfunction.com/
600 stars 73 forks source link

more detailed error messages #10

Closed ghoulsblade closed 12 years ago

ghoulsblade commented 12 years ago

I'm often running into not-yet-implemented stuff when trying my something in my luajs-based webplayer. Finding out what's missing is a pain, so i started experimenting with error messages.

example 1

local myobj = {}
myobj:MissingMethod(1,2,3)
-- luajs master : TypeError: Cannot read property 'metatable' of null
-- lua native : attempt to call method 'MissingMethod' (a nil value)
-- luajs changed (lualib.js only) : Error: attempt to call method 'MissingMethod' (a nil value)

example 2

local myfun1 = nil
myfun1()
-- luajs master : TypeError: Cannot read property 'metatable' of null
-- lua native : attempt to call local 'myfun1' (a nil value)
-- luajs changed (lualib.js only) : Error: attempt to call nil (undefined)
-- luajs changed (lualib.js + bison(see below)) : Error: attempt to call nil (_myfun1_)

example 3

local love = { graphics = {} } 
love.graphics.setDefaultImageFilter('linear','nearest')
-- luajs master : TypeError: Cannot read property 'metatable' of null
-- lua native : attempt to call field 'setDefaultImageFilter' (a nil value)
-- luajs changed (lualib.js only) : Error: attempt to call nil (undefined)
-- luajs changed (lualib.js + bison(see below)) : Error: attempt to call nil (lua_tableget(lua_tableget(_love_33, 'graphics'), 'setDefaultImageFilter)

bison : i don't know how to work with bison, so what i did was replace

case 91: this.$ = "lua_call( /*bla!*/ " + $$[$0-1].single + ", " + getTempDecl($$[$0]) + " )";

by

case 91: this.$ = "lua_call( /*bla!*/ " + $$[$0-1].single + ", " + getTempDecl($$[$0]) + ", "+longStringToString($$[$0-1].single)+")";

in the generated js code. ugly _ for example 2, and ugly js bulkwork around "setDefaultImageFilter" for example 3, but it already shows useful info and makes debugging a lot easier if you ask me. i'm pretty sure it's in src/lua.jison Line 598 ff:

functioncall
  : prefixexp args { $$ = "lua_call(" + $1.single + ", " + getTempDecl($2) + ")"; } 
  | prefixexp ":" NAME args { $$ = "lua_mcall(" + $1.single + ", '" + $3 + "', " + getTempDecl($4) + ")"; }
  ;

any idea how to generate a useful 3rd "origin" parameter for lua_call here ? the 2nd case with lua_mcall already works (see example1), but i don't even know how to set up node.js/jison/... , so i cannot try it. plus i wouldn't even know what i would be doing. If field name is unavailable, chunkname+linenumber as text would be useful.

mherkender commented 12 years ago

I agree, I've had some trouble with these poor error messages in the past.

myobj:MissingMethod(1,2,3)

I have to alter your version (doesn't match the code standards in lua.js) but I think it's great.

love.graphics.setDefaultImageFilter('linear','nearest')

I'm altering lua_call(lua_tableget(table, key), args) function calls to call a new function lua_tablegetcall which does the same thing. It however, knows what "key" is and can deliver the same error message as Lua 5.1 in this case.

myfun1()

This scenario is a bit different. The only way to match Lua's error messages is to pass in a string, like your examples above. I don't want to do this because it increases code size (unlike lua_tablegetcall above).

Right now I've improved it to the point it resembles the "luajs changed (lualib.js only)" version, which combined with a stack trace, is hopefully enough.

mherkender commented 12 years ago

Also, I've altered the error messages when setting/getting values in tables to better resemble their Lua 5.1 counterparts.