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 @ 63a9cd38
History | View | Annotate | Download (6.07 KB)
1 |
#include "node.h" |
---|---|
2 |
|
3 |
//#include "net.h"
|
4 |
#include "file.h" |
5 |
#include "process.h" |
6 |
#include "node_http.h" |
7 |
#include "node_timer.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 |
Handle<Script> script = Script::Compile(source, filename); |
74 |
if (script.IsEmpty()) {
|
75 |
return ThrowException(String::New("Error compiling string")); |
76 |
} |
77 |
|
78 |
Handle<Value> result = script->Run(); |
79 |
if (result.IsEmpty()) {
|
80 |
return ThrowException(String::New("Error running string")); |
81 |
} |
82 |
|
83 |
return scope.Close(result);
|
84 |
} |
85 |
|
86 |
JS_METHOD(print) |
87 |
{ |
88 |
if (args.Length() < 1) return v8::Undefined(); |
89 |
HandleScope scope; |
90 |
Handle<Value> arg = args[0];
|
91 |
String::Utf8Value value(arg); |
92 |
|
93 |
printf("%s\n", *value);
|
94 |
fflush(stdout); |
95 |
|
96 |
return Undefined();
|
97 |
} |
98 |
|
99 |
|
100 |
JS_METHOD(cat) |
101 |
{ |
102 |
if (args.Length() < 1) return v8::Undefined(); |
103 |
HandleScope scope; |
104 |
|
105 |
String::Utf8Value filename(args[0]);
|
106 |
|
107 |
Local<String> error_msg = String::New("File I/O error");
|
108 |
|
109 |
FILE* file = fopen(*filename, "rb");
|
110 |
if (file == NULL) { |
111 |
// Raise error
|
112 |
perror("fopen()");
|
113 |
return ThrowException(error_msg);
|
114 |
} |
115 |
|
116 |
int r = fseek(file, 0, SEEK_END); |
117 |
if (r < 0) { |
118 |
perror("fseek()");
|
119 |
return ThrowException(error_msg);
|
120 |
} |
121 |
|
122 |
int size = ftell(file);
|
123 |
if (size < 0) { |
124 |
perror("ftell()");
|
125 |
return ThrowException(error_msg);
|
126 |
} |
127 |
rewind(file); |
128 |
|
129 |
char chars[size+1]; |
130 |
chars[size] = '\0';
|
131 |
for (int i = 0; i < size;) { |
132 |
int read = fread(&chars[i], 1, size - i, file); |
133 |
if(read <= 0) { |
134 |
perror("read()");
|
135 |
return ThrowException(error_msg);
|
136 |
} |
137 |
i += read; |
138 |
} |
139 |
|
140 |
uint16_t expanded_base[size+1];
|
141 |
expanded_base[size] = '\0';
|
142 |
for(int i = 0; i < size; i++) |
143 |
expanded_base[i] = chars[i]; |
144 |
|
145 |
fclose(file); |
146 |
|
147 |
Local<String> contents = String::New(expanded_base, size); |
148 |
|
149 |
return scope.Close(contents);
|
150 |
} |
151 |
|
152 |
JS_METHOD(exec) |
153 |
{ |
154 |
if (args.Length() < 2) |
155 |
return Undefined();
|
156 |
|
157 |
HandleScope scope; |
158 |
|
159 |
Local<String> source = args[0]->ToString();
|
160 |
Local<String> filename = args[1]->ToString();
|
161 |
|
162 |
Handle<Value> result = ExecuteString(source, filename); |
163 |
|
164 |
return scope.Close(result);
|
165 |
} |
166 |
|
167 |
|
168 |
static void |
169 |
OnFatalError (const char* location, const char* message) |
170 |
{ |
171 |
fprintf(stderr, "Fatal error. %s %s\n", location, message);
|
172 |
ev_unloop(node_loop(), EVUNLOOP_ALL); |
173 |
} |
174 |
|
175 |
|
176 |
void
|
177 |
node_fatal_exception (TryCatch &try_catch) |
178 |
{ |
179 |
ReportException(&try_catch); |
180 |
ev_unloop(node_loop(), EVUNLOOP_ALL); |
181 |
exit_code = 1;
|
182 |
} |
183 |
|
184 |
void node_exit (int code) |
185 |
{ |
186 |
exit_code = code; |
187 |
ev_unloop(node_loop(), EVUNLOOP_ALL); |
188 |
} |
189 |
|
190 |
|
191 |
static ev_async thread_pool_watcher;
|
192 |
|
193 |
static void |
194 |
thread_pool_cb (EV_P_ ev_async *w, int revents)
|
195 |
{ |
196 |
int r = eio_poll();
|
197 |
/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
|
198 |
if(r == 0) ev_async_stop(EV_DEFAULT_ w); |
199 |
} |
200 |
|
201 |
static void |
202 |
thread_pool_want_poll (void)
|
203 |
{ |
204 |
ev_async_send(EV_DEFAULT_ &thread_pool_watcher); |
205 |
} |
206 |
|
207 |
void
|
208 |
node_eio_submit(eio_req *req) |
209 |
{ |
210 |
ev_async_start(EV_DEFAULT_ &thread_pool_watcher); |
211 |
} |
212 |
|
213 |
int
|
214 |
main (int argc, char *argv[]) |
215 |
{ |
216 |
// start eio thread pool
|
217 |
ev_async_init(&thread_pool_watcher, thread_pool_cb); |
218 |
eio_init(thread_pool_want_poll, NULL);
|
219 |
|
220 |
V8::SetFlagsFromCommandLine(&argc, argv, true);
|
221 |
|
222 |
if(argc < 2) { |
223 |
fprintf(stderr, "No script was specified.\n");
|
224 |
return 1; |
225 |
} |
226 |
|
227 |
string filename(argv[1]); |
228 |
|
229 |
HandleScope handle_scope; |
230 |
|
231 |
Persistent<Context> context = Context::New(NULL, ObjectTemplate::New());
|
232 |
Context::Scope context_scope(context); |
233 |
V8::SetFatalErrorHandler(OnFatalError); |
234 |
|
235 |
Local<Object> g = Context::GetCurrent()->Global(); |
236 |
|
237 |
Local<Object> node = Object::New(); |
238 |
g->Set(String::New("node"), node);
|
239 |
|
240 |
Local<Object> blocking = Object::New(); |
241 |
node->Set(String::New("blocking"), blocking);
|
242 |
|
243 |
JS_SET_METHOD(blocking, "exec", exec);
|
244 |
JS_SET_METHOD(blocking, "cat", cat);
|
245 |
JS_SET_METHOD(blocking, "print", print);
|
246 |
|
247 |
Local<Array> arguments = Array::New(argc); |
248 |
for (int i = 0; i < argc; i++) { |
249 |
Local<String> arg = String::New(argv[i]); |
250 |
arguments->Set(Integer::New(i), arg); |
251 |
} |
252 |
g->Set(String::New("ARGV"), arguments);
|
253 |
|
254 |
// BUILT-IN MODULES
|
255 |
Init_timer(g); |
256 |
//NodeInit_net(g);
|
257 |
NodeInit_process(g); |
258 |
NodeInit_file(g); |
259 |
Init_http(g); |
260 |
|
261 |
// NATIVE JAVASCRIPT MODULES
|
262 |
TryCatch try_catch; |
263 |
Handle<Value> result = ExecuteString(String::New(native_main), |
264 |
String::New("main.js"));
|
265 |
if (try_catch.HasCaught()) {
|
266 |
ReportException(&try_catch); |
267 |
return 1; |
268 |
} |
269 |
|
270 |
ev_loop(node_loop(), 0);
|
271 |
|
272 |
context.Dispose(); |
273 |
|
274 |
return exit_code;
|
275 |
} |