castl
castl copied to clipboard
Can't compile and run React.JS
@zeen thought it would be cool to compile React.JS into Lua. The JS source file: http://fb.me/react-0.11.1.js
The first error is
lua: ./castl/prototype/regexp.lua:110: bad argument #1 to 'find' (string, table or userdata expected, got boolean)
stack traceback:
[C]: in function 'find'
./castl/prototype/regexp.lua:110: in function 'test'
react-0.11.1.lua:4840: in function 'inject'
react-0.11.1.lua:2388: in function <react-0.11.1.lua:2367>
(...tail calls...)
react-0.11.1.lua:37: in function 's'
react-0.11.1.lua:48: in function <react-0.11.1.lua:14>
react-0.11.1.lua:14: in function 'e'
react-0.11.1.lua:9: in function <react-0.11.1.lua:9>
react-0.11.1.lua:9: in function <react-0.11.1.lua:2>
react-0.11.1.lua:2: in main chunk
[C]: in ?
Which comes from https://github.com/facebook/react/blob/8cb2812cff6a6cb54bb673254f1170281ce0790a/src/browser/ui/ReactDefaultInjection.js#L117 I just set the conditional to false so I could continue; but there's something weird going on there.
The next error I get is
lua: react-0.11.1.lua:10: attempt to index upvalue 'f' (a nil value)
stack traceback:
react-0.11.1.lua:10: in function <react-0.11.1.lua:10>
react-0.11.1.lua:10: in function <react-0.11.1.lua:3>
react-0.11.1.lua:3: in main chunk
[C]: in ?
Which is in the module definition bit at the start.
Hello @daurnimator,
Thanks for posting the very first issue!
Concerning the first error, I fixed the bug in commit ef200f45abe8105d2217834b90aef59c4ab0da6a
Concerning the second point, it fails because react.js try to execute as in a browser (but it can't find the window object). If you use the --node
option to castl (~ very basically simulate node environment for now), it compiles and execute without error. But I don't know react.js, and what it does, so I can't test it further, tell me if you manage to do something useful with that.
Hello @daurnimator, Thanks for posting the very first issue!
No problem, I think CASTL is an interesting idea, even if I don't have an application for it yet.
Concerning the first error, I fixed the bug in commit ef200f4
Thanks!
it fails because react.js try to execute as in a browser (but it can't find the window object)
Ah ha, yeah, it looks for exports
, define
, window
, global
and self
. None of them exist in CASTL.... so it just ends up index
ing nil. My first thought it is should fallback to this
instead of just trying anyway.
If you use the --node option to castl (~ very basically simulate node environment for now), it compiles and execute without error.
Thanks for that hint.
One small issue there is that you return exports
rather than module.exports
(see http://nodejs.org/api/modules.html#modules_module_exports )
With that small modification, React seems to at least load :D
I'll have a closer look into seeing if it actually does what it should soon.
One small issue there is that you return exports rather than module.exports (see http://nodejs.org/api/modules.html#modules_module_exports )
With that small modification, React seems to at least load :D
Thanks, looks like you fixed that in 7b3ad4f8a76e62d3afc5bfba8c40fdbec8fcac02
I'll have a closer look into seeing if it actually does what it should soon.
I'm now just trying to run the most minimal of React code:
local React = require "react"
local c = React.DOM:h1({}, "Hello world!")
print(React:renderComponentToString(c))
But getting an error:
lua: ./castl/internal.lua:131: attempt to index local 'mt' (a nil value)
stack traceback:
./castl/internal.lua:131: in function 'toPrimitive'
./castl/jssupport.lua:169: in function '_eq'
./react.lua:5408: in function <./react.lua:5404>
(...tail calls...)
./react.lua:5624: in function 'h1'
test.lua:3: in main chunk
[C]: in ?
It appears I need to wrap my table; which is reasonable:
local React = require "react"
local cr = require("castl.runtime")
local Object = cr._obj
local c = React.DOM:h1(Object{}, "Hello world!")
print(React:renderComponentToString(c))
This runs, but prints out the wrong thing..... a random html element. e.g. <br data-reactid=".121MYOMUD7O" data-react-checksum="2884766134">
This indicates that something is wrong elsewhere....
I had a hardtime figuring out what was going on (and fixed 2 others little things in passing) and I found that the core problem come from lua5.2:
for i=0,5 do
local a = function() end;
print(a);
end
If you execute this snippet with Lua5.2 you get something like:
function: 0x20fcc70
function: 0x20fcc70
function: 0x20fcc70
function: 0x20fcc70
function: 0x20fcc70
function: 0x20fcc70
So if you store these local functions in an array for example they'll all point to the same address, which is not the expected behavior in JS... By the way if you execute this code with Lua5.1 or LuaJIT it's ok:
function: 0x41e71058
function: 0x41e71078
function: 0x41e71158
function: 0x41e71338
function: 0x41e6b020
function: 0x41e6b070
Did you ever heard about this problem and any workaround? (I believe Tessel modified their lua VM to fix it) Sadly for now the only thing I can tell you is to use LuaJIT instead of Lua5.2...
Did you ever heard about this problem and any workaround?
This usually isn't a problem but a feature. Identical functions compare equal :p
You could get around it by having non-identical functions (e.g. if they have a different upvalue)
for i=0,5 do
local a = function() local _ = i end;
print(a);
end
function: 0xf70420
function: 0xfc2450
function: 0xfc2a50
function: 0xfc2b20
function: 0xfc2bf0
function: 0xfc2cc0
Or by wrapping them (which you sort of should be doing to get JS semantics around functions anyway):
local Func_mt = {
__call = function(t,this,...)
return t.raw(this,...)
end;
}
local function JSFunc(raw)
return setmetatable({raw=raw}, Func_mt)
end
for i=0,5 do
local a = JSFunc(function() end);
print(a);
end
table: 0x248ab70
table: 0x2483380
table: 0x24834a0
table: 0x248b160
table: 0x248b280
table: 0x248b3a0
Of course, you can put a nice __tostring
on.
I had another attempt at this today with a newer release of react:
local React = require "react"
local cr = require("castl.runtime")
local ReactDOMServer = React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED -- I don't know how to access things `define`d with castl.
local Object = cr._obj
local c = React.DOM:h1(Object{foo="bar"}, "Hello world!")
local s = ReactDOMServer:renderToString(c)
print(s)
it doesn't return anything. I tried to track it down but ran out of time.
I figured out the root cause: it's a pretty deep problem with regular expression including some utf8 characters... I'll try to find a fix for that. Still I don't understand why the error thrown don't propagate and is not displayed explicitly, took me hours to understand.