Created
March 22, 2011 13:04
-
-
Save evax/881178 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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..a5fb2fa 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); | |
+ 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); | |
+ | |
+ if (arity > 3) { | |
+ v8::Handle<v8::Value> name = term_to_js(vm->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(vm->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(vm->env, array[5])) { | |
+ unsigned len; | |
+ enif_get_atom_length(vm->env, array[5], &len, ERL_NIF_LATIN1); | |
+ enif_get_atom(vm->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(vm->env,array[6]); | |
+ } | |
+ | |
+ atom_val = obj_res->val->ToObject()->SetAccessor(name->ToString(), getter, setter, data, | |
+ access_control, property_attribute) ? "true" : "false"; | |
+ goto send; | |
+ } | |
+badarg: | |
+ atom_val = "badarg"; | |
+send: | |
+ SEND(vm->server, | |
+ enif_make_tuple3(env, | |
+ enif_make_atom(env,"result"), | |
+ enif_make_copy(env,set_ref), | |
+ enif_make_atom(env, atom_val))); | |
+ } | |
+ 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