@@ -1275,80 +1275,120 @@ ssize_t DecodeWrite(char *buf,
1275
1275
return StringBytes::Write (buf, buflen, val, encoding, NULL );
1276
1276
}
1277
1277
1278
- void DisplayExceptionLine (Handle <Message> message) {
1279
- // Prevent re-entry into this function. For example, if there is
1280
- // a throw from a program in vm.runInThisContext(code, filename, true),
1281
- // then we want to show the original failure, not the secondary one.
1282
- static bool displayed_error = false ;
1283
-
1284
- if (displayed_error)
1278
+ void AppendExceptionLine (Environment* env,
1279
+ Handle <Value> er,
1280
+ Handle <Message> message) {
1281
+ if (message.IsEmpty ())
1285
1282
return ;
1286
- displayed_error = true ;
1287
1283
1288
- uv_tty_reset_mode ();
1284
+ HandleScope scope (env->isolate ());
1285
+ Local<Object> err_obj;
1286
+ if (!er.IsEmpty () && er->IsObject ()) {
1287
+ err_obj = er.As <Object>();
1289
1288
1290
- fprintf (stderr, " \n " );
1291
-
1292
- if (!message.IsEmpty ()) {
1293
- // Print (filename):(line number): (message).
1294
- String::Utf8Value filename (message->GetScriptResourceName ());
1295
- const char * filename_string = *filename;
1296
- int linenum = message->GetLineNumber ();
1297
- fprintf (stderr, " %s:%i\n " , filename_string, linenum);
1298
- // Print line of source code.
1299
- String::Utf8Value sourceline (message->GetSourceLine ());
1300
- const char * sourceline_string = *sourceline;
1301
-
1302
- // Because of how node modules work, all scripts are wrapped with a
1303
- // "function (module, exports, __filename, ...) {"
1304
- // to provide script local variables.
1305
- //
1306
- // When reporting errors on the first line of a script, this wrapper
1307
- // function is leaked to the user. There used to be a hack here to
1308
- // truncate off the first 62 characters, but it caused numerous other
1309
- // problems when vm.runIn*Context() methods were used for non-module
1310
- // code.
1311
- //
1312
- // If we ever decide to re-instate such a hack, the following steps
1313
- // must be taken:
1314
- //
1315
- // 1. Pass a flag around to say "this code was wrapped"
1316
- // 2. Update the stack frame output so that it is also correct.
1317
- //
1318
- // It would probably be simpler to add a line rather than add some
1319
- // number of characters to the first line, since V8 truncates the
1320
- // sourceline to 78 characters, and we end up not providing very much
1321
- // useful debugging info to the user if we remove 62 characters.
1322
-
1323
- int start = message->GetStartColumn ();
1324
- int end = message->GetEndColumn ();
1325
-
1326
- fprintf (stderr, " %s\n " , sourceline_string);
1327
- // Print wavy underline (GetUnderline is deprecated).
1328
- for (int i = 0 ; i < start; i++) {
1329
- fputc ((sourceline_string[i] == ' \t ' ) ? ' \t ' : ' ' , stderr);
1330
- }
1331
- for (int i = start; i < end; i++) {
1332
- fputc (' ^' , stderr);
1333
- }
1334
- fputc (' \n ' , stderr);
1289
+ // Do it only once per message
1290
+ if (!err_obj->GetHiddenValue (env->processed_string ()).IsEmpty ())
1291
+ return ;
1292
+ err_obj->SetHiddenValue (env->processed_string (), True (env->isolate ()));
1335
1293
}
1294
+
1295
+ static char arrow[1024 ];
1296
+
1297
+ // Print (filename):(line number): (message).
1298
+ String::Utf8Value filename (message->GetScriptResourceName ());
1299
+ const char * filename_string = *filename;
1300
+ int linenum = message->GetLineNumber ();
1301
+ // Print line of source code.
1302
+ String::Utf8Value sourceline (message->GetSourceLine ());
1303
+ const char * sourceline_string = *sourceline;
1304
+
1305
+ // Because of how node modules work, all scripts are wrapped with a
1306
+ // "function (module, exports, __filename, ...) {"
1307
+ // to provide script local variables.
1308
+ //
1309
+ // When reporting errors on the first line of a script, this wrapper
1310
+ // function is leaked to the user. There used to be a hack here to
1311
+ // truncate off the first 62 characters, but it caused numerous other
1312
+ // problems when vm.runIn*Context() methods were used for non-module
1313
+ // code.
1314
+ //
1315
+ // If we ever decide to re-instate such a hack, the following steps
1316
+ // must be taken:
1317
+ //
1318
+ // 1. Pass a flag around to say "this code was wrapped"
1319
+ // 2. Update the stack frame output so that it is also correct.
1320
+ //
1321
+ // It would probably be simpler to add a line rather than add some
1322
+ // number of characters to the first line, since V8 truncates the
1323
+ // sourceline to 78 characters, and we end up not providing very much
1324
+ // useful debugging info to the user if we remove 62 characters.
1325
+
1326
+ int start = message->GetStartColumn ();
1327
+ int end = message->GetEndColumn ();
1328
+
1329
+ int off = snprintf (arrow,
1330
+ sizeof (arrow),
1331
+ " %s:%i\n %s\n " ,
1332
+ filename_string,
1333
+ linenum,
1334
+ sourceline_string);
1335
+ assert (off >= 0 );
1336
+
1337
+ // Print wavy underline (GetUnderline is deprecated).
1338
+ for (int i = 0 ; i < start; i++) {
1339
+ assert (static_cast <size_t >(off) < sizeof (arrow));
1340
+ arrow[off++] = (sourceline_string[i] == ' \t ' ) ? ' \t ' : ' ' ;
1341
+ }
1342
+ for (int i = start; i < end; i++) {
1343
+ assert (static_cast <size_t >(off) < sizeof (arrow));
1344
+ arrow[off++] = ' ^' ;
1345
+ }
1346
+ assert (static_cast <size_t >(off) < sizeof (arrow) - 1 );
1347
+ arrow[off++] = ' \n ' ;
1348
+ arrow[off] = ' \0 ' ;
1349
+
1350
+ Local<String> arrow_str = String::NewFromUtf8 (env->isolate (), arrow);
1351
+ Local<Value> msg;
1352
+ Local<Value> stack;
1353
+
1354
+ // Allocation failed, just print it out
1355
+ if (arrow_str.IsEmpty () || err_obj.IsEmpty () || !err_obj->IsNativeError ())
1356
+ goto print;
1357
+
1358
+ msg = err_obj->Get (env->message_string ());
1359
+ stack = err_obj->Get (env->stack_string ());
1360
+
1361
+ if (msg.IsEmpty () || stack.IsEmpty ())
1362
+ goto print;
1363
+
1364
+ err_obj->Set (env->message_string (),
1365
+ String::Concat (arrow_str, msg->ToString ()));
1366
+ err_obj->Set (env->stack_string (),
1367
+ String::Concat (arrow_str, stack->ToString ()));
1368
+ return ;
1369
+
1370
+ print:
1371
+ if (env->printed_error ())
1372
+ return ;
1373
+ env->set_printed_error (true );
1374
+ uv_tty_reset_mode ();
1375
+ fprintf (stderr, " \n %s" , arrow);
1336
1376
}
1337
1377
1338
1378
1339
- static void ReportException (Handle <Value> er, Handle <Message> message) {
1340
- HandleScope scope (node_isolate);
1379
+ static void ReportException (Environment* env,
1380
+ Handle <Value> er,
1381
+ Handle <Message> message) {
1382
+ HandleScope scope (env->isolate ());
1341
1383
1342
- DisplayExceptionLine ( message);
1384
+ AppendExceptionLine (env, er, message);
1343
1385
1344
1386
Local<Value> trace_value;
1345
1387
1346
- if (er->IsUndefined () || er->IsNull ()) {
1347
- trace_value = Undefined (node_isolate);
1348
- } else {
1349
- trace_value =
1350
- er->ToObject ()->Get (FIXED_ONE_BYTE_STRING (node_isolate, " stack" ));
1351
- }
1388
+ if (er->IsUndefined () || er->IsNull ())
1389
+ trace_value = Undefined (env->isolate ());
1390
+ else
1391
+ trace_value = er->ToObject ()->Get (env->stack_string ());
1352
1392
1353
1393
String::Utf8Value trace (trace_value);
1354
1394
@@ -1364,8 +1404,8 @@ static void ReportException(Handle<Value> er, Handle<Message> message) {
1364
1404
1365
1405
if (er->IsObject ()) {
1366
1406
Local<Object> err_obj = er.As <Object>();
1367
- message = err_obj->Get (FIXED_ONE_BYTE_STRING (node_isolate, " message " ));
1368
- name = err_obj->Get (FIXED_ONE_BYTE_STRING (node_isolate , " name" ));
1407
+ message = err_obj->Get (env-> message_string ( ));
1408
+ name = err_obj->Get (FIXED_ONE_BYTE_STRING (env-> isolate () , " name" ));
1369
1409
}
1370
1410
1371
1411
if (message.IsEmpty () ||
@@ -1386,14 +1426,16 @@ static void ReportException(Handle<Value> er, Handle<Message> message) {
1386
1426
}
1387
1427
1388
1428
1389
- static void ReportException (const TryCatch& try_catch) {
1390
- ReportException (try_catch.Exception (), try_catch.Message ());
1429
+ static void ReportException (Environment* env, const TryCatch& try_catch) {
1430
+ ReportException (env, try_catch.Exception (), try_catch.Message ());
1391
1431
}
1392
1432
1393
1433
1394
1434
// Executes a str within the current v8 context.
1395
- Local<Value> ExecuteString (Handle <String> source, Handle <Value> filename) {
1396
- HandleScope scope (node_isolate);
1435
+ static Local<Value> ExecuteString (Environment* env,
1436
+ Handle <String> source,
1437
+ Handle <Value> filename) {
1438
+ HandleScope scope (env->isolate ());
1397
1439
TryCatch try_catch;
1398
1440
1399
1441
// try_catch must be nonverbose to disable FatalException() handler,
@@ -1402,13 +1444,13 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) {
1402
1444
1403
1445
Local<v8::Script> script = v8::Script::Compile (source, filename);
1404
1446
if (script.IsEmpty ()) {
1405
- ReportException (try_catch);
1447
+ ReportException (env, try_catch);
1406
1448
exit (3 );
1407
1449
}
1408
1450
1409
1451
Local<Value> result = script->Run ();
1410
1452
if (result.IsEmpty ()) {
1411
- ReportException (try_catch);
1453
+ ReportException (env, try_catch);
1412
1454
exit (4 );
1413
1455
}
1414
1456
@@ -2025,7 +2067,7 @@ void FatalException(Handle<Value> error, Handle<Message> message) {
2025
2067
if (!fatal_exception_function->IsFunction ()) {
2026
2068
// failed before the process._fatalException function was added!
2027
2069
// this is probably pretty bad. Nothing to do but report and exit.
2028
- ReportException (error, message);
2070
+ ReportException (env, error, message);
2029
2071
exit (6 );
2030
2072
}
2031
2073
@@ -2040,12 +2082,12 @@ void FatalException(Handle<Value> error, Handle<Message> message) {
2040
2082
2041
2083
if (fatal_try_catch.HasCaught ()) {
2042
2084
// the fatal exception function threw, so we must exit
2043
- ReportException (fatal_try_catch);
2085
+ ReportException (env, fatal_try_catch);
2044
2086
exit (7 );
2045
2087
}
2046
2088
2047
2089
if (false == caught->BooleanValue ()) {
2048
- ReportException (error, message);
2090
+ ReportException (env, error, message);
2049
2091
exit (1 );
2050
2092
}
2051
2093
}
@@ -2705,10 +2747,10 @@ void Load(Environment* env) {
2705
2747
// are not safe to ignore.
2706
2748
try_catch.SetVerbose (false );
2707
2749
2708
- Local<String> script_name = FIXED_ONE_BYTE_STRING (node_isolate , " node.js" );
2709
- Local<Value> f_value = ExecuteString (MainSource (), script_name);
2750
+ Local<String> script_name = FIXED_ONE_BYTE_STRING (env-> isolate () , " node.js" );
2751
+ Local<Value> f_value = ExecuteString (env, MainSource (), script_name);
2710
2752
if (try_catch.HasCaught ()) {
2711
- ReportException (try_catch);
2753
+ ReportException (env, try_catch);
2712
2754
exit (10 );
2713
2755
}
2714
2756
assert (f_value->IsFunction ());
0 commit comments