Skip to content

Commit

Permalink
Update to latest SpiderMonkey from hg (some API changes) and fix time…
Browse files Browse the repository at this point in the history
…r example
  • Loading branch information
creationix committed Mar 6, 2012
1 parent b6254e7 commit bd28419
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 77 deletions.
28 changes: 24 additions & 4 deletions README.markdown
Expand Up @@ -10,14 +10,34 @@ At the moment it's only been tested on Ubuntu.

You need to build spidermonkey on your own. Here are quick instructions.

Install spidermonkey version 185. On ubuntu this is libmozjs185-dev.
### Building SpiderMonkey

Go to the luvmonkey source tree and do the normal configure;make dance. (Requires python installed since we use gyp)
First download mozilla-central (the repo that contains spidermonkey). If you have good internet, use the mecurial client, if not, you can download a roughly 100mb tarball of the latest revision at <http://hg.mozilla.org/mozilla-central>

Once downloaded, go to the js folder and build spidermonkey as a static library

```sh
cd $HOME/mozilla-central/js/src
autoconf2.13
./configure --disable-shared-js
make -j 4 # or however many cores you have
```

### Building

Once you have SpiderMonkey, link it in the deps folder of luvmonkey.

```sh
cd $HOME/luvmonkey/deps
ln -s $HOME/mozilla-central
```

Then building luvmonkey is super easy. Simply go to the luvmonkey source tree and do the normal configure;make dance. (Requires python installed since we use gyp)

```sh
cd $HOME/luvmonkey
./configure
make -j4 # or however many cores you have
# Test it
./out/Release/luvmonkey test.js
```
./out/Debug/luvmonkey test.js
```
8 changes: 4 additions & 4 deletions common.gypi
@@ -1,20 +1,20 @@
{
'variables': {
# 'visibility%': 'hidden', # V8's visibility setting
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'target_arch%': 'amd64', # set v8's target architecture
'host_arch%': 'amd64', # set v8's host architecture
# 'want_separate_host_toolset': 0, # V8 should not build target and host
# 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
# 'component%': 'static_library', # NB. these names match with what V8 expects
# 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
},

'target_defaults': {
'default_configuration': 'Release',
'default_configuration': 'Debug',
'configurations': {
'Debug': {
# This breaks the linker since the mozjs library isn't a debug build
#'defines': [ 'DEBUG', '_DEBUG' ],
'defines': [ 'DEBUG', '_DEBUG' ],
'cflags': [ '-g', '-O0' ],
'conditions': [
['target_arch=="x64"', {
Expand Down
5 changes: 3 additions & 2 deletions luvmonkey.gyp
Expand Up @@ -50,14 +50,15 @@
'include_dirs': [
'src',
'deps/uv/src/ares',
'/usr/include/js',
'deps/mozilla-central/js/src/dist/include',
'deps/mozilla-central/js/src',
'<(SHARED_INTERMEDIATE_DIR)' # for js_scripts.h
],
'libraries': [
"-ldl",
"-lm",
"-lrt",
'-lmozjs185',
'deps/mozilla-central/js/src/libjs_static.a',
],
'sources': [
'src/luv_handle.c',
Expand Down
4 changes: 4 additions & 0 deletions src/helpers.h
Expand Up @@ -9,5 +9,9 @@
return JS_FALSE; \
}

#define LUV_REF(cx, obj) \
(luv_ref_t*)malloc(sizeof(luv_ref_t)); \
ref->cx = cx; \
ref->obj = obj;

#endif
20 changes: 10 additions & 10 deletions src/luv.c
Expand Up @@ -9,25 +9,25 @@
#define PATH_MAX (8096)
#endif

static JSBool luv_run(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_run(JSContext *cx, unsigned argc, jsval *vp) {
uv_run(uv_default_loop());
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

static JSBool luv_ref(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_ref(JSContext *cx, unsigned argc, jsval *vp) {
uv_ref(uv_default_loop());
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

static JSBool luv_unref(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_unref(JSContext *cx, unsigned argc, jsval *vp) {
uv_unref(uv_default_loop());
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

static JSBool luv_exepath(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_exepath(JSContext *cx, unsigned argc, jsval *vp) {
size_t size = 2*PATH_MAX;
char exec_path[2*PATH_MAX];
UV_CALL(uv_exepath, exec_path, &size);
Expand All @@ -36,7 +36,7 @@ static JSBool luv_exepath(JSContext *cx, uintN argc, jsval *vp) {
return JS_TRUE;
}

static JSBool luv_cwd(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_cwd(JSContext *cx, unsigned argc, jsval *vp) {
size_t size = 2*PATH_MAX;
char cwd_path[2*PATH_MAX];

Expand All @@ -50,19 +50,19 @@ static JSBool luv_cwd(JSContext *cx, uintN argc, jsval *vp) {
return JS_TRUE;
}

static JSBool luv_get_free_memory(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_get_free_memory(JSContext *cx, unsigned argc, jsval *vp) {
uint64_t size = uv_get_free_memory();
JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(size));
return JS_TRUE;
}

static JSBool luv_get_total_memory(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_get_total_memory(JSContext *cx, unsigned argc, jsval *vp) {
uint64_t size = uv_get_total_memory();
JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(size));
return JS_TRUE;
}

static JSBool luv_loadavg(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_loadavg(JSContext *cx, unsigned argc, jsval *vp) {
double avg[3];
uv_loadavg(avg);
jsval values[] = {
Expand All @@ -74,7 +74,7 @@ static JSBool luv_loadavg(JSContext *cx, uintN argc, jsval *vp) {
return JS_TRUE;
}

static JSBool luv_uptime(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_uptime(JSContext *cx, unsigned argc, jsval *vp) {
double uptime;
uv_uptime(&uptime);
JS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(uptime));
Expand All @@ -94,7 +94,7 @@ static JSFunctionSpec luv_functions[] = {
JS_FS_END
};

JSBool luv_init(JSContext *cx, uintN argc, jsval *vp) {
JSBool luv_init(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* uv = JS_NewObject(cx, NULL, NULL, NULL);
if (!JS_DefineFunctions(cx, uv, luv_functions)) {
return JS_FALSE;
Expand Down
2 changes: 1 addition & 1 deletion src/luv.h
Expand Up @@ -3,6 +3,6 @@

#include "jsapi.h"

JSBool luv_init(JSContext *cx, uintN argc, jsval *vp);
JSBool luv_init(JSContext *cx, unsigned argc, jsval *vp);

#endif
42 changes: 37 additions & 5 deletions src/luv_handle.c
Expand Up @@ -8,20 +8,32 @@ static JSClass Handle_class = {
JSCLASS_NO_OPTIONAL_MEMBERS
};

static JSBool Handle_constructor(JSContext *cx, uintN argc, jsval *vp) {
static JSBool Handle_constructor(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* obj = JS_NewObject(cx, &Handle_class, Handle_prototype, NULL);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return JS_TRUE;
}

void luv_on_close(uv_handle_t* handle) {
printf("TODO: luv_on_close\n");
luv_ref_t* ref;
ref = (luv_ref_t*)handle->data;
if (!luv_call_callback(ref->cx, ref->obj, "onClose", 0, NULL)) {
/* TODO: report properly */
printf("Error in onClose callback\n");
}
}

static JSBool luv_close(JSContext *cx, uintN argc, jsval *vp) {
/* TODO: check that this is instanceof Handle */
static JSBool luv_close(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_handle_t* handle;
handle = (uv_handle_t*)JS_GetPrivate(cx, JS_THIS_OBJECT(cx, vp));
handle = (uv_handle_t*)JS_GetPrivate(this);

JSObject* callback;
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "o", &callback)) {
return JS_FALSE;
}

if (!luv_store_callback(cx, this, "onClose", callback)) return JS_FALSE;

uv_close(handle, luv_on_close);

Expand All @@ -40,3 +52,23 @@ int luv_handle_init(JSContext* cx, JSObject *uv) {
NULL, Handle_methods, NULL, NULL);
return 0;
}

/* Store an async callback in an object and put the object in the gc root for safekeeping */
JSBool luv_store_callback(JSContext* cx, JSObject *this, const char* name, JSObject* callback) {
if (!JS_AddObjectRoot(cx, &this)) return JS_FALSE;
jsval callback_val = OBJECT_TO_JSVAL(callback);
return JS_SetProperty(cx, this, name, &callback_val);
}

/* Call a callback stored in an object and free it from the gc root */
JSBool luv_call_callback(JSContext* cx, JSObject *this, const char* name, unsigned argc, jsval* argv) {
jsval callback_val;
JSBool ret = JS_GetProperty(cx, this, name, &callback_val);

if (ret && JSVAL_IS_OBJECT(callback_val) && JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(callback_val))) {
jsval result;
ret = JS_CallFunctionValue(cx, this, callback_val, argc, argv, &result);
}
JS_RemoveObjectRoot(cx, &this);
return ret;
}
3 changes: 3 additions & 0 deletions src/luv_handle.h
Expand Up @@ -7,6 +7,9 @@ JSObject* Handle_prototype;

int luv_handle_init(JSContext* cx, JSObject *uv);

JSBool luv_store_callback(JSContext* cx, JSObject *this, const char* name, JSObject* callback);
JSBool luv_call_callback(JSContext* cx, JSObject *this, const char* name, unsigned argc, jsval* argv);

typedef struct {
JSContext* cx;
JSObject* obj;
Expand Down
4 changes: 2 additions & 2 deletions src/luv_stream.c
Expand Up @@ -8,14 +8,14 @@ static JSClass Stream_class = {
JSCLASS_NO_OPTIONAL_MEMBERS
};

static JSBool Stream_constructor(JSContext *cx, uintN argc, jsval *vp) {
static JSBool Stream_constructor(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* obj = JS_NewObject(cx, &Stream_class, Stream_prototype, NULL);
JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return JS_TRUE;
}


static JSBool luv_write(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_write(JSContext *cx, unsigned argc, jsval *vp) {
printf("TODO: Implement luv_write\n");
return JS_TRUE;
}
Expand Down
12 changes: 6 additions & 6 deletions src/luv_tcp.c
Expand Up @@ -11,23 +11,23 @@ static JSClass Tcp_class = {
};


static JSBool Tcp_constructor(JSContext *cx, uintN argc, jsval *vp) {
static JSBool Tcp_constructor(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* obj = JS_NewObject(cx, &Tcp_class, Tcp_prototype, NULL);

uv_tcp_t* handle = malloc(sizeof(uv_tcp_t));
uv_tcp_init(uv_default_loop(), handle);
JS_SetPrivate(cx, obj, handle);
JS_SetPrivate(obj, handle);

JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return JS_TRUE;
}

/* Free the uv_tcp_t* when the object gets GCed */
static void Tcp_finalize(JSContext *cx, JSObject *this) {
free(JS_GetPrivate(cx, this));
free(JS_GetPrivate(this));
}

static JSBool luv_tcp_bind(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_tcp_bind(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_tcp_t* handle;
handle = (uv_tcp_t*)JS_GetInstancePrivate(cx, this, &Tcp_class, NULL);
Expand All @@ -44,7 +44,7 @@ static JSBool luv_tcp_bind(JSContext *cx, uintN argc, jsval *vp) {
return JS_TRUE;
}

static JSBool luv_tcp_nodelay(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_tcp_nodelay(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_tcp_t* handle;
handle = (uv_tcp_t*)JS_GetInstancePrivate(cx, this, &Tcp_class, NULL);
Expand All @@ -58,7 +58,7 @@ static JSBool luv_tcp_nodelay(JSContext *cx, uintN argc, jsval *vp) {
return JS_TRUE;
}

static JSBool luv_tcp_keepalive(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_tcp_keepalive(JSContext *cx, unsigned argc, jsval *vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_tcp_t* handle;
handle = (uv_tcp_t*)JS_GetInstancePrivate(cx, this, &Tcp_class, NULL);
Expand Down

0 comments on commit bd28419

Please sign in to comment.