Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't compile and run React.JS #1

Open
daurnimator opened this issue Sep 12, 2014 · 7 comments
Open

Can't compile and run React.JS #1

daurnimator opened this issue Sep 12, 2014 · 7 comments

Comments

@daurnimator
Copy link

@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.

@PaulBernier
Copy link
Owner

Hello @daurnimator,
Thanks for posting the very first issue!
Concerning the first error, I fixed the bug in commit ef200f4
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.

@daurnimator
Copy link
Author

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 indexing 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.

@daurnimator
Copy link
Author

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 7b3ad4f

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....

@PaulBernier
Copy link
Owner

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...

@daurnimator
Copy link
Author

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.

@daurnimator
Copy link
Author

daurnimator commented Apr 28, 2016

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.

@PaulBernier
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants