Skip to content

Instantly share code, notes, and snippets.

@evax
Created March 22, 2011 12:10
Show Gist options
  • Save evax/881119 to your computer and use it in GitHub Desktop.
Save evax/881119 to your computer and use it in GitHub Desktop.
diff --git a/c_src/erlv8.cc b/c_src/erlv8.cc
index e984844..84b0144 100644
--- a/c_src/erlv8.cc
+++ b/c_src/erlv8.cc
@@ -23,6 +23,7 @@ static ErlV8TickHandler tick_handlers[] =
{"set", SetTickHandler},
{"set_proto", SetProtoTickHandler},
{"set_hidden", SetHiddenTickHandler},
+ {"set_accessor", SetAccessorTickHandler},
{"proplist", ProplistTickHandler},
{"list", ListTickHandler},
{"script", ScriptTickHandler},
@@ -320,79 +321,6 @@ static ERL_NIF_TERM new_context(ErlNifEnv *env, int argc, const ERL_NIF_TERM arg
};
};
-v8::Handle<v8::Value> GetterFun(v8::Local<v8::String> property,const v8::AccessorInfo &info); // fwd
-void SetterFun(v8::Local<v8::String> property,v8::Local<v8::Value> value,const v8::AccessorInfo &info); // fwd
-
-void weak_accessor_data_cleaner(v8::Persistent<v8::Value> object, void * data) {
- if (object.IsNearDeath()) {
- object->ToObject()->DeleteHiddenValue(v8::String::New("_getter"));
- object->ToObject()->DeleteHiddenValue(v8::String::New("_setter"));
- object.Dispose();
- object.Clear();
- }
-}
-
-static ERL_NIF_TERM object_set_accessor(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
- val_res_t *res;
- char aname[MAX_ATOM_LEN];
- if (enif_get_resource(env,argv[0],val_resource,(void **)(&res))) {
- LHCS(res->ctx);
- if (argc > 2) {
- v8::Handle<v8::Value> name = term_to_js(env,argv[1]);
- if (!name->IsString())
- return enif_make_badarg(env);
-
- v8::AccessorGetter getter = GetterFun;
- v8::AccessorSetter setter = 0;
- 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(env,argv[2])->IsUndefined()) {
- return enif_make_badarg(env);
- } else {
- data->SetHiddenValue(v8::String::New("_getter"), term_to_external(argv[2]));
- }
-
- if (argc > 3) {
- setter = SetterFun;
- data->SetHiddenValue(v8::String::New("_setter"), term_to_external(argv[3]));
- }
-
- v8::AccessControl access_control = v8::DEFAULT;
-
- if (argc > 4 && enif_is_atom(env, argv[4])) {
- unsigned len;
- enif_get_atom_length(env, argv[4], &len, ERL_NIF_LATIN1);
- enif_get_atom(env,argv[4], (char *) &aname,len + 1, ERL_NIF_LATIN1);
- if (!strcmp(aname,"default")) {
- access_control = v8::DEFAULT;
- } else if (!strcmp(aname,"all_can_read")) {
- access_control = v8::ALL_CAN_READ;
- } else if (!strcmp(aname,"all_can_write")) {
- access_control = v8::ALL_CAN_WRITE;
- } else if (!strcmp(aname,"prohibits_overwriting")) {
- access_control = v8::PROHIBITS_OVERWRITING;
- }
- }
-
- v8::PropertyAttribute property_attribute = v8::None;
-
- if (argc > 5) {
- property_attribute = term_to_property_attribute(env,argv[5]);
- }
-
- return enif_make_atom(env, res->val->ToObject()->SetAccessor(name->ToString(), getter, setter, data,
- access_control, property_attribute) ? "true" : "false");
- } else {
- return enif_make_badarg(env);
- }
- } else {
- return enif_make_badarg(env);
- };
-};
-
-
-
static ErlNifFunc nif_funcs[] =
{
{"new_vm", 0, new_vm},
@@ -401,11 +329,6 @@ static ErlNifFunc nif_funcs[] =
{"new_context", 1, new_context},
{"global",1, global},
{"tick",3, tick},
- {"object_set_accessor", 3, object_set_accessor},
- {"object_set_accessor", 4, object_set_accessor},
- {"object_set_accessor", 5, object_set_accessor},
- {"object_set_accessor", 6, object_set_accessor},
- {"object_set_accessor", 7, object_set_accessor}
};
#define __ERLV8__(O) v8::Local<v8::External>::Cast(O->GetHiddenValue(string__erlv8__))->Value()
diff --git a/c_src/erlv8.hh b/c_src/erlv8.hh
index 3830093..11a0fcc 100644
--- a/c_src/erlv8.hh
+++ b/c_src/erlv8.hh
@@ -136,6 +136,7 @@ TickHandler(GetHiddenTickHandler);
TickHandler(SetTickHandler);
TickHandler(SetProtoTickHandler);
TickHandler(SetHiddenTickHandler);
+TickHandler(SetAccessorTickHandler);
TickHandler(ProplistTickHandler);
TickHandler(ListTickHandler);
TickHandler(ScriptTickHandler);
diff --git a/c_src/erlv8_set.cc b/c_src/erlv8_set.cc
index 45a63c1..2c75161 100644
--- a/c_src/erlv8_set.cc
+++ b/c_src/erlv8_set.cc
@@ -104,3 +104,86 @@ TickHandler(SetInternalTickHandler) {
enif_free_env(ref_env);
return DONE;
}
+
+v8::Handle<v8::Value> GetterFun(v8::Local<v8::String> property,const v8::AccessorInfo &info); // fwd
+void SetterFun(v8::Local<v8::String> property,v8::Local<v8::Value> value,const v8::AccessorInfo &info); // fwd
+
+void weak_accessor_data_cleaner(v8::Persistent<v8::Value> object, void * data) {
+ if (object.IsNearDeath()) {
+ object->ToObject()->DeleteHiddenValue(v8::String::New("_getter"));
+ object->ToObject()->DeleteHiddenValue(v8::String::New("_setter"));
+ object.Dispose();
+ object.Clear();
+ }
+}
+
+TickHandler(SetAccessorTickHandler) {
+ char aname[MAX_ATOM_LEN];
+ ErlNifEnv *ref_env = enif_alloc_env();
+ ERL_NIF_TERM set_ref = enif_make_copy(ref_env, tick_ref);
+ ERL_NIF_TERM ret;
+ val_res_t *obj_res;
+ if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&obj_res))) {
+ LHCS(obj_res->ctx);
+
+ if (arity > 3) {
+ v8::Handle<v8::Value> name = term_to_js(ref_env,array[2]);
+ if (!name->IsString()) {
+ goto badarg;
+ }
+ v8::AccessorGetter getter = GetterFun;
+ v8::AccessorSetter setter = 0;
+ 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(ref_env,array[3])->IsUndefined()) {
+ goto badarg;
+ } else {
+ data->SetHiddenValue(v8::String::New("_getter"), term_to_external(array[3]));
+ }
+
+ if (arity > 4) {
+ setter = SetterFun;
+ data->SetHiddenValue(v8::String::New("_setter"), term_to_external(array[4]));
+ }
+
+ v8::AccessControl access_control = v8::DEFAULT;
+
+ if (arity > 5 && enif_is_atom(ref_env, array[5])) {
+ unsigned len;
+ enif_get_atom_length(ref_env, array[5], &len, ERL_NIF_LATIN1);
+ enif_get_atom(ref_env,array[5], (char *) &aname,len + 1, ERL_NIF_LATIN1);
+ if (!strcmp(aname,"default")) {
+ access_control = v8::DEFAULT;
+ } else if (!strcmp(aname,"all_can_read")) {
+ access_control = v8::ALL_CAN_READ;
+ } else if (!strcmp(aname,"all_can_write")) {
+ access_control = v8::ALL_CAN_WRITE;
+ } else if (!strcmp(aname,"prohibits_overwriting")) {
+ access_control = v8::PROHIBITS_OVERWRITING;
+ }
+ }
+
+ v8::PropertyAttribute property_attribute = v8::None;
+
+ if (arity > 6) {
+ property_attribute = term_to_property_attribute(ref_env,array[6]);
+ }
+
+ ret = enif_make_atom(ref_env, obj_res->val->ToObject()->SetAccessor(name->ToString(), getter, setter, data,
+ access_control, property_attribute) ? "true" : "false");
+ goto send;
+ }
+badarg:
+ ret = enif_make_atom(ref_env, "badarg");
+send:
+ SEND(vm->server,
+ enif_make_tuple3(env,
+ enif_make_atom(env,"result"),
+ enif_make_copy(env,set_ref),
+ ret));
+ }
+ enif_free_env(ref_env);
+ return DONE;
+}
+
diff --git a/src/erlv8_nif.erl b/src/erlv8_nif.erl
index dca9fa1..68f9df5 100644
--- a/src/erlv8_nif.erl
+++ b/src/erlv8_nif.erl
@@ -1,9 +1,7 @@
-module(erlv8_nif).
-on_load(init/0).
--export([init/0,new_vm/0,set_server/2,global/1,context/1, new_context/1, tick/3,
- object_set_accessor/3, object_set_accessor/4,
- object_set_accessor/5, object_set_accessor/6, object_set_accessor/7]).
+-export([init/0, new_vm/0, set_server/2, global/1, context/1, new_context/1, tick/3]).
-define(DEFAULT_PREEMPTION, 100).
@@ -47,17 +45,3 @@ global(_ContextObject) ->
tick(_VMObject, _Ref, _Tick) ->
error(not_loaded).
-object_set_accessor(_ObjectRes, _Name, _Getter) ->
- error(not_loaded).
-
-object_set_accessor(_ObjectRes, _Name, _Getter, _Setter) ->
- error(not_loaded).
-
-object_set_accessor(_ObjectRes, _Name, _Getter, _Setter, _Data) ->
- error(not_loaded).
-
-object_set_accessor(_ObjectRes, _Name, _Getter, _Setter, _Data, _Setting) ->
- error(not_loaded).
-
-object_set_accessor(_ObjectRes, _Name, _Getter, _Setter, _Data, _Setting, _Attribute) ->
- error(not_loaded).
diff --git a/src/erlv8_object.erl b/src/erlv8_object.erl
index 4be7a29..07adf45 100644
--- a/src/erlv8_object.erl
+++ b/src/erlv8_object.erl
@@ -60,17 +60,36 @@ delete(Key) ->
erlv8_vm:enqueue_tick(VM, {delete, Resource, Key}).
set_accessor(Property, Getter) ->
- erlv8_nif:object_set_accessor(Resource, Property, Getter).
+ case erlv8_vm:enqueue_tick(VM, {set_accessor, Resource, Property, Getter}) of
+ badarg ->
+ throw(badarg);
+ Result ->
+ Result
+ end.
set_accessor(Property, Getter, Setter) ->
- erlv8_nif:object_set_accessor(Resource, Property, Getter, Setter).
+ case erlv8_vm:enqueue_tick(VM, {set_accessor, Resource, Property, Getter, Setter}) of
+ badarg ->
+ throw(badarg);
+ Result ->
+ Result
+ end.
set_accessor(Property, Getter, Setter, AccessControl) ->
- erlv8_nif:object_set_accessor(Resource, Property, Getter, Setter, AccessControl).
+ case erlv8_vm:enqueue_tick(VM, {set_accessor, Resource, Property, Getter, Setter, AccessControl}) of
+ badarg ->
+ throw(badarg);
+ Result ->
+ Result
+ end.
set_accessor(Property, Getter, Setter, AccessControl, PropertyAttribute) ->
- erlv8_nif:object_set_accessor(Resource, Property, Getter, Setter, AccessControl, PropertyAttribute).
-
+ case erlv8_vm:enqueue_tick(VM, {set_accessor, Resource, Property, Getter, Setter, AccessControl, PropertyAttribute}) of
+ badarg ->
+ throw(badarg);
+ Result ->
+ Result
+ end.
equals({_Tag,AnotherObject,_}) ->
erlv8_value:equals(VM, Resource, AnotherObject).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment