Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #68 from Licenser/master

Lots of updates, concurrency and memory management
  • Loading branch information...
commit 2ded86ab223e134faba156185f558be0453251f1 2 parents 906f10c + a73b9c3
Yurii Rashkovskii yrashk authored
2  .gitmodules
View
@@ -4,4 +4,4 @@
branch = trunk
[submodule "deps/zeromq2"]
path = deps/zeromq2
- url = git://github.com/zeromq/zeromq2-2.git
+ url = git://github.com/zeromq/zeromq2-x.git
11 Makefile
View
@@ -41,9 +41,18 @@ dependencies: deps/v8/libv8.a deps/zeromq2/src/.libs/libzmq.a
test: compile
@./rebar eunit skip_deps=true
+dbg-test: compile
+ @USE_GDB=true ./rebar eunit skip_deps=true
+
compile: dependencies
@./rebar get-deps
@EXTRA_CFLAGS= ./rebar compile
debug: dependencies
- @EXTRA_CFLAGS=-DERLV8_DEBUG ./rebar compile
+ @EXTRA_CFLAGS="-g3 -O0 -DERLV8_DEBUG" ./rebar compile
+
+clean:
+ -rm c_src/*.o
+
+analyze:
+ clang --analyze -Xanalyzer "-Ideps/v8/include/" -Xanalyzer "-I/usr/local//Cellar/erlang/R15B/lib/erlang/usr/include" -Xanalyzer "-Ideps/zeromq2/include/" c_src/*.cc
601 c_src/erlv8.cc
View
@@ -8,49 +8,58 @@ struct ErlV8TickHandler {
};
static ErlV8TickHandler tick_handlers[] =
-{
- {"stop", StopTickHandler},
- {"result", ResultTickHandler},
- {"call", CallTickHandler},
- {"inst", InstantiateTickHandler},
- {"delete", DeleteTickHandler},
- {"taint", TaintTickHandler},
- {"equals", EqualsTickHandler},
- {"strict_equals", StrictEqualsTickHandler},
- {"get", GetTickHandler},
- {"get_proto", GetProtoTickHandler},
- {"get_hidden", GetHiddenTickHandler},
- {"set", SetTickHandler},
- {"set_proto", SetProtoTickHandler},
- {"set_hidden", SetHiddenTickHandler},
- {"set_accessor", SetAccessorTickHandler},
- {"proplist", ProplistTickHandler},
- {"list", ListTickHandler},
- {"script", ScriptTickHandler},
- {"gc", GCTickHandler},
- {"to_string", ToStringTickHandler},
- {"to_detail_string", ToDetailStringTickHandler},
- {"extern_proto", ExternProtoTickHandler},
- {"externalize", ExternalizeTickHandler},
- {"internal_count", InternalCountTickHandler},
- {"set_internal", SetInternalTickHandler},
- {"set_internal_extern", SetInternalTickHandler},
- {"get_internal", GetInternalTickHandler},
- {NULL, UnknownTickHandler}
-};
+ {
+ {"stop", StopTickHandler},
+ {"result", ResultTickHandler},
+ {"call", CallTickHandler},
+ {"inst", InstantiateTickHandler},
+ {"delete", DeleteTickHandler},
+ {"taint", TaintTickHandler},
+ {"equals", EqualsTickHandler},
+ {"strict_equals", StrictEqualsTickHandler},
+ {"get", GetTickHandler},
+ {"get_proto", GetProtoTickHandler},
+ {"get_hidden", GetHiddenTickHandler},
+ {"set", SetTickHandler},
+ {"set_proto", SetProtoTickHandler},
+ {"set_hidden", SetHiddenTickHandler},
+ {"set_accessor", SetAccessorTickHandler},
+ {"proplist", ProplistTickHandler},
+ {"list", ListTickHandler},
+ {"script", ScriptTickHandler},
+ {"gc", GCTickHandler},
+ {"to_string", ToStringTickHandler},
+ {"to_detail_string", ToDetailStringTickHandler},
+ {"extern_proto", ExternProtoTickHandler},
+ {"externalize", ExternalizeTickHandler},
+ {"internal_count", InternalCountTickHandler},
+ {"set_internal", SetInternalTickHandler},
+ {"set_internal_extern", SetInternalTickHandler},
+ {"get_internal", GetInternalTickHandler},
+ {NULL, UnknownTickHandler}
+ };
VM::VM() {
env = enif_alloc_env();
mutex = enif_mutex_create((char*)"erlv8_vm_mutex");
- v8::Locker locker;
+ isolate = v8::Isolate::New();
+ v8::Isolate::Scope iscope(isolate);
+ v8::Locker locker(isolate);
v8::HandleScope handle_scope;
+
+ // Moved into the VM object since we have a own isolate for each VM
+ global_template = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ external_template = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ empty_constructor = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(EmptyFun));
+ string__erlv8__ = v8::Persistent<v8::String>::New(v8::String::New("__erlv8__"));
+
context = v8::Context::New(NULL, global_template);
v8::Context::Scope context_scope(context);
tid = enif_thread_self();
context->Global()->SetHiddenValue(string__erlv8__,v8::External::New(this));
-
+
ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t));
ptr->ctx = v8::Persistent<v8::Context>::New(context);
ERL_NIF_TERM resource_term = enif_make_resource(env, ptr);
@@ -58,7 +67,8 @@ VM::VM() {
context->Global()->SetHiddenValue(v8::String::New("__erlv8__ctx__"),term_to_external(resource_term));
- external_proto_num = v8::Persistent<v8::Object>::New(external_template->NewInstance());
+ v8::Local<v8::Object> tmp = external_template->NewInstance();
+ external_proto_num = v8::Persistent<v8::Object>::New(tmp);
external_proto_atom = v8::Persistent<v8::Object>::New(external_template->NewInstance());
external_proto_bin = v8::Persistent<v8::Object>::New(external_template->NewInstance());
external_proto_ref = v8::Persistent<v8::Object>::New(external_template->NewInstance());
@@ -82,120 +92,191 @@ VM::VM() {
zmq_bind(ticker_push_socket, ticker_socket_id);
zmq_connect(pull_socket, socket_id);
zmq_connect(pull_socket, ticker_socket_id);
-
};
VM::~VM() {
- enif_mutex_destroy(mutex);
- context.Dispose();
- external_proto_num.Dispose();
- external_proto_atom.Dispose();
- external_proto_bin.Dispose();
- external_proto_ref.Dispose();
- external_proto_fun.Dispose();
- external_proto_port.Dispose();
- external_proto_pid.Dispose();
- external_proto_tuple.Dispose();
- external_proto_list.Dispose();
-
- enif_free_env(env);
-
- zmq_close(push_socket);
- zmq_close(ticker_push_socket);
- zmq_close(pull_socket);
+ // v8::Isolate::Scope iscope(isolate);
+ // v8::Locker locker(isolate);
+ // v8::HandleScope handle_scope;
+ isolate->Enter();
+
+ TRACE("(%p) VM::~VM - 1\n", isolate);
+ enif_mutex_destroy(mutex);
+ TRACE("(%p) VM::~VM - 2\n", isolate);
+ TRACE("(%p) VM::~VM - 3\n", isolate);
+ external_proto_bin.Dispose();
+ external_proto_bin.Clear();
+ TRACE("(%p) VM::~VM - 4\n", isolate);
+ external_proto_ref.Dispose();
+ external_proto_ref.Clear();
+ external_proto_fun.Dispose();
+ external_proto_fun.Clear();
+ external_proto_port.Dispose();
+ external_proto_port.Clear();
+ external_proto_pid.Dispose();
+ external_proto_pid.Dispose();
+ external_proto_tuple.Clear();
+ external_proto_list.Dispose();
+ external_proto_list.Clear();
+ TRACE("(%p) VM::~VM - 4\n", isolate);
+ global_template.Dispose();
+ global_template.Clear();
+ TRACE("(%p) VM::~VM - 5\n", isolate);
+ external_template.Dispose();
+ external_template.Clear();
+ TRACE("(%p) VM::~VM - 6\n", isolate);
+ empty_constructor.Dispose();
+ empty_constructor.Clear();
+ TRACE("(%p) VM::~VM - 7\n", isolate);
+ string__erlv8__.Dispose();
+ string__erlv8__.Clear();
+ TRACE("(%p) VM::~VM - 8\n", isolate);
+ external_proto_num.Dispose();
+ external_proto_num.Clear();
+ TRACE("(%p) VM::~VM - 9\n", isolate);
+ external_proto_atom.Dispose();
+ external_proto_atom.Clear();
+ TRACE("(%p) VM::~VM - 10\n", isolate);
+ enif_free_env(env);
+ TRACE("(%p) VM::~VM - 11\n", isolate);
+ context.Dispose();
+ context.Clear();
+ while (v8::Isolate::GetCurrent() == isolate) {
+ isolate->Exit();
+ }
+ // this should dispoe everything created in the isolate:
+ // http://markmail.org/message/mcn27ibuijhgkehl
+ isolate->Dispose();
+
+ zmq_close(push_socket);
+ zmq_close(ticker_push_socket);
+ zmq_close(pull_socket);
};
void VM::run() {
- v8::Locker locker;
+ v8::Isolate::Scope iscope(isolate);
+ v8::Locker locker(isolate);
v8::HandleScope handle_scope; // the very top level handle scope
ticker(0);
};
+void VM::terminate() {
+ TRACE("(%p) VM::terminate - 1\n", isolate);
+ v8::V8::TerminateExecution(isolate);
+}
+
v8::Handle<v8::Value> VM::ticker(ERL_NIF_TERM ref0) {
- LHCS(context);
+ TRACE("(%p) VM::ticker - 0\n", isolate);
+ LHCS(isolate, context);
+ isolate->Enter();
+ TRACE("(%p) VM::ticker - 1\n", isolate);
char name[MAX_ATOM_LEN];
unsigned len;
-
+
ErlNifEnv * ref_env = enif_alloc_env();
ERL_NIF_TERM ref;
-
+ TRACE("(%p) VM::ticker - 2\n", isolate);
if ((unsigned long) ref0 == 0) {
- ref = ref0;
- DEBUG(server, enif_make_atom(env, "current_ticker"), enif_make_atom(env, "top"));
+ ref = ref0;
+ DEBUG(server, enif_make_atom(env, "current_ticker"), enif_make_atom(env, "top"));
} else {
- ref = enif_make_copy(ref_env, ref0);
- DEBUG(server, enif_make_atom(env, "current_ticker"), enif_make_copy(env, ref));
+ ref = enif_make_copy(ref_env, ref0);
+ DEBUG(server, enif_make_atom(env, "current_ticker"), enif_make_copy(env, ref));
}
-
-
+ TRACE("(%p) VM::ticker - 3\n", isolate);
+
zmq_msg_t msg;
Tick tick_s;
ERL_NIF_TERM tick, tick_ref;
while (1) {
- {
- v8::Unlocker unlocker;
- zmq_msg_init (&msg);
- zmq_recv (pull_socket, &msg, 0);
- memcpy(&tick_s, zmq_msg_data(&msg), sizeof(Tick));
- tick = enif_make_copy(env, tick_s.tick);
- tick_ref = enif_make_copy(env, tick_s.ref);
- enif_free_env(tick_s.env);
- zmq_msg_close(&msg);
- }
-
- DEBUG(server, enif_make_tuple2(env, enif_make_atom(env, "last_tick"), (unsigned long) ref == 0 ? enif_make_atom(env,"top") :
- enif_make_copy(env, ref)), enif_make_copy(env, tick));
-
- if (enif_is_tuple(env, tick)) { // should be always true, just a sanity check
-
- ERL_NIF_TERM *array;
- int arity;
- enif_get_tuple(env,tick,&arity,(const ERL_NIF_TERM **)&array);
-
- enif_get_atom_length(env, array[0], &len, ERL_NIF_LATIN1);
- enif_get_atom(env,array[0],(char *)&name,len + 1, ERL_NIF_LATIN1);
-
- // lookup the matrix
- unsigned int i = 0;
- bool stop_flag = false;
-
- while (!stop_flag) {
- if ((!tick_handlers[i].name) ||
- (!strcmp(name,tick_handlers[i].name))) { // handler has been located
+ {
+ isolate->Exit();
+ TRACE("(%p) VM::ticker - 3.1\n", isolate);
+ v8::Unlocker unlocker(isolate);
+ TRACE("(%p) VM::ticker - 3.2\n", isolate);
+ zmq_msg_init (&msg);
+ TRACE("(%p) VM::ticker - 3.3\n", isolate);
+ zmq_recv (pull_socket, &msg, 0);
+ TRACE("(%p) VM::ticker - 3.4\n", isolate);
+ memcpy(&tick_s, zmq_msg_data(&msg), sizeof(Tick));
+ TRACE("(%p) VM::ticker - 3.5\n", isolate);
+ tick = enif_make_copy(env, tick_s.tick);
+ TRACE("(%p) VM::ticker - 3.6\n", isolate);
+ tick_ref = enif_make_copy(env, tick_s.ref);
+ TRACE("(%p) VM::ticker - 3.7\n", isolate);
+ enif_free_env(tick_s.env);
+ TRACE("(%p) VM::ticker - 3.8\n", isolate);
+ zmq_msg_close(&msg);
+ TRACE("(%p) VM::ticker - 3.9\n", isolate);
+ }
+ isolate->Enter();
+ TRACE("(%p) VM::ticker - 4\n", isolate);
+ DEBUG(server,
+ enif_make_tuple2(env,
+ enif_make_atom(env, "last_tick"),
+ (unsigned long) ref == 0 ? enif_make_atom(env,"top") : enif_make_copy(env, ref)),
+ enif_make_copy(env, tick));
+
+ if (enif_is_tuple(env, tick)) { // should be always true, just a sanity check
+ TRACE("(%p) VM::ticker - 5\n", isolate);
+ ERL_NIF_TERM *array;
+ int arity;
+ enif_get_tuple(env,tick,&arity,(const ERL_NIF_TERM **)&array);
+
+ enif_get_atom_length(env, array[0], &len, ERL_NIF_LATIN1);
+ enif_get_atom(env,array[0],(char *)&name,len + 1, ERL_NIF_LATIN1);
+
+ // lookup the matrix
+ unsigned int i = 0;
+ bool stop_flag = false;
+ TRACE("(%p) VM::ticker - 6 (%s)\n", isolate, name);
+ while (!stop_flag) {
+ if ((!tick_handlers[i].name) ||
+ (!strcmp(name,tick_handlers[i].name))) { // handler has been located
+ TRACE("(%p) VM::ticker - 7\n", isolate);
TickHandlerResolution resolution = (tick_handlers[i].handler(this, name, tick, tick_ref, ref, arity, array));
-
- switch (resolution.type) {
- case DONE:
- stop_flag = true;
- break;
- case NEXT:
- break;
- case RETURN:
- enif_free_env(ref_env);
- enif_clear_env(env);
- zmq_msg_t tick_msg;
- int e;
-
- while (!pop_ticks.empty()) {
- Tick newtick = pop_ticks.front();
- pop_ticks.pop();
- zmq_msg_init_size(&tick_msg, sizeof(Tick));
+ TRACE("(%p) VM::ticker - 8\n", isolate);
+
+ switch (resolution.type) {
+ case DONE:
+ stop_flag = true;
+ break;
+ case NEXT:
+ break;
+ case RETURN:
+ TRACE("(%p) VM::ticker - 9\n", isolate);
+ enif_free_env(ref_env);
+ TRACE("(%p) VM::ticker - 10\n", isolate);
+ enif_clear_env(env);
+ TRACE("(%p) VM::ticker - 11\n", isolate);
+ zmq_msg_t tick_msg;
+ int e;
+ TRACE("(%p) VM::ticker - 12\n", isolate);
+ while (!pop_ticks.empty()) {
+ TRACE("(%p) VM::ticker - 12.1\n", isolate);
+ Tick newtick = pop_ticks.front();
+ TRACE("(%p) VM::ticker - 12.2\n", isolate);
+ pop_ticks.pop();
+ TRACE("(%p) VM::ticker - 12.3\n", isolate);
+ zmq_msg_init_size(&tick_msg, sizeof(Tick));
+ TRACE("(%p) VM::ticker - 12.4\n", isolate);
memcpy(zmq_msg_data(&tick_msg), &newtick, sizeof(Tick));
-
- do {
- e = zmq_send(ticker_push_socket, &tick_msg, ZMQ_NOBLOCK);
- } while (e == EAGAIN);
-
- zmq_msg_close(&tick_msg);
- }
- return handle_scope.Close(resolution.value);
- break;
- }
- }
- i++;
+ TRACE("(%p) VM::ticker - 12.5\n", isolate);
+ do {
+ e = zmq_send(ticker_push_socket, &tick_msg, ZMQ_NOBLOCK);
+ TRACE("(%p) VM::ticker - 12.6\n", isolate);
+ } while (e == EAGAIN);
+ zmq_msg_close(&tick_msg);
+ }
+ TRACE("(%p) VM::ticker - 13\n", isolate);
+ return handle_scope.Close(resolution.value);
+ break;
}
}
- enif_clear_env(env);
+ i++;
+ }
+ }
+ enif_clear_env(env);
}
};
@@ -213,17 +294,17 @@ void * start_vm(void *data) {
static ERL_NIF_TERM new_vm(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
ERL_NIF_TERM term;
-
VM *vm = new VM();
-
+
vm_res_t *ptr = (vm_res_t *)enif_alloc_resource(vm_resource, sizeof(vm_res_t));
+
ptr->vm = vm;
vm->resource = ptr;
term = enif_make_resource(env, ptr);
-
+
enif_release_resource(ptr);
-
+
return term;
};
@@ -231,10 +312,10 @@ static ERL_NIF_TERM set_server(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv
{
vm_res_t *res;
if (enif_get_resource(env,argv[0],vm_resource,(void **)(&res))) {
- res->vm->server = (ErlNifPid *) malloc(sizeof(ErlNifPid));
- enif_get_local_pid(env, argv[1], res->vm->server);
- enif_thread_create((char *)"erlv8", &res->vm->tid, start_vm, res->vm, NULL);
- return enif_make_atom(env,"ok");
+ res->vm->server = (ErlNifPid *) malloc(sizeof(ErlNifPid));
+ enif_get_local_pid(env, argv[1], res->vm->server);
+ enif_thread_create((char *)"erlv8", &res->vm->tid, start_vm, res->vm, NULL);
+ return enif_make_atom(env,"ok");
};
return enif_make_badarg(env);
};
@@ -243,50 +324,65 @@ static ERL_NIF_TERM context(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
vm_res_t *res;
if (enif_get_resource(env,argv[0],vm_resource,(void **)(&res))) {
- LHCS(res->vm->context);
-
- ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t));
- ptr->ctx = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
-
- ERL_NIF_TERM term = enif_make_resource(env, ptr);
-
- enif_release_resource(ptr);
-
- return term;
+ LHCS(res->vm->isolate, res->vm->context);
+ ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t));
+ ptr->ctx = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
+
+ ERL_NIF_TERM term = enif_make_resource(env, ptr);
+
+ enif_release_resource(ptr);
+
+ return term;
};
return enif_make_badarg(env);
};
+
+
+static ERL_NIF_TERM kill(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
+ vm_res_t *res;
+ TRACE("kill - 1\n");
+ if (enif_get_resource(env,argv[0],vm_resource,(void **)(&res))) {
+ TRACE("kill - 2\n");
+ res->vm->terminate();
+ TRACE("kill - 3\n");
+ return enif_make_atom(env,"ok");
+ } else {
+ TRACE("kill - 3\n");
+ return enif_make_badarg(env);
+ }
+}
+
static ERL_NIF_TERM stop(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
vm_res_t *res;
int e;
if (enif_get_resource(env,argv[0],vm_resource,(void **)(&res))) {
- if ((!enif_is_ref(env, argv[1])))
- return enif_make_badarg(env);
-
- zmq_msg_t tick_msg;
-
- Tick tick;
- tick.env = enif_alloc_env();
- tick.tick = enif_make_tuple1(tick.env, enif_make_atom(tick.env, "stop"));
- tick.ref = enif_make_copy(tick.env, argv[1]);
-
-
+ if ((!enif_is_ref(env, argv[1])))
+ return enif_make_badarg(env);
+ TRACE("(%p) stop\n", res->vm->isolate);
+ zmq_msg_t tick_msg;
+
+ Tick tick;
+ tick.env = enif_alloc_env();
+ tick.tick = enif_make_tuple1(tick.env, enif_make_atom(tick.env, "stop"));
+ tick.ref = enif_make_copy(tick.env, argv[1]);
+
+
zmq_msg_init_size(&tick_msg, sizeof(Tick));
-
+
memcpy(zmq_msg_data(&tick_msg), &tick, sizeof(Tick));
-
+
enif_mutex_lock(res->vm->mutex);
- do {
- e = zmq_send(res->vm->push_socket, &tick_msg, ZMQ_NOBLOCK);
- } while (e == EAGAIN);
-
- zmq_msg_close(&tick_msg);
+ do {
+ e = zmq_send(res->vm->push_socket, &tick_msg, ZMQ_NOBLOCK);
+ } while (e == EAGAIN);
+
+ zmq_msg_close(&tick_msg);
enif_mutex_unlock(res->vm->mutex);
-
- return enif_make_atom(env,"ok");
+
+ return enif_make_atom(env,"ok");
} else {
- return enif_make_badarg(env);
+ return enif_make_badarg(env);
};
};
@@ -294,76 +390,80 @@ static ERL_NIF_TERM tick(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
vm_res_t *res;
int e;
if (enif_get_resource(env,argv[0],vm_resource,(void **)(&res))) {
- if ((!enif_is_ref(env, argv[1])))
- return enif_make_badarg(env);
-
- zmq_msg_t tick_msg;
-
- Tick tick;
- tick.env = enif_alloc_env();
- tick.tick = enif_make_copy(tick.env, argv[2]);
- tick.ref = enif_make_copy(tick.env, argv[1]);
-
-
+ if ((!enif_is_ref(env, argv[1])))
+ return enif_make_badarg(env);
+
+ zmq_msg_t tick_msg;
+
+ Tick tick;
+ tick.env = enif_alloc_env();
+ tick.tick = enif_make_copy(tick.env, argv[2]);
+ tick.ref = enif_make_copy(tick.env, argv[1]);
+
+
zmq_msg_init_size(&tick_msg, sizeof(Tick));
-
+
memcpy(zmq_msg_data(&tick_msg), &tick, sizeof(Tick));
-
- do {
- e = zmq_send(res->vm->push_socket, &tick_msg, ZMQ_NOBLOCK);
- } while (e == EAGAIN);
-
- zmq_msg_close(&tick_msg);
-
- return enif_make_atom(env,"tack");
+
+ do {
+ e = zmq_send(res->vm->push_socket, &tick_msg, ZMQ_NOBLOCK);
+ } while (e == EAGAIN);
+
+ zmq_msg_close(&tick_msg);
+
+ return enif_make_atom(env,"tack");
} else {
- return enif_make_badarg(env);
+ return enif_make_badarg(env);
};
};
static ERL_NIF_TERM global(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ctx_res_t *res;
- if (enif_get_resource(env,argv[0],ctx_resource,(void **)(&res))) {
- LHCS(res->ctx);
- v8::Handle<v8::Object> global = res->ctx->Global();
- return js_to_term(res->ctx,env,global);
+ vm_res_t *vm_res;
+
+ if (
+ enif_get_resource(env, argv[0], vm_resource, (void **)(&vm_res))
+ && enif_get_resource(env,argv[1],ctx_resource,(void **)(&res))) {
+ LHCS(vm_res->vm->isolate, res->ctx);
+ v8::Handle<v8::Object> global = res->ctx->Global();
+ return js_to_term(res->ctx, vm_res->vm->isolate, env,global);
} else {
- return enif_make_badarg(env);
+ return enif_make_badarg(env);
};
};
static ERL_NIF_TERM new_context(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
vm_res_t *res;
- if (enif_get_resource(env,argv[0],vm_resource,(void **)(&res))) {
- LHCS(res->vm->context);
- v8::Persistent<v8::Context> context = v8::Context::New(NULL, global_template);
- context->Global()->SetHiddenValue(string__erlv8__,v8::External::New(res->vm));
-
- ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t));
- ptr->ctx = v8::Persistent<v8::Context>::New(context);
-
- ERL_NIF_TERM resource_term = enif_make_resource(env, ptr);
-
- enif_release_resource(ptr);
-
- context->Global()->SetHiddenValue(v8::String::New("__erlv8__ctx__"),term_to_external(resource_term));
-
- return resource_term;
+ if (enif_get_resource(env, argv[0], vm_resource, (void **)(&res))) {
+ LHCS(res->vm->isolate, res->vm->context);
+ v8::Persistent<v8::Context> context = v8::Context::New(NULL, res->vm->global_template);
+ context->Global()->SetHiddenValue(res->vm->string__erlv8__, v8::External::New(res->vm));
+
+ ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t));
+ ptr->ctx = v8::Persistent<v8::Context>::New(context);
+ ERL_NIF_TERM resource_term = enif_make_resource(env, ptr);
+
+ enif_release_resource(ptr);
+
+ context->Global()->SetHiddenValue(v8::String::New("__erlv8__ctx__"), term_to_external(resource_term));
+
+ return resource_term;
} else {
- return enif_make_badarg(env);
+ return enif_make_badarg(env);
};
};
static ErlNifFunc nif_funcs[] =
-{
- {"new_vm", 0, new_vm},
- {"set_server", 2, set_server},
- {"context", 1, context},
- {"new_context", 1, new_context},
- {"global",1, global},
- {"tick",3, tick},
- {"stop",2, stop},
-};
+ {
+ {"kill", 1, kill},
+ {"new_vm", 0, new_vm},
+ {"set_server", 2, set_server},
+ {"context", 1, context},
+ {"new_context", 1, new_context},
+ {"global", 2, global},
+ {"tick", 3, tick},
+ {"stop", 2, stop},
+ };
v8::Handle<v8::Value> EmptyFun(const v8::Arguments &arguments) {
v8::HandleScope handle_scope;
@@ -372,33 +472,30 @@ v8::Handle<v8::Value> EmptyFun(const v8::Arguments &arguments) {
v8::Handle<v8::Value> WrapFun(const v8::Arguments &arguments) {
v8::HandleScope handle_scope;
- v8::Locker locker;
VM * vm = (VM *)__ERLV8__(v8::Context::GetCurrent()->Global());
-
- // each call gets a unique ref
- ERL_NIF_TERM ref = enif_make_ref(vm->env);
- // prepare arguments
- ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * arguments.Length());
- for (int i=0;i<arguments.Length();i++) {
- arr[i] = js_to_term(vm->context,vm->env,arguments[i]);
- }
- ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,arguments.Length());
- free(arr);
- // send invocation request
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_copy(env,external_to_term(arguments.Data())),
- enif_make_tuple7(env,
- enif_make_atom(env,"erlv8_fun_invocation"),
- enif_make_atom(env,arguments.IsConstructCall() ? "true" : "false"),
- js_to_term(vm->context, env, arguments.Holder()),
- js_to_term(vm->context, env, arguments.This()),
- enif_make_copy(env, ref),
- enif_make_pid(env, vm->server),
- enif_make_copy(env, external_to_term(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__ctx__"))))
- ),
- enif_make_copy(env,arglist)));
- return handle_scope.Close(vm->ticker(ref));
+ // each call gets a unique ref
+ ERL_NIF_TERM ref = enif_make_ref(vm->env);
+ // prepare arguments
+ ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * arguments.Length());
+ for (int i=0;i<arguments.Length();i++) {
+ arr[i] = js_to_term(vm->context, vm->isolate, vm->env,arguments[i]);
+ }
+ ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,arguments.Length());
+ free(arr);
+ // send invocation request
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_copy(env,external_to_term(arguments.Data())),
+ enif_make_tuple7(env,
+ enif_make_atom(env,"erlv8_fun_invocation"),
+ enif_make_atom(env,arguments.IsConstructCall() ? "true" : "false"),
+ js_to_term(vm->context, vm->isolate, env, arguments.Holder()),
+ js_to_term(vm->context, vm->isolate, env, arguments.This()),
+ enif_make_copy(env, ref),
+ enif_make_pid(env, vm->server),
+ enif_make_copy(env, external_to_term(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__ctx__"))))),
+ enif_make_copy(env,arglist)));
+ return handle_scope.Close(vm->ticker(ref));
};
@@ -406,24 +503,17 @@ static void vm_resource_destroy(ErlNifEnv* env, void* obj) {
};
static void val_resource_destroy(ErlNifEnv* env, void* obj) {
- v8::Locker locker;
- val_res_t * res = reinterpret_cast<val_res_t *>(obj);
- res->ctx.Dispose();
- res->val.Dispose();
};
static void ctx_resource_destroy(ErlNifEnv* env, void* obj) {
- v8::Locker locker;
- ctx_res_t * res = reinterpret_cast<ctx_res_t *>(obj);
- res->ctx.Dispose();
};
int load(ErlNifEnv *env, void** priv_data, ERL_NIF_TERM load_info)
{
-
+ TRACE("load\n");
zmq_context = zmq_init(0); // we are using inproc only, so no I/O threads
-
+
vm_resource = enif_open_resource_type(env, NULL, "erlv8_vm_resource", vm_resource_destroy, (ErlNifResourceFlags) (ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL);
val_resource = enif_open_resource_type(env, NULL, "erlv8_val_resource", val_resource_destroy, (ErlNifResourceFlags) (ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL);
ctx_resource = enif_open_resource_type(env, NULL, "erlv8_ctx_resource", ctx_resource_destroy, (ErlNifResourceFlags) (ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL);
@@ -436,25 +526,14 @@ int load(ErlNifEnv *env, void** priv_data, ERL_NIF_TERM load_info)
v8::HandleScope handle_scope;
- global_template = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
-
- external_template = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
-
- empty_constructor = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(EmptyFun));
-
- string__erlv8__ = v8::Persistent<v8::String>::New(v8::String::New("__erlv8__"));
-
return 0;
};
void unload(ErlNifEnv *env, void* priv_data)
{
+ TRACE("unload\n");
v8::Locker::StopPreemption();
- global_template.Dispose();
- external_template.Dispose();
- empty_constructor.Dispose();
- string__erlv8__.Dispose();
zmq_term(zmq_context);
};
@@ -466,12 +545,6 @@ int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM
return 0;
}
-
-v8::Persistent<v8::ObjectTemplate> global_template;
-v8::Persistent<v8::ObjectTemplate> external_template;
-v8::Persistent<v8::FunctionTemplate> empty_constructor;
-v8::Persistent<v8::String> string__erlv8__;
-
ErlNifResourceType * ctx_resource;
ErlNifResourceType * vm_resource;
ErlNifResourceType * val_resource;
87 c_src/erlv8.hh
View
@@ -12,6 +12,19 @@
#include <zmq.h>
+
+// Debugging
+
+#ifdef ERLV8_DEBUG
+#define DEBUG(pid,name,code) SEND(pid, enif_make_tuple3(env, enif_make_atom(env,"DEBUG"), name, code))
+#define TRACE printf
+#else
+#define DEBUG(pid,name,code)
+#define TRACE(...)
+#endif
+
+// Debugging end
+
using namespace std;
using namespace __gnu_cxx;
@@ -37,18 +50,24 @@ typedef struct _ctx_res_t {
v8::Persistent<v8::Context> ctx;
} ctx_res_t;
-
// Helpers
-#define LHCS(ctx) v8::Locker locker; \
- v8::HandleScope handle_scope; \
- v8::Context::Scope context_scope(ctx)
-
-#define SEND(pid, code) \
- { \
- Send send = Send(pid); \
- ErlNifEnv * env = send.env; \
- send.send(code); \
- }
+#define LHCS(iso, ctx) \
+ TRACE("(%p) LHCS - 1\n", iso); \
+ v8::Locker locker(iso); \
+ TRACE("(%p) LHCS - 2\n", iso); \
+ v8::Isolate::Scope iscope(iso); \
+ TRACE("(%p) LHCS - 3\n", iso); \
+ v8::HandleScope handle_scope; \
+ TRACE("(%p) LHCS - 4\n", iso); \
+ v8::Context::Scope context_scope(ctx); \
+ TRACE("(%p) LHCS - 1\n", iso)
+
+#define SEND(pid, code)\
+ {\
+ Send send = Send(pid);\
+ ErlNifEnv * env = send.env;\
+ send.send(code);\
+ }
//
struct cmp_erl_nif_term
@@ -61,10 +80,6 @@ struct cmp_erl_nif_term
// Statics
-extern v8::Persistent<v8::ObjectTemplate> global_template;
-extern v8::Persistent<v8::ObjectTemplate> external_template;
-extern v8::Persistent<v8::FunctionTemplate> empty_constructor;
-extern v8::Persistent<v8::String> string__erlv8__;
extern ErlNifResourceType * vm_resource;
extern ErlNifResourceType * val_resource;
@@ -83,8 +98,13 @@ struct Tick {
// VM
class VM {
public:
- v8::Persistent<v8::Context> context;
+ v8::Persistent<v8::ObjectTemplate> global_template;
+ v8::Persistent<v8::ObjectTemplate> external_template;
+ v8::Persistent<v8::FunctionTemplate> empty_constructor;
+ v8::Persistent<v8::String> string__erlv8__;
+
+ v8::Persistent<v8::Context> context;
v8::Persistent<v8::Object> external_proto_num;
v8::Persistent<v8::Object> external_proto_atom;
v8::Persistent<v8::Object> external_proto_bin;
@@ -115,8 +135,10 @@ public:
VM();
~VM();
void run();
+ void terminate();
v8::Handle<v8::Value> ticker(ERL_NIF_TERM ref);
+ v8::Isolate* isolate;
};
enum TickHandlerResolutionType { DONE, RETURN, NEXT };
@@ -147,6 +169,7 @@ TickHandler(ProplistTickHandler);
TickHandler(ListTickHandler);
TickHandler(ScriptTickHandler);
TickHandler(GCTickHandler);
+TickHandler(TerminateTickHandler);
TickHandler(ToStringTickHandler);
TickHandler(ToDetailStringTickHandler);
TickHandler(ExternProtoTickHandler);
@@ -160,27 +183,26 @@ class Send {
public:
ErlNifPid * pid;
ErlNifEnv * env;
-
+
Send(ErlNifPid *a_pid) : pid(a_pid) {
- env = enif_alloc_env();
-
+ env = enif_alloc_env();
};
~Send() {
- enif_free_env(env);
+ enif_free_env(env);
};
-
+
void send(ERL_NIF_TERM term) {
- enif_send(NULL, pid, env, term);
- enif_clear_env(env);
+ enif_send(NULL, pid, env, term);
+ enif_clear_env(env);
};
-
+
};
-#define __ERLV8__(O) v8::Local<v8::External>::Cast(O->GetHiddenValue(string__erlv8__))->Value()
+#define __ERLV8__(O) v8::Local<v8::External>::Cast(O->GetHiddenValue(v8::String::New("__erlv8__")))->Value()
-v8::Handle<v8::Value> term_to_js(v8::Handle<v8::Context> ctx, ErlNifEnv *env, ERL_NIF_TERM term);
-ERL_NIF_TERM js_to_term(v8::Handle<v8::Context> ctx, ErlNifEnv *env, v8::Handle<v8::Value> val);
+v8::Handle<v8::Value> term_to_js(v8::Handle<v8::Context> ctx, v8::Isolate* isolate, ErlNifEnv *env, ERL_NIF_TERM term);
+ERL_NIF_TERM js_to_term(v8::Handle<v8::Context> ctx, v8::Isolate* isolate, ErlNifEnv *env, v8::Handle<v8::Value> val);
ERL_NIF_TERM external_to_term(v8::Handle<v8::Value> val);
v8::Handle<v8::Value> term_to_external(ERL_NIF_TERM term);
v8::PropertyAttribute term_to_property_attribute(ErlNifEnv * env, ERL_NIF_TERM term);
@@ -189,18 +211,11 @@ v8::PropertyAttribute term_to_property_attribute(ErlNifEnv * env, ERL_NIF_TERM t
v8::Handle<v8::Value> term_to_external(ERL_NIF_TERM term);
ERL_NIF_TERM external_to_term(v8::Handle<v8::Value> val);
v8::Handle<v8::Object> externalize_term(map<ERL_NIF_TERM, v8::Handle<v8::Object>, cmp_erl_nif_term> cache, v8::Handle<v8::Object> proto, ERL_NIF_TERM term);
-v8::Handle<v8::Value> term_to_js(ErlNifEnv *env, ERL_NIF_TERM term);
-ERL_NIF_TERM js_to_term(ErlNifEnv *env, v8::Handle<v8::Value> val);
+v8::Handle<v8::Value> term_to_js(ErlNifEnv *env, v8::Isolate* isolat, ERL_NIF_TERM term);
+ERL_NIF_TERM js_to_term(ErlNifEnv *env, v8::Isolate* isolat, v8::Handle<v8::Value> val);
v8::Handle<v8::Value> WrapFun(const v8::Arguments &arguments);
v8::Handle<v8::Value> EmptyFun(const v8::Arguments &arguments);
v8::Handle<v8::Object> extern_name_to_proto(VM * vm, char *name);
-// Debugging
-
-#ifdef ERLV8_DEBUG
-#define DEBUG(pid,name,code) SEND(pid, enif_make_tuple3(env, enif_make_atom(env,"DEBUG"), name, code))
-#else
-#define DEBUG(pid,name,code)
-#endif
67 c_src/erlv8_call.cc
View
@@ -17,36 +17,42 @@ TickHandler(CallTickHandler) {
args = new v8::Local<v8::Value>[alen];
int i = 0;
while (enif_get_list_cell(vm->env, current, &head, &tail)) {
- args[i] = v8::Local<v8::Value>::New(term_to_js(fun_res->ctx,vm->env,head));
+ args[i] = v8::Local<v8::Value>::New(term_to_js(fun_res->ctx, vm->isolate, vm->env,head));
i++; current = tail;
}
v8::Local<v8::Object> recv;
if (arity == 4) { // this is specified
- recv = term_to_js(fun_res->ctx,vm->env, array[3])->ToObject();
+ recv = term_to_js(fun_res->ctx, vm->isolate, vm->env, array[3])->ToObject();
} else {
recv = fun_res->ctx->Global();
}
v8::Persistent<v8::Function> f = v8::Persistent<v8::Function>::Cast(fun_res->val);
- if (!*f->GetHiddenValue(string__erlv8__)) { // js function
+ if (!*f->GetHiddenValue(vm->string__erlv8__)) { // js function
v8::TryCatch try_catch;
v8::Local<v8::Value> call_result = f->Call(recv, alen, args);
if (call_result.IsEmpty()) {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,call_ref),
- enif_make_tuple2(env,
- enif_make_atom(env,"throw"),
- enif_make_tuple2(env,
- enif_make_atom(env,"error"),
- js_to_term(fun_res->ctx,env,try_catch.Exception())))));
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,call_ref),
+ enif_make_tuple2(env,
+ enif_make_atom(env,"throw"),
+ enif_make_tuple2(env,
+ enif_make_atom(env,"error"),
+ js_to_term(fun_res->ctx,
+ vm->isolate,
+ env,
+ try_catch.Exception())))));
} else {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,call_ref),
- js_to_term(fun_res->ctx,env,call_result)));
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,call_ref),
+ js_to_term(fun_res->ctx,
+ vm->isolate,
+ env,
+ call_result)));
}
} else { // native Erlang function
v8::Local<v8::Array> array = v8::Array::New(alen);
@@ -55,7 +61,7 @@ TickHandler(CallTickHandler) {
array->Set(i,args[i]);
}
- ErlangFun(vm, external_to_term(f->GetHiddenValue((string__erlv8__))), call_ref, recv, array);
+ ErlangFun(vm, external_to_term(f->GetHiddenValue((vm->string__erlv8__))), call_ref, recv, array);
}
delete [] args;
@@ -73,22 +79,25 @@ void ErlangFun(VM * vm, ERL_NIF_TERM term, ERL_NIF_TERM ref, v8::Handle<v8::Obje
// prepare arguments
ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * array->Length());
for (unsigned int i=0;i<array->Length();i++) {
- arr[i] = js_to_term(vm->context,vm->env,array->Get(v8::Integer::NewFromUnsigned(i)));
+ arr[i] = js_to_term(vm->context,
+ vm->isolate,
+ vm->env,
+ array->Get(v8::Integer::NewFromUnsigned(i)));
}
ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,array->Length());
free(arr);
// send invocation request
SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_copy(env,term),
- enif_make_tuple7(env,
- enif_make_atom(env,"erlv8_fun_invocation"),
- enif_make_atom(env, "false"),
- js_to_term(vm->context, env, recv), // FIXME: not quite sure it's right
- js_to_term(vm->context, env, recv),
- enif_make_copy(env, ref),
- enif_make_pid(env, vm->server),
- enif_make_copy(env, external_to_term(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__ctx__"))))
+ enif_make_tuple3(env,
+ enif_make_copy(env,term),
+ enif_make_tuple7(env,
+ enif_make_atom(env,"erlv8_fun_invocation"),
+ enif_make_atom(env, "false"),
+ js_to_term(vm->context, vm->isolate, env, recv), // FIXME: not quite sure it's right
+ js_to_term(vm->context, vm->isolate, env, recv),
+ enif_make_copy(env, ref),
+ enif_make_pid(env, vm->server),
+ enif_make_copy(env, external_to_term(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__ctx__"))))
),
enif_make_copy(env,arglist)));
};
26 c_src/erlv8_delete.cc
View
@@ -3,19 +3,19 @@
TickHandler(DeleteTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
- v8::Handle<v8::Value> key = term_to_js(obj_res->ctx,vm->env,array[2]);
- if (key->IsString()) {
- obj_res->val->ToObject()->Delete(key->ToString());
- } else if (key->IsNumber()) {
- obj_res->val->ToObject()->Delete(key->Uint32Value());
- }
-
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- enif_make_atom(env, "ok")));
+ LHCS(vm->isolate, obj_res->ctx);
+ v8::Handle<v8::Value> key = term_to_js(obj_res->ctx,vm->isolate,vm->env,array[2]);
+ if (key->IsString()) {
+ obj_res->val->ToObject()->Delete(key->ToString());
+ } else if (key->IsNumber()) {
+ obj_res->val->ToObject()->Delete(key->Uint32Value());
+ }
+
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ enif_make_atom(env, "ok")));
}
TickHandlerResolution result;
result.type = DONE;
12 c_src/erlv8_equals.cc
View
@@ -9,11 +9,11 @@ TickHandler(EqualsTickHandler) {
if ((enif_get_resource(vm->env,array[1],val_resource,(void **)(&res1))) &&
(enif_get_resource(vm->env,array[2],val_resource,(void **)(&res2)))) {
- LHCS(res1->ctx);
+ LHCS(vm->isolate, res1->ctx);
bres = res1->val->ToObject()->Equals(res2->val->ToObject());
} else {
- LHCS(vm->context);
- bres = term_to_js(vm->context,vm->env,array[1])->Equals(term_to_js(vm->context,vm->env,array[2]));
+ LHCS(vm->isolate, vm->context);
+ bres = term_to_js(vm->context, vm->isolate, vm->env,array[1])->Equals(term_to_js(vm->context, vm->isolate, vm->env,array[2]));
};
SEND(vm->server,
@@ -37,11 +37,11 @@ TickHandler(StrictEqualsTickHandler) {
if ((enif_get_resource(vm->env,array[1],val_resource,(void **)(&res1))) &&
(enif_get_resource(vm->env,array[2],val_resource,(void **)(&res2)))) {
- LHCS(res1->ctx);
+ LHCS(vm->isolate, res1->ctx);
bres = res1->val->ToObject()->StrictEquals(res2->val->ToObject());
} else {
- LHCS(vm->context);
- bres = term_to_js(vm->context,vm->env,array[1])->StrictEquals(term_to_js(vm->context,vm->env,array[2]));
+ LHCS(vm->isolate, vm->context);
+ bres = term_to_js(vm->context, vm->isolate, vm->env,array[1])->StrictEquals(term_to_js(vm->context, vm->isolate, vm->env,array[2]));
};
SEND(vm->server,
6 c_src/erlv8_extern.cc
View
@@ -41,9 +41,9 @@ TickHandler(ExternProtoTickHandler) {
SEND(vm->server,
enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,extern_proto_ref),
- js_to_term(vm->context,env,proto)));
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,extern_proto_ref),
+ js_to_term(vm->context, vm->isolate, env, proto)));
enif_free_env(ref_env);
TickHandlerResolution result;
108 c_src/erlv8_get.cc
View
@@ -3,14 +3,14 @@
TickHandler(GetTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
- v8::Local<v8::Value> get_result = obj_res->val->ToObject()->Get(term_to_js(obj_res->ctx,vm->env,array[2]));
-
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- js_to_term(obj_res->ctx,env,get_result)));
+ LHCS(vm->isolate, obj_res->ctx);
+ v8::Local<v8::Value> get_result = obj_res->val->ToObject()->Get(term_to_js(obj_res->ctx,vm->isolate, vm->env,array[2]));
+
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ js_to_term(obj_res->ctx, vm->isolate, env,get_result)));
}
TickHandlerResolution result;
result.type = DONE;
@@ -20,14 +20,14 @@ TickHandler(GetTickHandler) {
TickHandler(GetProtoTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
- v8::Local<v8::Value> get_result = obj_res->val->ToObject()->GetPrototype();
-
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- js_to_term(obj_res->ctx,env,get_result)));
+ LHCS(vm->isolate, obj_res->ctx);
+ v8::Local<v8::Value> get_result = obj_res->val->ToObject()->GetPrototype();
+
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ js_to_term(obj_res->ctx, vm->isolate, env,get_result)));
}
TickHandlerResolution result;
result.type = DONE;
@@ -37,14 +37,14 @@ TickHandler(GetProtoTickHandler) {
TickHandler(GetHiddenTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
- v8::Local<v8::Value> get_result = obj_res->val->ToObject()->GetHiddenValue(term_to_js(obj_res->ctx,vm->env,array[2])->ToString());
-
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- js_to_term(obj_res->ctx,env,get_result)));
+ LHCS(vm->isolate, obj_res->ctx);
+ v8::Local<v8::Value> get_result = obj_res->val->ToObject()->GetHiddenValue(term_to_js(obj_res->ctx,vm->isolate,vm->env,array[2])->ToString());
+
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ js_to_term(obj_res->ctx, vm->isolate, env,get_result)));
}
TickHandlerResolution result;
result.type = DONE;
@@ -54,36 +54,36 @@ TickHandler(GetHiddenTickHandler) {
TickHandler(GetInternalTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
-
- int index;
- enif_get_int(vm->env, array[2], &index);
-
- if (index < 0 || (index + 1 > obj_res->val->ToObject()->InternalFieldCount())) {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- enif_make_atom(env,"error")));
- } else {
-
- v8::Local<v8::Value> get_result = obj_res->val->ToObject()->GetInternalField(index);
-
- if (get_result->IsExternal()) {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- external_to_term(get_result)));
- } else {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- js_to_term(obj_res->ctx,env,get_result)));
- }
-
- }
+ LHCS(vm->isolate, obj_res->ctx);
+
+ int index;
+ enif_get_int(vm->env, array[2], &index);
+
+ if (index < 0 || (index + 1 > obj_res->val->ToObject()->InternalFieldCount())) {
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ enif_make_atom(env,"error")));
+ } else {
+
+ v8::Local<v8::Value> get_result = obj_res->val->ToObject()->GetInternalField(index);
+
+ if (get_result->IsExternal()) {
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ external_to_term(get_result)));
+ } else {
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ js_to_term(obj_res->ctx, vm->isolate, env,get_result)));
+ }
+
+ }
}
TickHandlerResolution result;
result.type = DONE;
73 c_src/erlv8_instantiate.cc
View
@@ -17,44 +17,44 @@ TickHandler(InstantiateTickHandler) {
args = new v8::Local<v8::Value>[alen];
int i = 0;
while (enif_get_list_cell(vm->env, current, &head, &tail)) {
- args[i] = v8::Local<v8::Value>::New(term_to_js(fun_res->ctx,vm->env,head));
+ args[i] = v8::Local<v8::Value>::New(term_to_js(fun_res->ctx, vm->isolate, vm->env,head));
i++; current = tail;
}
v8::Handle<v8::Function> f = v8::Handle<v8::Function>::Cast(fun_res->val);
- if (!*f->GetHiddenValue(string__erlv8__)) { // js function
+ if (!*f->GetHiddenValue(vm->string__erlv8__)) { // js function
v8::TryCatch try_catch;
v8::Local<v8::Value> inst_result = f->NewInstance(alen, args);
if (inst_result.IsEmpty()) {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,inst_ref),
- enif_make_tuple2(env,
- enif_make_atom(env,"throw"),
- enif_make_tuple2(env,
- enif_make_atom(env,"error"),
- js_to_term(fun_res->ctx,env,try_catch.Exception())))));
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,inst_ref),
+ enif_make_tuple2(env,
+ enif_make_atom(env,"throw"),
+ enif_make_tuple2(env,
+ enif_make_atom(env,"error"),
+ js_to_term(fun_res->ctx,vm->isolate, env,try_catch.Exception())))));
} else {
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,inst_ref),
- js_to_term(fun_res->ctx,env,inst_result)));
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,inst_ref),
+ js_to_term(fun_res->ctx,vm->isolate, env,inst_result)));
}
} else { // native Erlang function
v8::Local<v8::Array> array = v8::Array::New(alen);
-
+
for (unsigned int i=0;i<alen;i++) {
- array->Set(i,args[i]);
+ array->Set(i,args[i]);
}
-
+
ErlangConstFun(vm,
- external_to_term(f->GetHiddenValue(v8::String::New("__erlv8__"))),
- inst_ref,
- empty_constructor->GetFunction()->NewInstance(),
- array);
+ external_to_term(f->GetHiddenValue(v8::String::New("__erlv8__"))),
+ inst_ref,
+ vm->empty_constructor->GetFunction()->NewInstance(),
+ array);
}
delete [] args;
@@ -71,28 +71,27 @@ void ErlangConstFun(VM * vm, ERL_NIF_TERM term, ERL_NIF_TERM ref, v8::Handle<v8:
ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t));
ptr->ctx = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
-
// prepare arguments
ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * array->Length());
for (unsigned int i=0;i<array->Length();i++) {
- arr[i] = js_to_term(vm->context,vm->env,array->Get(v8::Integer::NewFromUnsigned(i)));
+ arr[i] = js_to_term(vm->context,vm->isolate, vm->env,array->Get(v8::Integer::NewFromUnsigned(i)));
}
ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,array->Length());
free(arr);
// send invocation request
SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_copy(env,term),
- enif_make_tuple7(env,
- enif_make_atom(env,"erlv8_fun_invocation"),
- enif_make_atom(env, "true"),
- js_to_term(vm->context,env, instance), // FIXME: not quite sure it's right
- js_to_term(vm->context,env, instance),
- enif_make_copy(env, ref),
- enif_make_pid(env, vm->server),
- enif_make_resource(env, ptr)
- ),
- enif_make_copy(env,arglist)));
+ enif_make_tuple3(env,
+ enif_make_copy(env,term),
+ enif_make_tuple7(env,
+ enif_make_atom(env,"erlv8_fun_invocation"),
+ enif_make_atom(env, "true"),
+ js_to_term(vm->context, vm->isolate, env, instance), // FIXME: not quite sure it's right
+ js_to_term(vm->context, vm->isolate, env, instance),
+ enif_make_copy(env, ref),
+ enif_make_pid(env, vm->server),
+ enif_make_resource(env, ptr)
+ ),
+ enif_make_copy(env,arglist)));
enif_release_resource(ptr);
};
16 c_src/erlv8_internal.cc
View
@@ -5,15 +5,15 @@ TickHandler(InternalCountTickHandler) {
ERL_NIF_TERM get_ref = enif_make_copy(ref_env, tick_ref);
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
+ LHCS(vm->isolate, obj_res->ctx);
- int ifc = obj_res->val->ToObject()->InternalFieldCount();
-
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,get_ref),
- enif_make_int(env, ifc)));
+ int ifc = obj_res->val->ToObject()->InternalFieldCount();
+
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,get_ref),
+ enif_make_int(env, ifc)));
}
enif_free_env(ref_env);
TickHandlerResolution result;
38 c_src/erlv8_list.cc
View
@@ -3,28 +3,28 @@
TickHandler(ListTickHandler) {
ErlNifEnv *ref_env = enif_alloc_env();
ERL_NIF_TERM list_ref = enif_make_copy(ref_env, tick_ref);
-
+
val_res_t *res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&res))) {
- LHCS(res->ctx);
-
- if (res->val->IsArray()) {
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(res->val->ToObject());
-
- ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * array->Length());
- for (unsigned int i=0;i<array->Length();i++) {
- arr[i] = js_to_term(res->ctx,vm->env,array->Get(v8::Integer::NewFromUnsigned(i)));
- }
- ERL_NIF_TERM list = enif_make_list_from_array(vm->env,arr,array->Length());
- free(arr);
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,list_ref),
- enif_make_copy(env,list)));
- }
+ LHCS(vm->isolate, res->ctx);
+
+ if (res->val->IsArray()) {
+ v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(res->val->ToObject());
+
+ ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * array->Length());
+ for (unsigned int i=0;i<array->Length();i++) {
+ arr[i] = js_to_term(res->ctx, vm->isolate, vm->env, array->Get(v8::Integer::NewFromUnsigned(i)));
+ }
+ ERL_NIF_TERM list = enif_make_list_from_array(vm->env, arr, array->Length());
+ free(arr);
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env, "result"),
+ enif_make_copy(env, list_ref),
+ enif_make_copy(env, list)));
+ }
}
-
+
enif_free_env(ref_env);
TickHandlerResolution result;
result.type = DONE;
40 c_src/erlv8_proplist.cc
View
@@ -3,30 +3,30 @@
TickHandler(ProplistTickHandler) {
ErlNifEnv *ref_env = enif_alloc_env();
ERL_NIF_TERM proplist_ref = enif_make_copy(ref_env, tick_ref);
-
+
val_res_t *res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&res))) {
- LHCS(res->ctx);
+ LHCS(vm->isolate, res->ctx);
- v8::Handle<v8::Array> keys = res->val->ToObject()->GetPropertyNames();
-
- ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * keys->Length());
-
- for (unsigned int i=0;i<keys->Length();i++) {
- v8::Handle<v8::Value> key = keys->Get(v8::Integer::New(i));
- arr[i] = enif_make_tuple2(vm->env,
- js_to_term(res->ctx,vm->env,v8::Handle<v8::String>::Cast(key)),
- js_to_term(res->ctx,vm->env,res->val->ToObject()->Get(key)));
- }
- ERL_NIF_TERM list = enif_make_list_from_array(vm->env,arr,keys->Length());
- free(arr);
- SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,proplist_ref),
- enif_make_copy(env,list)));
+ v8::Handle<v8::Array> keys = res->val->ToObject()->GetPropertyNames();
+
+ ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * keys->Length());
+
+ for (unsigned int i=0;i<keys->Length();i++) {
+ v8::Handle<v8::Value> key = keys->Get(v8::Integer::New(i));
+ arr[i] = enif_make_tuple2(vm->env,
+ js_to_term(res->ctx, vm->isolate, vm->env,v8::Handle<v8::String>::Cast(key)),
+ js_to_term(res->ctx, vm->isolate, vm->env,res->val->ToObject()->Get(key)));
+ }
+ ERL_NIF_TERM list = enif_make_list_from_array(vm->env,arr,keys->Length());
+ free(arr);
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,proplist_ref),
+ enif_make_copy(env,list)));
}
-
+
enif_free_env(ref_env);
TickHandlerResolution result;
result.type = DONE;
8 c_src/erlv8_result.cc
View
@@ -3,12 +3,12 @@
TickHandler(ResultTickHandler) {
v8::HandleScope handle_scope;
TickHandlerResolution result;
-
+
if (((unsigned long) ref) &&
- (enif_is_identical(array[1],ref))) { // this is our result
- result.value = handle_scope.Close(term_to_js(vm->context,vm->env,array[2]));
+ (enif_is_identical(array[1],ref))) { // this is our result
+ result.value = handle_scope.Close(term_to_js(vm->context, vm->isolate, vm->env,array[2]));
result.type = RETURN;
- return result;
+ return result;
} else {
Tick newtick;
97 c_src/erlv8_script.cc
View
@@ -7,47 +7,66 @@ TickHandler(ScriptTickHandler) {
enif_get_list_length(vm->env, array[2], &len);
char * buf = (char *) malloc(len + 1);
enif_get_string(vm->env,array[2],buf,len + 1, ERL_NIF_LATIN1);
-
+
ctx_res_t *res;
if (enif_get_resource(vm->env,array[1],ctx_resource,(void **)(&res))) {
- v8::Context::Scope context_scope(res->ctx);
-
-
- v8::TryCatch try_catch;
-
- v8::ScriptOrigin * origin = new v8::ScriptOrigin(term_to_js(res->ctx,vm->env,array[3])->ToString(),
- term_to_js(res->ctx,vm->env,array[4])->ToInteger(),
- term_to_js(res->ctx,vm->env,array[5])->ToInteger());
-
- v8::Handle<v8::String> script = v8::String::New(buf, len);
- v8::Handle<v8::Script> compiled = v8::Script::Compile(script,origin);
-
- delete origin;
-
- if (compiled.IsEmpty()) {
- SEND(vm->server,enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env, script_ref),
- enif_make_tuple2(env,
- enif_make_atom(env,"throw"),
- js_to_term(res->ctx,env,try_catch.Exception()))));
- } else {
- v8::Handle<v8::Value> value = compiled->Run();
- if (value.IsEmpty()) {
- SEND(vm->server,enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env, script_ref),
- enif_make_tuple2(env,
- enif_make_atom(env,"throw"),
- js_to_term(res->ctx,env,try_catch.Exception()))));
- } else {
- SEND(vm->server,enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env, script_ref),
- enif_make_tuple2(env, enif_make_atom(env,"ok"),
- js_to_term(res->ctx,env,value))));
- }
- }
+ TRACE("(%p) script - 1\n", vm->isolate);
+ v8::Isolate::Scope iscope(vm->isolate);
+ TRACE("(%p) script - 2\n", vm->isolate);
+ v8::Context::Scope context_scope(res->ctx);
+ TRACE("(%p) script - 3\n", vm->isolate);
+ v8::HandleScope handle_scope;
+ TRACE("(%p) script - 4\n", vm->isolate);
+
+
+ v8::TryCatch try_catch;
+
+ TRACE("(%p) script - 4a\n", vm->isolate);
+
+
+ v8::ScriptOrigin * origin = new v8::ScriptOrigin(term_to_js(res->ctx,vm->isolate,vm->env,array[3])->ToString(),
+ term_to_js(res->ctx,vm->isolate,vm->env,array[4])->ToInteger(),
+ term_to_js(res->ctx,vm->isolate,vm->env,array[5])->ToInteger());
+
+ TRACE("(%p) script - 5\n", vm->isolate);
+
+ v8::Handle<v8::String> script = v8::String::New(buf, len);
+ v8::Handle<v8::Script> compiled = v8::Script::Compile(script,origin);
+
+ TRACE("(%p) script - 6\n", vm->isolate);
+
+
+ delete origin;
+
+ if (compiled.IsEmpty()) {
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env, script_ref),
+ enif_make_tuple2(env,
+ enif_make_atom(env,"throw"),
+ js_to_term(res->ctx,vm->isolate,env,try_catch.Exception()))));
+ } else {
+ TRACE("(%p) script - 7\n", vm->isolate);
+
+ v8::Handle<v8::Value> value = compiled->Run();
+ TRACE("(%p) script - 8\n", vm->isolate);
+
+ if (value.IsEmpty()) {
+ SEND(vm->server,enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env, script_ref),
+ enif_make_tuple2(env,
+ enif_make_atom(env,"throw"),
+ js_to_term(res->ctx,vm->isolate,env,try_catch.Exception()))));
+ } else {
+ SEND(vm->server,enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env, script_ref),
+ enif_make_tuple2(env, enif_make_atom(env,"ok"),
+ js_to_term(res->ctx,vm->isolate,env,value))));
+ }
+ }
}
enif_free_env(ref_env);
free(buf);
52 c_src/erlv8_set.cc
View
@@ -5,7 +5,7 @@ TickHandler(SetTickHandler) {
ERL_NIF_TERM value = enif_make_copy(tmp_env, array[3]); // stashing it away since Set() might call an accessor, which might change vm->env
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
+ LHCS(vm->isolate, obj_res->ctx);
v8::PropertyAttribute property_attribute = v8::None;
@@ -13,13 +13,13 @@ TickHandler(SetTickHandler) {
property_attribute = term_to_property_attribute(vm->env,array[4]);
}
- obj_res->val->ToObject()->Set(term_to_js(obj_res->ctx, vm->env,array[2]),term_to_js(obj_res->ctx, tmp_env,value), property_attribute);
+ obj_res->val->ToObject()->Set(term_to_js(obj_res->ctx, vm->isolate, vm->env,array[2]),term_to_js(obj_res->ctx, vm->isolate, tmp_env,value), property_attribute);
SEND(vm->server,
enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- enif_make_copy(env,value)));
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ enif_make_copy(env,value)));
}
enif_free_env(tmp_env);
TickHandlerResolution result;
@@ -30,9 +30,9 @@ TickHandler(SetTickHandler) {
TickHandler(SetProtoTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
+ LHCS(vm->isolate, obj_res->ctx);
- const char *atom_val = obj_res->val->ToObject()->SetPrototype(term_to_js(obj_res->ctx,vm->env,array[2])) ? "true" : "false";
+ const char *atom_val = obj_res->val->ToObject()->SetPrototype(term_to_js(obj_res->ctx,vm->isolate,vm->env,array[2])) ? "true" : "false";
SEND(vm->server,
enif_make_tuple3(env,
@@ -48,15 +48,15 @@ TickHandler(SetProtoTickHandler) {
TickHandler(SetHiddenTickHandler) {
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
-
- obj_res->val->ToObject()->SetHiddenValue(term_to_js(obj_res->ctx,vm->env,array[2])->ToString(),term_to_js(obj_res->ctx,vm->env,array[3]));
+ LHCS(vm->isolate, obj_res->ctx);
+ obj_res->val->ToObject()->SetHiddenValue(term_to_js(obj_res->ctx, vm->isolate, vm->env,array[2])->ToString(),term_to_js(obj_res->ctx,vm->isolate, vm->env,array[3]));
+
SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,tick_ref),
- enif_make_copy(env,array[2])));
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,tick_ref),
+ enif_make_copy(env,array[2])));
}
TickHandlerResolution result;
result.type = DONE;
@@ -69,7 +69,7 @@ TickHandler(SetInternalTickHandler) {
unsigned len;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
+ LHCS(vm->isolate, obj_res->ctx);
int index;
enif_get_int(vm->env, array[2], &index);
@@ -88,7 +88,7 @@ TickHandler(SetInternalTickHandler) {
v8::Handle<v8::Object> proto = extern_name_to_proto(vm, name);
obj_res->val->ToObject()->SetInternalField(index,term_to_external(array[3]));
} else {
- obj_res->val->ToObject()->SetInternalField(index,term_to_js(obj_res->ctx,vm->env,array[3]));
+ obj_res->val->ToObject()->SetInternalField(index,term_to_js(obj_res->ctx,vm->isolate, vm->env,array[3]));
}
SEND(vm->server,
@@ -120,10 +120,10 @@ TickHandler(SetAccessorTickHandler) {
const char *atom_val;
val_res_t *obj_res;
if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
- LHCS(obj_res->ctx);
+ LHCS(vm->isolate, obj_res->ctx);
if (arity > 3) {
- v8::Handle<v8::Value> name = term_to_js(obj_res->ctx,vm->env,array[2]);
+ v8::Handle<v8::Value> name = term_to_js(obj_res->ctx,vm->isolate, vm->env,array[2]);
if (!name->IsString()) {
goto badarg;
}
@@ -132,7 +132,7 @@ TickHandler(SetAccessorTickHandler) {
v8::Persistent<v8::Object> data = v8::Persistent<v8::Object>::New(v8::Object::New());
data.MakeWeak(NULL,weak_accessor_data_cleaner); // so that we'll release externals when we're done
- if (term_to_js(obj_res->ctx,vm->env,array[3])->IsUndefined()) {
+ if (term_to_js(obj_res->ctx,vm->isolate, vm->env,array[3])->IsUndefined()) {
goto badarg;
} else {
data->SetHiddenValue(v8::String::New("_getter"), term_to_external(array[3]));
@@ -197,7 +197,7 @@ v8::Handle<v8::Value> GetterFun(v8::Local<v8::String> property,const v8::Accesso
// prepare arguments
ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * 1);
- arr[0] = js_to_term(vm->context, vm->env, property);
+ arr[0] = js_to_term(vm->context, vm->isolate, vm->env, property);
ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,1);
free(arr);
@@ -208,8 +208,8 @@ v8::Handle<v8::Value> GetterFun(v8::Local<v8::String> property,const v8::Accesso
enif_make_tuple7(env,
enif_make_atom(env,"erlv8_fun_invocation"),
enif_make_atom(env,"false"),
- js_to_term(vm->context, env, info.Holder()),
- js_to_term(vm->context, env, info.This()),
+ js_to_term(vm->context, vm->isolate, env, info.Holder()),
+ js_to_term(vm->context, vm->isolate, env, info.This()),
enif_make_copy(env, ref),
enif_make_pid(env, vm->server),
enif_make_copy(env, external_to_term(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__ctx__"))))
@@ -229,8 +229,8 @@ void SetterFun(v8::Local<v8::String> property,v8::Local<v8::Value> value,const v
// prepare arguments
ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * 2);
- arr[0] = js_to_term(vm->context, vm->env, property);
- arr[1] = js_to_term(vm->context, vm->env, value);
+ arr[0] = js_to_term(vm->context, vm->isolate, vm->env, property);
+ arr[1] = js_to_term(vm->context, vm->isolate, vm->env, value);
ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,2);
free(arr);
@@ -241,8 +241,8 @@ void SetterFun(v8::Local<v8::String> property,v8::Local<v8::Value> value,const v
enif_make_tuple7(env,
enif_make_atom(env,"erlv8_fun_invocation"),
enif_make_atom(env,"false"),
- js_to_term(vm->context, env, info.Holder()),
- js_to_term(vm->context, env, info.This()),
+ js_to_term(vm->context, vm->isolate, env, info.Holder()),
+ js_to_term(vm->context, vm->isolate, env, info.This()),
enif_make_copy(env, ref),
enif_make_pid(env, vm->server),
enif_make_copy(env, external_to_term(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__ctx__"))))
9 c_src/erlv8_stop.cc
View
@@ -1,9 +1,18 @@
#include "erlv8.hh"
TickHandler(StopTickHandler) {
+ TRACE("(%p) stop - 1\n", vm->isolate);
+ v8::Isolate::Scope iscope(vm->isolate);
+ TRACE("(%p) stop - 2\n", vm->isolate);
v8::HandleScope handle_scope;
+ TRACE("(%p) stop - 3\n", vm->isolate);
TickHandlerResolution result;
+ TRACE("(%p) stop - 4\n", vm->isolate);
+ v8::V8::TerminateExecution();
+ TRACE("(%p) stop - 5\n", vm->isolate);
result.value = v8::Undefined();
+ TRACE("(%p) stop - 6\n", vm->isolate);
result.type = RETURN;
+ TRACE("(%p) stop - 7\n", vm->isolate);
return result;
}
16 c_src/erlv8_string.cc
View
@@ -4,10 +4,10 @@ TickHandler(ToStringTickHandler) {
ErlNifEnv *ref_env = enif_alloc_env();
ERL_NIF_TERM to_string_ref = enif_make_copy(ref_env, tick_ref);
SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,to_string_ref),
- js_to_term(vm->context,env,term_to_js(vm->context,vm->env,array[1])->ToString())));
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,to_string_ref),
+ js_to_term(vm->context, vm->isolate, env,term_to_js(vm->context, vm->isolate, vm->env,array[1])->ToString())));
enif_free_env(ref_env);
TickHandlerResolution result;
result.type = DONE;
@@ -18,10 +18,10 @@ TickHandler(ToDetailStringTickHandler) {
ErlNifEnv *ref_env = enif_alloc_env();
ERL_NIF_TERM to_string_ref = enif_make_copy(ref_env, tick_ref);
SEND(vm->server,
- enif_make_tuple3(env,
- enif_make_atom(env,"result"),
- enif_make_copy(env,to_string_ref),
- js_to_term(vm->context,env,term_to_js(vm->context,vm->env,array[1])->ToDetailString())));
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,to_string_ref),
+ js_to_term(vm->context, vm->isolate, env,term_to_js(vm->context,vm->isolate,vm->env,array[1])->ToDetailString())));
enif_free_env(ref_env);
TickHandlerResolution result;
result.type = DONE;
9 c_src/erlv8_taint.cc
View
@@ -1,15 +1,18 @@
#include "erlv8.hh"
TickHandler(TaintTickHandler) {
+ TRACE("(%p) tain - 1\n", vm->isolate);
ErlNifEnv *ref_env = enif_alloc_env();
+ TRACE("(%p) tain - 2\n", vm->isolate);
ERL_NIF_TERM taint_ref = enif_make_copy(ref_env, tick_ref);
- LHCS(vm->context);
-
+ TRACE("(%p) tain - 3\n", vm->isolate);
+ LHCS(vm->isolate, vm->context);
+ TRACE("(%p) tain - 4\n", vm->isolate);
SEND(vm->server,
enif_make_tuple3(env,
enif_make_atom(env,"result"),
enif_make_copy(env,taint_ref),
- js_to_term(vm->context,env,term_to_js(vm->context,vm->env, array[1]))));
+ js_to_term(vm->context, vm->isolate, env,term_to_js(vm->context, vm->isolate,vm->env, array[1]))));
enif_free_env(ref_env);
TickHandlerResolution result;
507 c_src/erlv8_term.cc
View
@@ -41,19 +41,21 @@ v8::PropertyAttribute term_to_property_attribute(ErlNifEnv * env, ERL_NIF_TERM t
char name[MAX_ATOM_LEN];
if (enif_is_atom(env, term)) {
- v8::PropertyAttribute property_attribute;
- enif_get_atom_length(env, term, &len, ERL_NIF_LATIN1);
- enif_get_atom(env,term, (char *) &name,len + 1, ERL_NIF_LATIN1);
- if (!strcmp(name,"none")) {
- property_attribute = v8::None;
- } else if (!strcmp(name,"readonly")) {
- property_attribute = v8::ReadOnly;
- } else if (!strcmp(name,"dontenum")) {
- property_attribute = v8::DontEnum;
- } else if (!strcmp(name,"dontdelete")) {
- property_attribute = v8::DontDelete;
- }
- return property_attribute;
+ v8::PropertyAttribute property_attribute;
+ enif_get_atom_length(env, term, &len, ERL_NIF_LATIN1);
+ enif_get_atom(env,term, (char *) &name,len + 1, ERL_NIF_LATIN1);
+ if (!strcmp(name,"none")) {
+ property_attribute = v8::None;
+ } else if (!strcmp(name,"readonly")) {
+ property_attribute = v8::ReadOnly;
+ } else if (!strcmp(name,"dontenum")) {
+ property_attribute = v8::DontEnum;
+ } else if (!strcmp(name,"dontdelete")) {
+ property_attribute = v8::DontDelete;
+ } else { // always return something
+ property_attribute = v8::None;
+ }
+ return property_attribute;
} else if (enif_is_list(env, term)) {
ERL_NIF_TERM current = term;
ERL_NIF_TERM head, tail;
@@ -103,274 +105,323 @@ v8::Handle<v8::Object> externalize_term(map<ERL_NIF_TERM, v8::Handle<v8::Object>
return handle_scope.Close(iter->second); // it was cached before
} else {
v8::Handle<v8::Value> external = term_to_external(term);
- v8::Handle<v8::Object> obj = external_template->NewInstance();
+ v8::Handle<v8::Object> obj = v8::Object::New();
obj->SetPrototype(proto);
- obj->SetHiddenValue(string__erlv8__, external);
+ obj->SetHiddenValue(v8::String::New("__erlv8__"), external);
cache.insert(std::pair<ERL_NIF_TERM, v8::Handle<v8::Object> >(term, obj)); // cache it
return handle_scope.Close(obj);
}
}
-v8::Handle<v8::Value> term_to_js(v8::Handle<v8::Context> ctx, ErlNifEnv *env, ERL_NIF_TERM term) {
- LHCS(ctx);
+v8::Handle<v8::Value> term_to_js(v8::Handle<v8::Context> ctx, v8::Isolate* isolate, ErlNifEnv *env, ERL_NIF_TERM term) {
+ TRACE("(%p) term_to_js - 1\n", isolate);
+ LHCS(isolate, ctx);
+ TRACE("(%p) term_to_js - 2\n", isolate);
int _int; unsigned int _uint; long _long; unsigned long _ulong; ErlNifSInt64 _int64; ErlNifUInt64 _uint64; double _double;
ErlNifBinary string_binary;
unsigned len;
char name[MAX_ATOM_LEN];
if (enif_is_atom(env, term)) {
- enif_get_atom_length(env, term, &len, ERL_NIF_LATIN1);
- enif_get_atom(env, term, (char *) &name,len + 1, ERL_NIF_LATIN1);
- v8::Handle<v8::Value> result;
-
- // check for special atoms
- if (strcmp(name,"false")==0) {
- result = v8::Local<v8::Boolean>::New(v8::Boolean::New(0));
- } else if (strcmp(name,"true")==0) {
- result = v8::Local<v8::Boolean>::New(v8::Boolean::New(1));
- } else if (strcmp(name,"ok")==0) {
- result = v8::Local<v8::Boolean>::New(v8::Boolean::New(1));
- } else if (strcmp(name,"undefined")==0) {
- result = v8::Undefined();
- } else if (strcmp(name,"null")==0) {
- result = v8::Null();
- } else { // if it is not a special atom, convert it to a string
- result = v8::String::New(name);
- }
- return handle_scope.Close(result);
- } else if (enif_get_int(env,term,&_int)) {
- return handle_scope.Close(v8::Local<v8::Integer>::New(v8::Integer::New(_int)));
+ TRACE("(%p) term_to_js - 3 a\n", isolate);
+ enif_get_atom_length(env, term, &len, ERL_NIF_LATIN1);
+ enif_get_atom(env, term, (char *) &name,len + 1, ERL_NIF_LATIN1);
+ v8::Handle<v8::Value> result;
+ // check for special atoms
+ if (strcmp(name,"false")==0) {
+ result = v8::Local<v8::Boolean>::New(v8::Boolean::New(0));
+ } else if (strcmp(name,"true")==0) {
+ result = v8::Local<v8::Boolean>::New(v8::Boolean::New(1));
+ } else if (strcmp(name,"ok")==0) {
+ result = v8::Local<v8::Boolean>::New(v8::Boolean::New(1));
+ } else if (strcmp(name,"undefined")==0) {
+ result = v8::Undefined();
+ } else if (strcmp(name,"null")==0) {
+ result = v8::Null();
+ } else { // if it is not a special atom, convert it to a string
+ result = v8::String::New(name);
+ }
+ return handle_scope.Close(result);
+ } else if (enif_get_int(env,term,&_int)) {
+ TRACE("(%p) term_to_js - 3 b\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Integer>::New(v8::Integer::New(_int)));
} else if (enif_get_uint(env,term,&_uint)) {
- return handle_scope.Close(v8::Local<v8::Integer>::New(v8::Integer::NewFromUnsigned(_uint)));
+ TRACE("(%p) term_to_js - 3 c\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Integer>::New(v8::Integer::NewFromUnsigned(_uint)));
} else if (enif_get_long(env,term,&_long)) {
- return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_long)));
+ TRACE("(%p) term_to_js - 3 d\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_long)));
} else if (enif_get_ulong(env,term,&_ulong)) {
- return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_ulong)));
+ TRACE("(%p) term_to_js - 3 e\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_ulong)));
} else if (enif_get_int64(env,term,&_int64)) {
- return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_int64)));
+ TRACE("(%p) term_to_js - 3 f\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_int64)));
} else if (enif_get_uint64(env,term,&_uint64)) {
- return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_uint64)));
+ TRACE("(%p) term_to_js - 3 g\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_uint64)));
} else if (enif_get_double(env,term,&_double)) {
- return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_double)));
+ TRACE("(%p) term_to_js - 3 h\n", isolate);
+ return handle_scope.Close(v8::Local<v8::Number>::New(v8::Number::New(_double)));
} else if (enif_inspect_iolist_as_binary(env, term, &string_binary)) { // string
+ TRACE("(%p) term_to_js - 3 i\n", isolate);
v8::Local<v8::String> s = v8::String::New((const char *)string_binary.data, string_binary.size);
+ if (s->Utf8Length() != string_binary.size)
+ printf("%d != %lu\n", s->Utf8Length()-1, string_binary.size);
return handle_scope.Close(s);
} else if (enif_is_tuple(env, term)) {
- ERL_NIF_TERM *array;
- int arity;
- enif_get_tuple(env,term,&arity,(const ERL_NIF_TERM **)&array);
- if (arity == 3) {
- enif_get_atom_length(env, array[0], &len, ERL_NIF_LATIN1);
- enif_get_atom(env,array[0], (char *) &name,len + 1, ERL_NIF_LATIN1);
- val_res_t *res;
- // check if it is a v8_fun
- int isv8fun = strcmp(name,"erlv8_fun")==0;
- // check if it is an object
- int isobj = strcmp(name,"erlv8_object")==0;
- // check if it is an array
- int isarray = strcmp(name,"erlv8_array")==0;
-
- if (isobj||isarray) {
- if (enif_get_resource(env,array[1],val_resource,(void **)(&res))) {
- return handle_scope.Close(res->val->ToObject());
- } else if (isobj && enif_is_proplist(env,array[1])) {
- v8::Local<v8::Object> obj = v8::Object::New();
- ERL_NIF_TERM head, tail;
- ERL_NIF_TERM current = array[1];
- int arity;
- ERL_NIF_TERM *arr;
- while (enif_get_list_cell(env, current, &head, &tail)) {
- enif_get_tuple(env,head,&arity,(const ERL_NIF_TERM **)&arr);
- obj->Set(term_to_js(ctx,env,arr[0]),
- term_to_js(ctx,env,arr[1]));
-
- current = tail;
- }
- return handle_scope.Close(obj);
- } else if (isarray && enif_is_list(env, array[1])) {
- unsigned int i,alen;
- ERL_NIF_TERM head, tail;
- ERL_NIF_TERM current = array[1];
-
- enif_get_list_length(env, current, &alen);
-
- v8::Local<v8::Array> arrobj = v8::Array::New(alen);
-
- i = 0;
- while (enif_get_list_cell(env, current, &head, &tail)) {
- arrobj->Set(v8::Integer::New(i), term_to_js(ctx,env,head));
- current = tail;
- i++;
- }
- return handle_scope.Close(arrobj);
- }
+ TRACE("(%p) term_to_js - 3 j\n", isolate);
+ ERL_NIF_TERM *array;
+ int arity;
+ enif_get_tuple(env,term,&arity,(const ERL_NIF_TERM **)&array);
+ if (arity == 3) {
+ enif_get_atom_length(env, array[0], &len, ERL_NIF_LATIN1);
+ enif_get_atom(env,array[0], (char *) &name,len + 1, ERL_NIF_LATIN1);
+ val_res_t *res;
+ // check if it is a v8_fun
+ int isv8fun = strcmp(name,"erlv8_fun")==0;
+ // check if it is an object
+ int isobj = strcmp(name,"erlv8_object")==0;
+ // check if it is an array
+ int isarray = strcmp(name,"erlv8_array")==0;
+
+ if (isobj||isarray) {
+ if (enif_get_resource(env,array[1],val_resource,(void **)(&res))) {
+ return handle_scope.Close(res->val->ToObject());
+ } else if (isobj && enif_is_proplist(env,array[1])) {
+ v8::Local<v8::Object> obj = v8::Object::New();
+ ERL_NIF_TERM head, tail;
+ ERL_NIF_TERM current = array[1];
+ int arity;
+ ERL_NIF_TERM *arr;
+ while (enif_get_list_cell(env, current, &head, &tail)) {
+ enif_get_tuple(env,head,&arity,(const ERL_NIF_TERM **)&arr);
+ obj->Set(term_to_js(ctx, isolate, env,arr[0]),
+ term_to_js(ctx, isolate, env,arr[1]));
+
+ current = tail;
}
-
- if ((isv8fun) &&
- (enif_get_resource(env,array[1],val_resource,(void **)(&res)))){
- return handle_scope.Close(res->val);
- } else if ((isv8fun) && (enif_is_fun(env, array[1]))) {
- v8::Handle<v8::Function> f = v8::Handle<v8::Function>::Cast(term_to_js(ctx,env,array[1]));
- v8::Handle<v8::Object> o = v8::Handle<v8::Object>::Cast(term_to_js(ctx,env,array[2]));
-
- v8::Local<v8::Array> keys = o->GetPropertyNames();
-
- for (unsigned int i=0;i<keys->Length();i++) {
- v8::Local<v8::Value> key = keys->Get(v8::Integer::New(i));
- f->Set(key,o->Get(key));
- }
+ return handle_scope.Close(obj);
+ } else if (isarray && enif_is_list(env, array[1])) {
+ unsigned int i,alen;
+ ERL_NIF_TERM head, tail;
+ ERL_NIF_TERM current = array[1];
- return handle_scope.Close(f);
-
- }
+ enif_get_list_length(env, current, &alen);
- }
-
- if (arity == 2) {
- enif_get_atom_length(env, array[0], &len, ERL_NIF_LATIN1);
- enif_get_atom(env,array[0], (char *) &name,len + 1, ERL_NIF_LATIN1);
- // check if it is an error
- int iserror = strcmp(name,"error")==0;
- int isthrow = strcmp(name,"throw")==0;
- if (iserror) {
- return handle_scope.Close(v8::Exception::Error(v8::Handle<v8::String>::Cast(term_to_js(ctx,env,array[1]))));
- }
- if (isthrow) {
- return v8::ThrowException(term_to_js(ctx,env, array[1]));
+ v8::Local<v8::Array> arrobj = v8::Array::New(alen);
+
+ i = 0;
+ while (enif_get_list_cell(env, current, &head, &tail)) {
+ arrobj->Set(v8::Integer::New(i), term_to_js(ctx, isolate, env,head));
+ current = tail;
+ i++;
}
+ return handle_scope.Close(arrobj);
}
-
- } else if (enif_is_fun(env, term)) {
- VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(string__erlv8__));
- map<ERL_NIF_TERM, v8::Handle<v8::FunctionTemplate>, cmp_erl_nif_term>::iterator iter = vm->fun_map.find(term);
-
- if (iter != vm->fun_map.end()) {
- return handle_scope.Close(iter->second->GetFunction()); // it was cached before
- } else {
- v8::Handle<v8::Value> external = term_to_external(term);
- v8::Persistent<v8::FunctionTemplate> t = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(WrapFun,external));
-
- v8::Local<v8::Function> f = t->GetFunction();
- f->SetHiddenValue(string__erlv8__, external);
-
- vm->fun_map.insert(std::pair<ERL_NIF_TERM, v8::Handle<v8::FunctionTemplate> >(external_to_term(external), t)); // cache it
- return handle_scope.Close(f);
+ }
+
+ if ((isv8fun) &&
+ (enif_get_resource(env,array[1],val_resource,(void **)(&res)))){
+ return handle_scope.Close(res->val);
+ } else if ((isv8fun) && (enif_is_fun(env, array[1]))) {
+ v8::Handle<v8::Function> f = v8::Handle<v8::Function>::Cast(term_to_js(ctx, isolate, env, array[1]));
+ v8::Handle<v8::Object> o = v8::Handle<v8::Object>::Cast(term_to_js(ctx, isolate, env, array[2]));
+
+ v8::Local<v8::Array> keys = o->GetPropertyNames();
+
+ for (unsigned int i=0;i<keys->Length();i++) {
+ v8::Local<v8::Value> key = keys->Get(v8::Integer::New(i));
+ f->Set(key,o->Get(key));
}
+
+ return handle_scope.Close(f);
+
+ }
+
+ }
+
+ if (arity == 2) {
+ enif_get_atom_length(env, array[0], &len, ERL_NIF_LATIN1);
+ enif_get_atom(env,array[0], (char *) &name,len + 1, ERL_NIF_LATIN1);
+ // check if it is an error
+ int iserror = strcmp(name,"error")==0;
+ int isthrow = strcmp(name,"throw")==0;
+ if (iserror) {
+ return handle_scope.Close(v8::Exception::Error(v8::Handle<v8::String>::Cast(term_to_js(ctx, isolate, env,array[1]))));
+ }
+ if (isthrow) {
+ return v8::ThrowException(term_to_js(ctx, isolate, env, array[1]));
+ }
+ }
+
+ } else if (enif_is_fun(env, term)) {
+ TRACE("(%p) term_to_js - 3 k\n", isolate);
+ VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__")));
+ map<ERL_NIF_TERM, v8::Handle<v8::FunctionTemplate>, cmp_erl_nif_term>::iterator iter = vm->fun_map.find(term);
+
+ if (iter != vm->fun_map.end()) {
+ return handle_scope.Close(iter->second->GetFunction()); // it was cached before
+ } else {
+ v8::Handle<v8::Value> external = term_to_external(term);
+ v8::Persistent<v8::FunctionTemplate> t = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(WrapFun,external));
+
+ v8::Local<v8::Function> f = t->GetFunction();
+ f->SetHiddenValue(vm->string__erlv8__, external);
+
+ vm->fun_map.insert(std::pair<ERL_NIF_TERM, v8::Handle<v8::FunctionTemplate> >(external_to_term(external), t)); // cache it
+ return handle_scope.Close(f);
+ }
} else if (enif_is_pid(env, term)) {
- VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(string__erlv8__));
- return handle_scope.Close(externalize_term(vm->extern_map, vm->external_proto_pid, term));
+ VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__")));
+ return handle_scope.Close(externalize_term(vm->extern_map, vm->external_proto_pid, term));
} else if (enif_is_ref(env, term)) {
- VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(string__erlv8__));
- return handle_scope.Close(externalize_term(vm->extern_map, vm->external_proto_ref, term));
+ VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__")));
+ return handle_scope.Close(externalize_term(vm->extern_map, vm->external_proto_ref, term));
}
-
+
return v8::Undefined(); // if nothing else works, return undefined
};
-ERL_NIF_TERM js_to_term(v8::Handle<v8::Context> ctx, ErlNifEnv *env, v8::Handle<v8::Value> val) {
- LHCS(ctx);
+ERL_NIF_TERM js_to_term(v8::Handle<v8::Context> ctx, v8::Isolate* isolate, ErlNifEnv *env, v8::Handle<v8::Value> val) {
+ TRACE("(%p) js_to_term - 1\n", isolate);
+ LHCS(isolate, ctx);
+ TRACE("(%p) js_to_term - 2\n", isolate);
if (val.IsEmpty()) {
- return enif_make_atom(env,"undefined");
+ TRACE("(%p) js_to_term - 3 a\n", isolate);
+ return enif_make_atom(env,"undefined");
} else if (val->IsFunction()) { // the reason why this check is so high up here is because it is also an object, so it should be before any object.
- val_res_t *ptr;
- v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(val);
- ERL_NIF_TERM resource_term;
-
- ptr = (val_res_t *)enif_alloc_resource(val_resource, sizeof(val_res_t));
-
- ptr->ctx = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
- ptr->val = v8::Persistent<v8::Function>::New(v8::Handle<v8::Function>::Cast(val));
- resource_term = enif_make_resource(env, ptr);
- enif_release_resource(ptr);
-
- VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(string__erlv8__));
-
- ERL_NIF_TERM term = enif_make_tuple3(env,enif_make_atom(env,"erlv8_fun"),
- resource_term,
- enif_make_pid(env, vm->server));
-
-
- return term;
+ TRACE("(%p) js_to_term - 3 b\n", isolate);
+ val_res_t *ptr;
+ TRACE("(%p) js_to_term - 4\n", isolate);
+ v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(val);
+ ERL_NIF_TERM resource_term;
+ TRACE("(%p) js_to_term - 5\n", isolate);
+ ptr = (val_res_t *)enif_alloc_resource(val_resource, sizeof(val_res_t));
+ TRACE("(%p) js_to_term - 6\n", isolate);
+ ptr->ctx = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
+ TRACE("(%p) js_to_term - 7\n", isolate);
+ ptr->val = v8::Persistent<v8::Function>::New(v8::Handle<v8::Function>::Cast(val));
+ TRACE("(%p) js_to_term - 8\n", isolate);
+ resource_term = enif_make_resource(env, ptr);
+ TRACE("(%p) js_to_term - 9\n", isolate);
+ enif_release_resource(ptr);
+ TRACE("(%p) js_to_term - 10\n", isolate);
+ VM * vm = (VM *) v8::External::Unwrap(v8::Context::GetCurrent()->Global()->GetHiddenValue(v8::String::New("__erlv8__")));
+ TRACE("(%p) js_to_term - 11\n", isolate);
+ ERL_NIF_TERM term = enif_make_tuple3(env,enif_make_atom(env,"erlv8_fun"),
+ resource_term,
+ enif_make_pid(env, vm->server));
+ TRACE("(%p) js_to_term - 11\n", isolate);
+
+ return term;
} else if (val->IsUndefined()) {
+ TRACE("(%p) js_to_term - 3 c\n", isolate);
return enif_make_atom(env,"undefined");
} else if (val->IsNull()) {
- return enif_make_atom(env,"null");
+ TRACE("(%p) js_to_term - 3 d\n", isolate);
+ return enif_make_atom(env,"null");
} else if (val->IsTrue()) {
- return enif_make_atom(env,"true");
+ TRACE("(%p) js_to_term - 3 c\n", isolate);
+ return enif_make_atom(env,"true");
} else if (val->IsFalse()) {
- return enif_make_atom(env,"false");
+ TRACE("(%p) js_to_term - 3 d\n", isolate);
+ return enif_make_atom(env,"false");
} else if (val->IsString()) {
+ TRACE("(%p) js_to_term - 3 e\n", isolate);
ErlNifBinary result_binary = {0};
- enif_alloc_binary(v8::String::Utf8Value(val->ToString()).length(), &result_binary);
- (void)memcpy(result_binary.data