The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.
Please select the desired protocol below to get the URL.
This URL has Read-Only access.
main_repo / src / node.cc @ 90fc8d36
History | View | Annotate | Download (5.29 KB)
1 |
#include "node.h" |
---|---|
2 |
|
3 |
#include "net.h" |
4 |
#include "file.h" |
5 |
#include "process.h" |
6 |
#include "http.h" |
7 |
#include "timers.h" |
8 |
|
9 |
#include "natives.h" |
10 |
|
11 |
#include <stdio.h> |
12 |
#include <assert.h> |
13 |
|
14 |
#include <string> |
15 |
#include <list> |
16 |
#include <map> |
17 |
|
18 |
using namespace v8; |
19 |
using namespace node; |
20 |
using namespace std; |
21 |
|
22 |
static int exit_code = 0; |
23 |
|
24 |
// Extracts a C string from a V8 Utf8Value.
|
25 |
const char* |
26 |
ToCString(const v8::String::Utf8Value& value)
|
27 |
{ |
28 |
return *value ? *value : "<string conversion failed>"; |
29 |
} |
30 |
|
31 |
void
|
32 |
ReportException(v8::TryCatch* try_catch) |
33 |
{ |
34 |
v8::HandleScope handle_scope; |
35 |
v8::String::Utf8Value exception(try_catch->Exception()); |
36 |
const char* exception_string = ToCString(exception); |
37 |
v8::Handle<v8::Message> message = try_catch->Message(); |
38 |
if (message.IsEmpty()) {
|
39 |
// V8 didn't provide any extra information about this error; just
|
40 |
// print the exception.
|
41 |
printf("%s\n", exception_string);
|
42 |
} else {
|
43 |
message->PrintCurrentStackTrace(stdout); |
44 |
|
45 |
// Print (filename):(line number): (message).
|
46 |
v8::String::Utf8Value filename(message->GetScriptResourceName()); |
47 |
const char* filename_string = ToCString(filename); |
48 |
int linenum = message->GetLineNumber();
|
49 |
printf("%s:%i: %s\n", filename_string, linenum, exception_string);
|
50 |
// Print line of source code.
|
51 |
v8::String::Utf8Value sourceline(message->GetSourceLine()); |
52 |
const char* sourceline_string = ToCString(sourceline); |
53 |
printf("%s\n", sourceline_string);
|
54 |
// Print wavy underline (GetUnderline is deprecated).
|
55 |
int start = message->GetStartColumn();
|
56 |
for (int i = 0; i < start; i++) { |
57 |
printf(" ");
|
58 |
} |
59 |
int end = message->GetEndColumn();
|
60 |
for (int i = start; i < end; i++) { |
61 |
printf("^");
|
62 |
} |
63 |
printf("\n");
|
64 |
} |
65 |
} |
66 |
|
67 |
// Executes a string within the current v8 context.
|
68 |
Handle<Value> |
69 |
ExecuteString(v8::Handle<v8::String> source, |
70 |
v8::Handle<v8::Value> filename) |
71 |
{ |
72 |
HandleScope scope; |
73 |
TryCatch try_catch; |
74 |
|
75 |
Handle<Script> script = Script::Compile(source, filename); |
76 |
if (script.IsEmpty()) {
|
77 |
ReportException(&try_catch); |
78 |
exit(1);
|
79 |
} |
80 |
|
81 |
Handle<Value> result = script->Run(); |
82 |
if (result.IsEmpty()) {
|
83 |
ReportException(&try_catch); |
84 |
exit(1);
|
85 |
} |
86 |
|
87 |
return scope.Close(result);
|
88 |
} |
89 |
|
90 |
NODE_METHOD(compile) |
91 |
{ |
92 |
if (args.Length() < 2) |
93 |
return Undefined();
|
94 |
|
95 |
HandleScope scope; |
96 |
|
97 |
Local<String> source = args[0]->ToString();
|
98 |
Local<String> filename = args[1]->ToString();
|
99 |
|
100 |
Handle<Value> result = ExecuteString(source, filename); |
101 |
|
102 |
return scope.Close(result);
|
103 |
} |
104 |
|
105 |
NODE_METHOD(debug) |
106 |
{ |
107 |
if (args.Length() < 1) |
108 |
return Undefined();
|
109 |
HandleScope scope; |
110 |
String::Utf8Value msg(args[0]->ToString());
|
111 |
fprintf(stderr, "DEBUG: %s\n", *msg);
|
112 |
return Undefined();
|
113 |
} |
114 |
|
115 |
static void |
116 |
OnFatalError (const char* location, const char* message) |
117 |
{ |
118 |
#define FATAL_ERROR "\033[1;31mV8 FATAL ERROR.\033[m" |
119 |
if (location)
|
120 |
fprintf(stderr, FATAL_ERROR " %s %s\n", location, message);
|
121 |
else
|
122 |
fprintf(stderr, FATAL_ERROR " %s\n", message);
|
123 |
|
124 |
exit(1);
|
125 |
} |
126 |
|
127 |
|
128 |
void
|
129 |
node_fatal_exception (TryCatch &try_catch) |
130 |
{ |
131 |
ReportException(&try_catch); |
132 |
ev_unloop(EV_DEFAULT_UC_ EVUNLOOP_ALL); |
133 |
exit_code = 1;
|
134 |
} |
135 |
|
136 |
void node_exit (int code) |
137 |
{ |
138 |
exit_code = code; |
139 |
ev_unloop(EV_DEFAULT_UC_ EVUNLOOP_ALL); |
140 |
} |
141 |
|
142 |
|
143 |
static ev_async thread_pool_watcher;
|
144 |
|
145 |
static void |
146 |
thread_pool_cb (EV_P_ ev_async *w, int revents)
|
147 |
{ |
148 |
int r = eio_poll();
|
149 |
/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
|
150 |
|
151 |
// XXX is this check too heavy?
|
152 |
// it require three locks in eio
|
153 |
// what's the better way?
|
154 |
if (eio_nreqs () == 0 && eio_nready() == 0 && eio_npending() == 0) |
155 |
ev_async_stop(EV_DEFAULT_ w); |
156 |
} |
157 |
|
158 |
static void |
159 |
thread_pool_want_poll (void)
|
160 |
{ |
161 |
ev_async_send(EV_DEFAULT_ &thread_pool_watcher); |
162 |
} |
163 |
|
164 |
void
|
165 |
node_eio_warmup (void)
|
166 |
{ |
167 |
ev_async_start(EV_DEFAULT_ &thread_pool_watcher); |
168 |
} |
169 |
|
170 |
int
|
171 |
main (int argc, char *argv[]) |
172 |
{ |
173 |
ev_default_loop(EVFLAG_AUTO); // initialize the default ev loop.
|
174 |
|
175 |
// start eio thread pool
|
176 |
ev_async_init(&thread_pool_watcher, thread_pool_cb); |
177 |
eio_init(thread_pool_want_poll, NULL);
|
178 |
|
179 |
V8::SetFlagsFromCommandLine(&argc, argv, true);
|
180 |
|
181 |
if(argc < 2) { |
182 |
fprintf(stderr, "No script was specified.\n");
|
183 |
return 1; |
184 |
} |
185 |
|
186 |
string filename(argv[1]); |
187 |
|
188 |
HandleScope handle_scope; |
189 |
|
190 |
Persistent<Context> context = Context::New(NULL, ObjectTemplate::New());
|
191 |
Context::Scope context_scope(context); |
192 |
V8::SetFatalErrorHandler(OnFatalError); |
193 |
|
194 |
Local<Object> g = Context::GetCurrent()->Global(); |
195 |
|
196 |
Local<Object> node = Object::New(); |
197 |
g->Set(String::New("node"), node);
|
198 |
|
199 |
NODE_SET_METHOD(node, "compile", compile);
|
200 |
NODE_SET_METHOD(node, "debug", debug);
|
201 |
|
202 |
Local<Array> arguments = Array::New(argc); |
203 |
for (int i = 0; i < argc; i++) { |
204 |
Local<String> arg = String::New(argv[i]); |
205 |
arguments->Set(Integer::New(i), arg); |
206 |
} |
207 |
g->Set(String::New("ARGV"), arguments);
|
208 |
|
209 |
// BUILT-IN MODULES
|
210 |
NodeInit_net(g); |
211 |
NodeInit_timers(g); |
212 |
NodeInit_process(g); |
213 |
NodeInit_file(g); |
214 |
NodeInit_http(g); |
215 |
|
216 |
// NATIVE JAVASCRIPT MODULES
|
217 |
TryCatch try_catch; |
218 |
|
219 |
ExecuteString(String::New(native_file), String::New("file.js"));
|
220 |
if (try_catch.HasCaught()) goto native_js_error; |
221 |
|
222 |
ExecuteString(String::New(native_main), String::New("main.js"));
|
223 |
if (try_catch.HasCaught()) goto native_js_error; |
224 |
|
225 |
ev_loop(EV_DEFAULT_UC_ 0);
|
226 |
|
227 |
context.Dispose(); |
228 |
|
229 |
return exit_code;
|
230 |
|
231 |
native_js_error:
|
232 |
ReportException(&try_catch); |
233 |
return 1; |
234 |
} |