Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
core: isolate-ify
  • Loading branch information
bnoordhuis committed Nov 29, 2011
1 parent bf06e27 commit d4f1972
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 78 deletions.
191 changes: 116 additions & 75 deletions src/node.cc
Expand Up @@ -99,51 +99,75 @@ extern char **environ;

namespace node {

static Persistent<Object> process;
static TLS(Persistent<Object>, process);
#define process VAR(process)

static Persistent<String> errno_symbol;
static Persistent<String> syscall_symbol;
static Persistent<String> errpath_symbol;
static Persistent<String> code_symbol;
static TLS(Persistent<String>, errno_symbol);
#define errno_symbol VAR(errno_symbol)

static Persistent<String> rss_symbol;
static Persistent<String> heap_total_symbol;
static Persistent<String> heap_used_symbol;
static TLS(Persistent<String>, syscall_symbol);
#define syscall_symbol VAR(syscall_symbol)

static Persistent<String> listeners_symbol;
static Persistent<String> uncaught_exception_symbol;
static Persistent<String> emit_symbol;
static TLS(Persistent<String>, errpath_symbol);
#define errpath_symbol VAR(errpath_symbol)

static TLS(Persistent<String>, code_symbol);
#define code_symbol VAR(code_symbol)

static char *eval_string = NULL;
static int option_end_index = 0;
static bool use_debug_agent = false;
static bool debug_wait_connect = false;
static int debug_port=5858;
static int max_stack_size = 0;
static TLS(Persistent<String>, rss_symbol);
#define rss_symbol VAR(rss_symbol)

static uv_check_t check_tick_watcher;
static uv_prepare_t prepare_tick_watcher;
static uv_idle_t tick_spinner;
static bool need_tick_cb;
static Persistent<String> tick_callback_sym;
static TLS(Persistent<String>, heap_total_symbol);
#define heap_total_symbol VAR(heap_total_symbol)

static TLS(Persistent<String>, heap_used_symbol);
#define heap_used_symbol VAR(heap_used_symbol)

static TLS(Persistent<String>, listeners_symbol);
#define listeners_symbol VAR(listeners_symbol)

static TLS(Persistent<String>, uncaught_exception_symbol);
#define uncaught_exception_symbol VAR(uncaught_exception_symbol)

static TLS(Persistent<String>, emit_symbol);
#define emit_symbol VAR(emit_symbol)

static TLS(Persistent<String>, tick_callback_sym);
#define tick_callback_sym VAR(tick_callback_sym)

static TLS(Persistent<Object>, binding_cache);
#define binding_cache VAR(binding_cache)

static TLS(Persistent<Array>, module_load_list);
#define module_load_list VAR(module_load_list)

static THREAD char *eval_string = NULL;
static THREAD int option_end_index = 0;
static THREAD bool use_debug_agent = false;
static THREAD bool debug_wait_connect = false;
static THREAD int debug_port=5858;
static THREAD int max_stack_size = 0;

static THREAD uv_check_t check_tick_watcher;
static THREAD uv_prepare_t prepare_tick_watcher;
static THREAD uv_idle_t tick_spinner;
static THREAD bool need_tick_cb;

#ifdef OPENSSL_NPN_NEGOTIATED
static bool use_npn = true;
static THREAD bool use_npn = true;
#else
static bool use_npn = false;
static THREAD bool use_npn = false;
#endif

#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
static bool use_sni = true;
static THREAD bool use_sni = true;
#else
static bool use_sni = false;
static THREAD bool use_sni = false;
#endif

// Buffer for getpwnam_r(), getgrpam_r() and other misc callers; keep this
// scoped at file-level rather than method-level to avoid excess stack usage.
static char getbuf[PATH_MAX + 1];
static THREAD char getbuf[PATH_MAX + 1];

// We need to notify V8 when we're idle so that it can run the garbage
// collector. The interface to this is V8::IdleNotification(). It returns
Expand All @@ -152,18 +176,20 @@ static char getbuf[PATH_MAX + 1];
//
// A rather convoluted algorithm has been devised to determine when Node is
// idle. You'll have to figure it out for yourself.
static uv_check_t gc_check;
static uv_idle_t gc_idle;
static uv_timer_t gc_timer;
bool need_gc;
static THREAD uv_check_t gc_check;
static THREAD uv_idle_t gc_idle;
static THREAD uv_timer_t gc_timer;
bool THREAD need_gc;


#define FAST_TICK 700.
#define GC_WAIT_TIME 5000.
#define RPM_SAMPLES 100
#define TICK_TIME(n) tick_times[(tick_time_head - (n)) % RPM_SAMPLES]
static int64_t tick_times[RPM_SAMPLES];
static int tick_time_head;
static THREAD int64_t tick_times[RPM_SAMPLES];
static THREAD int tick_time_head;

static THREAD uv_async_t debug_watcher;

static void CheckStatus(uv_timer_t* watcher, int status);

Expand Down Expand Up @@ -228,11 +254,7 @@ static void Tick(void) {

HandleScope scope;

if (tick_callback_sym.IsEmpty()) {
// Lazily set the symbol
tick_callback_sym =
Persistent<String>::New(String::NewSymbol("_tickCallback"));
}
LAZY_ASSIGN(tick_callback_sym, "_tickCallback");

Local<Value> cb_v = process->Get(tick_callback_sym);
if (!cb_v->IsFunction()) return;
Expand Down Expand Up @@ -773,11 +795,11 @@ Local<Value> ErrnoException(int errorno,
Local<String> cons1 = String::Concat(estring, String::NewSymbol(", "));
Local<String> cons2 = String::Concat(cons1, message);

if (syscall_symbol.IsEmpty()) {
syscall_symbol = NODE_PSYMBOL("syscall");
errno_symbol = NODE_PSYMBOL("errno");
errpath_symbol = NODE_PSYMBOL("path");
code_symbol = NODE_PSYMBOL("code");
if (EMPTY(syscall_symbol)) {
ASSIGN(syscall_symbol, "syscall");
ASSIGN(errno_symbol, "errno");
ASSIGN(errpath_symbol, "path");
ASSIGN(code_symbol, "code");
}

if (path) {
Expand Down Expand Up @@ -889,9 +911,7 @@ void MakeCallback(Handle<Object> object,
void SetErrno(uv_err_t err) {
HandleScope scope;

if (errno_symbol.IsEmpty()) {
errno_symbol = NODE_PSYMBOL("errno");
}
LAZY_ASSIGN(errno_symbol, "errno");

if (err.code == UV_UNKNOWN) {
char errno_buf[100];
Expand Down Expand Up @@ -1478,10 +1498,10 @@ v8::Handle<v8::Value> MemoryUsage(const v8::Arguments& args) {

Local<Object> info = Object::New();

if (rss_symbol.IsEmpty()) {
rss_symbol = NODE_PSYMBOL("rss");
heap_total_symbol = NODE_PSYMBOL("heapTotal");
heap_used_symbol = NODE_PSYMBOL("heapUsed");
if (EMPTY(rss_symbol)) {
ASSIGN(rss_symbol, "rss");
ASSIGN(heap_total_symbol, "heapTotal");
ASSIGN(heap_used_symbol, "heapUsed");
}

info->Set(rss_symbol, Integer::NewFromUnsigned(rss));
Expand Down Expand Up @@ -1625,7 +1645,7 @@ static void OnFatalError(const char* location, const char* message) {
exit(1);
}

static int uncaught_exception_counter = 0;
static THREAD int uncaught_exception_counter = 0;

void FatalException(TryCatch &try_catch) {
HandleScope scope;
Expand All @@ -1636,10 +1656,10 @@ void FatalException(TryCatch &try_catch) {
exit(1);
}

if (listeners_symbol.IsEmpty()) {
listeners_symbol = NODE_PSYMBOL("listeners");
uncaught_exception_symbol = NODE_PSYMBOL("uncaughtException");
emit_symbol = NODE_PSYMBOL("emit");
if (EMPTY(listeners_symbol)) {
ASSIGN(listeners_symbol, "listeners");
ASSIGN(uncaught_exception_symbol, "uncaughtException");
ASSIGN(emit_symbol, "emit");
}

Local<Value> listeners_v = process->Get(listeners_symbol);
Expand Down Expand Up @@ -1678,8 +1698,6 @@ void FatalException(TryCatch &try_catch) {
}


static uv_async_t debug_watcher;

static void DebugMessageCallback(uv_async_t* watcher, int status) {
HandleScope scope;
assert(watcher == &debug_watcher);
Expand All @@ -1702,19 +1720,14 @@ static void DebugBreakMessageHandler(const Debug::Message& message) {
}


Persistent<Object> binding_cache;
Persistent<Array> module_load_list;

static Handle<Value> Binding(const Arguments& args) {
HandleScope scope;

Local<String> module = args[0]->ToString();
String::Utf8Value module_v(module);
node_module_struct* modp;

if (binding_cache.IsEmpty()) {
binding_cache = Persistent<Object>::New(Object::New());
}
LAZY_ASSIGN(binding_cache, Object::New());

Local<Object> exports;

Expand Down Expand Up @@ -1760,9 +1773,38 @@ static Handle<Value> Binding(const Arguments& args) {
}


static Handle<Value> Print(const Arguments& args) {
for (int i = 0; args[i]->IsString(); ++i) {
String::Utf8Value s(args[i]);
write(1, *s, s.length());
}
write(1, "\n", 1);
return Undefined();
}


static void RunIsolate(void* arg) {
uv_loop_t* loop = uv_loop_new();
Isolate* isolate = Isolate::New(loop);

HandleScope scope;

Persistent<Context> context = Context::New();
Context::Scope context_scope(context);

Local<Object> global = context->Global();
NODE_SET_METHOD(global, "print", Print);

char *argv[] = { "node", "tmp/empty.js", NULL }; // FIXME

Handle<Object> process_object = SetupProcessObject(ARRAY_SIZE(argv) - 1, argv);
// v8_typed_array::AttachBindings(global); // FIXME

// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Load(process_object);

context.Dispose();
}


Expand Down Expand Up @@ -1948,12 +1990,11 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {

Local<FunctionTemplate> process_template = FunctionTemplate::New();

process = Persistent<Object>::New(process_template->GetFunction()->NewInstance());

ASSIGN(process, process_template->GetFunction()->NewInstance());

process->SetAccessor(String::New("title"),
ProcessTitleGetter,
ProcessTitleSetter);
ProcessTitleGetter,
ProcessTitleSetter);

// process.version
process->Set(String::NewSymbol("version"), String::New(NODE_VERSION));
Expand All @@ -1964,7 +2005,7 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
#endif

// process.moduleLoadList
module_load_list = Persistent<Array>::New(Array::New());
ASSIGN(module_load_list, Array::New());
process->Set(String::NewSymbol("moduleLoadList"), module_load_list);

Local<Object> versions = Object::New();
Expand Down Expand Up @@ -2091,7 +2132,7 @@ static void SignalExit(int signal) {
}


void Load(Handle<Object> process) {
void Load(Handle<Object> process_object) {
// Compile, execute the src/node.js file. (Which was included as static C
// string in node_natives.h. 'natve_node' is the string containing that
// source code.)
Expand Down Expand Up @@ -2121,7 +2162,7 @@ void Load(Handle<Object> process) {

// Add a reference to the global object
Local<Object> global = v8::Context::GetCurrent()->Global();
Local<Value> args[1] = { Local<Value>::New(process) };
Local<Value> args[1] = { Local<Value>::New(process_object) };

#ifdef HAVE_DTRACE
InitDTrace(global);
Expand Down Expand Up @@ -2564,14 +2605,14 @@ char** Init(int argc, char *argv[]) {
}


void EmitExit(v8::Handle<v8::Object> process) {
void EmitExit(v8::Handle<v8::Object> process_object) {
// process.emit('exit')
Local<Value> emit_v = process->Get(String::New("emit"));
assert(emit_v->IsFunction());
Local<Function> emit = Local<Function>::Cast(emit_v);
Local<Value> args[] = { String::New("exit") };
TryCatch try_catch;
emit->Call(process, 1, args);
emit->Call(process_object, 1, args);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
Expand All @@ -2592,12 +2633,12 @@ int Start(int argc, char *argv[]) {
// Create the main node::Isolate object
Isolate* isolate = Isolate::New(uv_default_loop());

Handle<Object> process = SetupProcessObject(argc, argv);
Handle<Object> process_object = SetupProcessObject(argc, argv);
v8_typed_array::AttachBindings(context->Global());

// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Load(process);
Load(process_object);

// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If
Expand All @@ -2606,7 +2647,7 @@ int Start(int argc, char *argv[]) {
// watchers, it blocks.
uv_run(NODE_LOOP());

EmitExit(process);
EmitExit(process_object);

isolate->Dispose();

Expand Down
6 changes: 3 additions & 3 deletions src/node.h
Expand Up @@ -88,7 +88,7 @@ void Load(v8::Handle<v8::Object> process);
void EmitExit(v8::Handle<v8::Object> process);

#define NODE_PSYMBOL(s) \
v8::Persistent<v8::String>::New(v8::String::NewSymbol(s))
(v8::Persistent<v8::String>::New(v8::String::NewSymbol(s)))

/* Converts a unixtime to V8 Date */
#define NODE_UNIXTIME_V8(t) v8::Date::New(1000*static_cast<double>(t))
Expand All @@ -101,8 +101,8 @@ void EmitExit(v8::Handle<v8::Object> process);
v8::ReadOnly|v8::DontDelete))

#define NODE_SET_METHOD(obj, name, callback) \
obj->Set(v8::String::NewSymbol(name), \
v8::FunctionTemplate::New(callback)->GetFunction())
(obj)->Set(v8::String::NewSymbol((name)), \
v8::FunctionTemplate::New((callback))->GetFunction())

#define NODE_SET_PROTOTYPE_METHOD(templ, name, callback) \
do { \
Expand Down

0 comments on commit d4f1972

Please sign in to comment.