PageRenderTime 38ms CodeModel.GetById 1ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/c_src/erlv8.hh

http://github.com/beamjs/erlv8
C++ Header | 221 lines | 165 code | 48 blank | 8 comment | 0 complexity | d386446658352e2a96c2404bdb370f82 MD5 | raw file
  1#include "v8.h"
  2
  3#include "erl_nif.h"
  4
  5#include <pthread.h>
  6
  7#include <iostream>
  8#include <cstring>
  9#include <cmath>
 10#include <map>
 11#include <queue>
 12
 13#include <zmq.h>
 14
 15
 16// Debugging
 17
 18#ifdef ERLV8_DEBUG
 19#define DEBUG(pid,name,code) SEND(pid, enif_make_tuple3(env, enif_make_atom(env,"DEBUG"), name, code))
 20#define TRACE printf
 21#else
 22#define DEBUG(pid,name,code)
 23#define TRACE(...)
 24#endif
 25
 26// Debugging end
 27
 28using namespace std;
 29using namespace __gnu_cxx;
 30
 31// This should be enough for our tags:
 32#define MAX_ATOM_LEN 32 
 33
 34class VM; // fwd
 35typedef struct _vm_res_t { 
 36  VM * vm;
 37} vm_res_t;
 38
 39typedef struct _val_res_t { 
 40  v8::Persistent<v8::Context> ctx;
 41  v8::Persistent<v8::Value> val;
 42} val_res_t;
 43
 44typedef struct _term_ref_t {
 45  ErlNifEnv *env;
 46  ERL_NIF_TERM term;
 47} term_ref_t;
 48
 49typedef struct _ctx_res_t { 
 50  v8::Persistent<v8::Context> ctx;
 51} ctx_res_t;
 52
 53// Helpers
 54#define LHCS(iso, ctx)					\
 55  TRACE("(%p) LHCS - 1\n", iso);			\
 56  v8::Locker locker(iso);				\
 57  TRACE("(%p) LHCS - 2\n", iso);			\
 58  v8::Isolate::Scope iscope(iso);			\
 59  TRACE("(%p) LHCS - 3\n", iso);			\
 60  v8::HandleScope handle_scope;				\
 61  TRACE("(%p) LHCS - 4\n", iso);			\
 62  v8::Context::Scope context_scope(ctx);		\
 63  TRACE("(%p) LHCS - 1\n", iso)
 64
 65#define SEND(pid, code)\
 66  {\
 67	Send send = Send(pid);\
 68	ErlNifEnv * env = send.env;\
 69	send.send(code);\
 70  }
 71//
 72
 73struct cmp_erl_nif_term
 74{
 75  bool operator()(ERL_NIF_TERM a, ERL_NIF_TERM b)
 76   {
 77	 return enif_compare(a,b) < 0;
 78   }
 79};
 80
 81
 82// Statics
 83
 84extern ErlNifResourceType * vm_resource;
 85extern ErlNifResourceType * val_resource;
 86extern ErlNifResourceType * ctx_resource;
 87
 88extern void *zmq_context;
 89
 90//
 91
 92struct Tick {
 93  ErlNifEnv * env;
 94  ERL_NIF_TERM tick;
 95  ERL_NIF_TERM ref;
 96};
 97
 98// VM
 99class VM {
100public:
101  v8::Persistent<v8::ObjectTemplate> global_template;
102  v8::Persistent<v8::ObjectTemplate> external_template;
103  v8::Persistent<v8::FunctionTemplate> empty_constructor;
104  v8::Persistent<v8::String> string__erlv8__;
105  
106
107  v8::Persistent<v8::Context> context;
108  v8::Persistent<v8::Object> external_proto_num;
109  v8::Persistent<v8::Object> external_proto_atom;
110  v8::Persistent<v8::Object> external_proto_bin;
111  v8::Persistent<v8::Object> external_proto_ref;
112  v8::Persistent<v8::Object> external_proto_fun;
113  v8::Persistent<v8::Object> external_proto_port;
114  v8::Persistent<v8::Object> external_proto_pid;
115  v8::Persistent<v8::Object> external_proto_tuple;
116  v8::Persistent<v8::Object> external_proto_list;
117
118  ErlNifPid *server;
119  ErlNifEnv *env;
120  ErlNifMutex *mutex;
121
122  void * push_socket;
123  void * ticker_push_socket;
124  void * pull_socket;
125
126  queue<Tick> pop_ticks;
127
128  ErlNifTid tid;
129  
130  vm_res_t * resource;
131
132  map<ERL_NIF_TERM, v8::Handle<v8::FunctionTemplate>, cmp_erl_nif_term> fun_map;
133  map<ERL_NIF_TERM, v8::Handle<v8::Object>, cmp_erl_nif_term> extern_map;
134
135  VM();
136  ~VM();
137  void run();
138  void terminate();
139  v8::Handle<v8::Value> ticker(ERL_NIF_TERM ref);
140
141  v8::Isolate* isolate;
142};
143
144enum TickHandlerResolutionType { DONE, RETURN, NEXT };
145
146typedef struct {
147  v8::Handle<v8::Value> value;
148  TickHandlerResolutionType type;
149} TickHandlerResolution;
150
151#define TickHandler(name) extern TickHandlerResolution name(VM * vm, char * tick_name, ERL_NIF_TERM tick, ERL_NIF_TERM tick_ref, ERL_NIF_TERM ref, int arity, const ERL_NIF_TERM * array)
152
153TickHandler(StopTickHandler);
154TickHandler(ResultTickHandler);
155TickHandler(CallTickHandler);
156TickHandler(InstantiateTickHandler);
157TickHandler(DeleteTickHandler);
158TickHandler(TaintTickHandler);
159TickHandler(EqualsTickHandler);
160TickHandler(StrictEqualsTickHandler);
161TickHandler(GetTickHandler);
162TickHandler(GetProtoTickHandler);
163TickHandler(GetHiddenTickHandler);
164TickHandler(SetTickHandler);
165TickHandler(SetProtoTickHandler);
166TickHandler(SetHiddenTickHandler);
167TickHandler(SetAccessorTickHandler);
168TickHandler(ProplistTickHandler);
169TickHandler(ListTickHandler);
170TickHandler(ScriptTickHandler);
171TickHandler(GCTickHandler);
172TickHandler(TerminateTickHandler);
173TickHandler(ToStringTickHandler);
174TickHandler(ToDetailStringTickHandler);
175TickHandler(ExternProtoTickHandler);
176TickHandler(ExternalizeTickHandler);
177TickHandler(UnknownTickHandler);
178TickHandler(InternalCountTickHandler);
179TickHandler(SetInternalTickHandler);
180TickHandler(GetInternalTickHandler);
181
182class Send {
183public:
184  ErlNifPid * pid;
185  ErlNifEnv * env;
186  
187  Send(ErlNifPid *a_pid) : pid(a_pid) {
188    env = enif_alloc_env();
189  };
190  
191  ~Send() {
192    enif_free_env(env);
193  };
194  
195  void send(ERL_NIF_TERM term) {
196    enif_send(NULL, pid, env, term);
197    enif_clear_env(env);
198  };
199  
200};
201
202#define __ERLV8__(O) v8::Local<v8::External>::Cast(O->GetHiddenValue(v8::String::New("__erlv8__")))->Value()
203
204v8::Handle<v8::Value> term_to_js(v8::Handle<v8::Context> ctx, v8::Isolate* isolate, ErlNifEnv *env, ERL_NIF_TERM term);
205ERL_NIF_TERM js_to_term(v8::Handle<v8::Context> ctx, v8::Isolate* isolate, ErlNifEnv *env, v8::Handle<v8::Value> val);
206ERL_NIF_TERM external_to_term(v8::Handle<v8::Value> val);
207v8::Handle<v8::Value> term_to_external(ERL_NIF_TERM term);
208v8::PropertyAttribute term_to_property_attribute(ErlNifEnv * env, ERL_NIF_TERM term);
209int enif_is_proplist(ErlNifEnv * env, ERL_NIF_TERM term);
210v8::PropertyAttribute term_to_property_attribute(ErlNifEnv * env, ERL_NIF_TERM term);
211v8::Handle<v8::Value> term_to_external(ERL_NIF_TERM term);
212ERL_NIF_TERM external_to_term(v8::Handle<v8::Value> val);
213v8::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);
214v8::Handle<v8::Value> term_to_js(ErlNifEnv *env, v8::Isolate* isolat, ERL_NIF_TERM term);
215ERL_NIF_TERM js_to_term(ErlNifEnv *env, v8::Isolate* isolat, v8::Handle<v8::Value> val);
216v8::Handle<v8::Value> WrapFun(const v8::Arguments &arguments);
217v8::Handle<v8::Value> EmptyFun(const v8::Arguments &arguments);
218
219v8::Handle<v8::Object> extern_name_to_proto(VM * vm, char *name);
220
221