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 @ 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
}