Sunday, February 6, 2011

Exposing C-functions to Spidermonkey

Today I implemented my very first additional function into Spidermonkey, it was just a test function which just responds with a static string but anyhow, this is hot shit! We will use it to call Erlang functions from JavaScript to implement something like webstorage. here is some code, the js_erlang() function which will be exposed to JavaScript:

JSBool js_erlang(JSContext *cx, uintN argc, jsval *vp) {
  const char *s = "text comes from C function";
  JSString *str = JS_NewStringCopyN(cx, s, sizeof(s));
  JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
  return JSVAL_TRUE;
}

And here is how you add it to all the other native functions in Spidermonkey:

JSNative *js_erlptr = (JSNative *) *js_erlang;
JS_DefineFunction(vm->context, JS_GetGlobalObject(vm->context), "callErlang", js_erlptr, 0, JSFUN_FAST_NATIVE);

Because we wanted to add this, we had to fork the erlang_js project, I hope we can write code which is general enough so it will be back ported to the original project. Here is our version.

The next step is to get the argument from the function, I suppose it'll look something like that:

jsval *argv = JS_ARGV(cx, vp);
jsval js_arg = argv[0];
char *argument = JS_GetStringBytes(JS_ValueToString(cx, js_arg));

And after that we have to call a erlang function. Jonathan found this neat erlang helper called erl_call. With its help you can call functions in a node:

me@Zepto$ echo "[2+2, node(), \"Hello world\"]." | erl_call -sname ggs -e
{ok, [4, ggs@Zepto, "Hello world"]}

And you get an answer from the erlang node in plaintext. This looks like the easiest way to talk to erlang yet. You probably saw the argument "-sname ggs" and wandered what that is. It is the name of the node you would like to talk to, here "ggs".

Time report

Today: 7 hours

No comments:

Post a Comment