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.

Statistics
| Branch: | Revision:

main_repo / src / node.cc @ 12d31dd0

History | View | Annotate | Download (5.9 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(cat) 
87
{
88
  if (args.Length() < 1) return v8::Undefined();
89
  HandleScope scope;
90

    
91
  String::Utf8Value filename(args[0]);
92

    
93
  Local<String> error_msg = String::New("File I/O error");
94

    
95
  FILE* file = fopen(*filename, "rb");
96
  if (file == NULL) {
97
    // Raise error
98
    perror("fopen()");
99
    return ThrowException(error_msg);
100
  }
101
 
102
  int r = fseek(file, 0, SEEK_END);
103
  if (r < 0) {
104
    perror("fseek()");
105
    return ThrowException(error_msg);
106
  }
107

    
108
  int size = ftell(file);
109
  if (size < 0) {
110
    perror("ftell()");
111
    return ThrowException(error_msg);
112
  }
113
  rewind(file);
114

    
115
  char chars[size+1];
116
  chars[size] = '\0';
117
  for (int i = 0; i < size;) {
118
    int read = fread(&chars[i], 1, size - i, file);
119
    if(read <= 0) {
120
      perror("read()");
121
      return ThrowException(error_msg);
122
    }
123
    i += read;
124
  }
125

    
126
  uint16_t expanded_base[size+1];
127
  expanded_base[size] = '\0';
128
  for(int i = 0; i < size; i++) 
129
    expanded_base[i] = chars[i];
130

    
131
  fclose(file);
132

    
133
  Local<String> contents = String::New(expanded_base, size);
134

    
135
  return scope.Close(contents);
136
}
137

    
138
JS_METHOD(exec) 
139
{
140
  if (args.Length() < 2) 
141
    return Undefined();
142

    
143
  HandleScope scope;
144

    
145
  Local<String> source = args[0]->ToString();
146
  Local<String> filename = args[1]->ToString();
147

    
148
  Handle<Value> result = ExecuteString(source, filename);
149
  
150
  return scope.Close(result);
151
}
152

    
153

    
154
static void
155
OnFatalError (const char* location, const char* message)
156
{
157
  fprintf(stderr, "Fatal error: %s %s\n", location, message);
158
  ev_unloop(node_loop(), EVUNLOOP_ALL);
159
}
160

    
161

    
162
void
163
node_fatal_exception (TryCatch &try_catch)
164
{
165
  ReportException(&try_catch);
166
  ev_unloop(node_loop(), EVUNLOOP_ALL);
167
  exit_code = 1;
168
}
169

    
170
void node_exit (int code)
171
{
172
  exit_code = code;
173
  ev_unloop(node_loop(), EVUNLOOP_ALL);
174
}
175

    
176

    
177
static ev_async thread_pool_watcher;
178

    
179
static void 
180
thread_pool_cb (EV_P_ ev_async *w, int revents)
181
{
182
  int r = eio_poll();
183
  /* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
184
  if(r == 0) ev_async_stop(EV_DEFAULT_ w);
185
}
186

    
187
static void
188
thread_pool_want_poll (void)
189
{
190
  ev_async_send(EV_DEFAULT_ &thread_pool_watcher); 
191
}
192

    
193
void
194
node_eio_submit(eio_req *req)
195
{
196
  ev_async_start(EV_DEFAULT_ &thread_pool_watcher);
197
}
198

    
199
int
200
main (int argc, char *argv[]) 
201
{
202
  // start eio thread pool
203
  ev_async_init(&thread_pool_watcher, thread_pool_cb);
204
  eio_init(thread_pool_want_poll, NULL);
205

    
206
  V8::SetFlagsFromCommandLine(&argc, argv, true);
207

    
208
  if(argc < 2)  {
209
    fprintf(stderr, "No script was specified.\n");
210
    return 1;
211
  }
212

    
213
  string filename(argv[1]);
214

    
215
  HandleScope handle_scope;
216

    
217
  Persistent<Context> context = Context::New(NULL, ObjectTemplate::New());
218
  Context::Scope context_scope(context);
219
  V8::SetFatalErrorHandler(OnFatalError);
220

    
221
  Local<Object> g = Context::GetCurrent()->Global();
222

    
223
  Local<Object> node = Object::New();
224
  g->Set(String::New("node"), node);
225

    
226
  Local<Object> blocking = Object::New();
227
  node->Set(String::New("blocking"), blocking);
228

    
229
  JS_SET_METHOD(blocking, "exec", exec);
230
  JS_SET_METHOD(blocking, "cat", cat);
231

    
232
  Local<Array> arguments = Array::New(argc);
233
  for (int i = 0; i < argc; i++) {
234
    Local<String> arg = String::New(argv[i]);
235
    arguments->Set(Integer::New(i), arg);
236
  }
237
  g->Set(String::New("ARGV"), arguments);
238

    
239
  // BUILT-IN MODULES
240
  Init_timer(g);
241
  //NodeInit_net(g);
242
  NodeInit_process(g);
243
  NodeInit_file(g);
244
  Init_http(g);
245

    
246
  // NATIVE JAVASCRIPT MODULES
247
  TryCatch try_catch;
248

    
249
  ExecuteString(String::New(native_file), String::New("file.js"));
250
  if (try_catch.HasCaught()) goto native_js_error; 
251

    
252
  ExecuteString(String::New(native_main), String::New("main.js"));
253
  if (try_catch.HasCaught()) goto native_js_error; 
254

    
255
  ev_loop(node_loop(), 0);
256

    
257
  context.Dispose();
258

    
259
  return exit_code;
260

    
261
native_js_error:
262
  ReportException(&try_catch);
263
  return 1;
264
}