basho / erlang_js

A linked-in driver for Erlang to Mozilla's Spidermonkey Javascript runtime.
Apache License 2.0
238 stars 88 forks source link

js:call() not behaving as expected #42

Closed jan--f closed 10 years ago

jan--f commented 10 years ago

Hi, I was playing aroung with erlang_js and encountered the following behavior: I want to run the following js function with a string as the argument:

function(x)
{
    return x.split(" ");
}

there are three ways I can think of doing this and two work, whereas the third does not.

{ok, JS} = js_driver:new().
js:eval(JS, <<"function(x) {return x.split(\" \")}(\"foo bar\")">>).

and

{ok, JS} = js_driver:new().
js:define(JS, <<"var doSplit = function(x) {return x.split(\" \")}">>).
js:call(JS, <<"doSplit">>, [<<"foo bar">>]).

both return the expected {ok, [<<"foo">>, <<"bar">>]}

when I try to do call an anonymous function I get an error:

{ok, JS} = js_driver:new().
js:call(JS, <<"function(x) {return x.split(\" \")}">>, [<<"foo bar">>]).
{error,[{<<"lineno">>,1},
        {<<"message">>,
         <<"SyntaxError: missing ) in parenthetical">>},
        {<<"source">>,
         <<"JSON.stringify(function() { if (function(x) {return x.split(\" \");} === undefined) { thro"...>>}]}

something is going wrong with the space character in split(). If I pass it in as an argument it works fine again:

{ok, JS} = js_driver:new().
js:call(JS, <<"function(x, s) {return x.split(s)}">>, [<<"foo bar">>, <<" ">>]).
strange commented 10 years ago

Note that you can also wrap the space in single quotes:

js:call(JS, <<"function(x) {return x.split(' ')}">>, [<<"foo bar">>]).

The problem seems to be the quotes in the "function name" when used as a string in the argument to throw() in js.erl.

I haven't done any thorough testing, but doing something like:

EscapedFunctionName = binary:replace(FunctionName, <<"\"">>, <<"\\\"">>, [global])

And then:

[...] throw(\">>, EscapedfunctionName, <<" not [...]

Seems to work.