/c_src/erlv8_instantiate.cc
C++ | 96 lines | 83 code | 11 blank | 2 comment | 8 complexity | eb3d03cde7097fa5168c66fe549a9082 MD5 | raw file
1#include "erlv8.hh" 2 3void ErlangConstFun(VM * vm, ERL_NIF_TERM term, ERL_NIF_TERM ref, v8::Handle<v8::Object> instance, v8::Handle<v8::Array> array); // fwd 4 5TickHandler(InstantiateTickHandler) { 6 ErlNifEnv *ref_env = enif_alloc_env(); 7 ERL_NIF_TERM inst_ref = enif_make_copy(ref_env, tick_ref); 8 val_res_t *fun_res; 9 if (enif_get_resource(vm->env,array[1],val_resource,(void **)(&fun_res))) { 10 ERL_NIF_TERM head, tail; 11 ERL_NIF_TERM current = array[2]; 12 unsigned int alen; 13 14 enif_get_list_length(vm->env,array[2],&alen); 15 16 v8::Local<v8::Value> *args = NULL; 17 args = new v8::Local<v8::Value>[alen]; 18 int i = 0; 19 while (enif_get_list_cell(vm->env, current, &head, &tail)) { 20 args[i] = v8::Local<v8::Value>::New(term_to_js(fun_res->ctx, vm->isolate, vm->env,head)); 21 i++; current = tail; 22 } 23 24 v8::Handle<v8::Function> f = v8::Handle<v8::Function>::Cast(fun_res->val); 25 26 if (!*f->GetHiddenValue(vm->string__erlv8__)) { // js function 27 v8::TryCatch try_catch; 28 v8::Local<v8::Value> inst_result = f->NewInstance(alen, args); 29 if (inst_result.IsEmpty()) { 30 SEND(vm->server, 31 enif_make_tuple3(env, 32 enif_make_atom(env,"result"), 33 enif_make_copy(env,inst_ref), 34 enif_make_tuple2(env, 35 enif_make_atom(env,"throw"), 36 enif_make_tuple2(env, 37 enif_make_atom(env,"error"), 38 js_to_term(fun_res->ctx,vm->isolate, env,try_catch.Exception()))))); 39 } else { 40 SEND(vm->server, 41 enif_make_tuple3(env, 42 enif_make_atom(env,"result"), 43 enif_make_copy(env,inst_ref), 44 js_to_term(fun_res->ctx,vm->isolate, env,inst_result))); 45 } 46 } else { // native Erlang function 47 v8::Local<v8::Array> array = v8::Array::New(alen); 48 49 for (unsigned int i=0;i<alen;i++) { 50 array->Set(i,args[i]); 51 } 52 53 ErlangConstFun(vm, 54 external_to_term(f->GetHiddenValue(v8::String::New("__erlv8__"))), 55 inst_ref, 56 vm->empty_constructor->GetFunction()->NewInstance(), 57 array); 58 } 59 60 delete [] args; 61 args = NULL; 62 } 63 enif_free_env(ref_env); 64 TickHandlerResolution result; 65 result.type = DONE; 66 return result; 67} 68 69void ErlangConstFun(VM * vm, ERL_NIF_TERM term, ERL_NIF_TERM ref, v8::Handle<v8::Object> instance, v8::Handle<v8::Array> array) { 70 v8::HandleScope handle_scope; 71 72 ctx_res_t *ptr = (ctx_res_t *)enif_alloc_resource(ctx_resource, sizeof(ctx_res_t)); 73 ptr->ctx = v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); 74 // prepare arguments 75 ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM) * array->Length()); 76 for (unsigned int i=0;i<array->Length();i++) { 77 arr[i] = js_to_term(vm->context,vm->isolate, vm->env,array->Get(v8::Integer::NewFromUnsigned(i))); 78 } 79 ERL_NIF_TERM arglist = enif_make_list_from_array(vm->env,arr,array->Length()); 80 free(arr); 81 // send invocation request 82 SEND(vm->server, 83 enif_make_tuple3(env, 84 enif_make_copy(env,term), 85 enif_make_tuple7(env, 86 enif_make_atom(env,"erlv8_fun_invocation"), 87 enif_make_atom(env, "true"), 88 js_to_term(vm->context, vm->isolate, env, instance), // FIXME: not quite sure it's right 89 js_to_term(vm->context, vm->isolate, env, instance), 90 enif_make_copy(env, ref), 91 enif_make_pid(env, vm->server), 92 enif_make_resource(env, ptr) 93 ), 94 enif_make_copy(env,arglist))); 95 enif_release_resource(ptr); 96};