@@ -37,7 +37,11 @@ using v8::FunctionCallbackInfo;
37
37
using v8::HandleScope;
38
38
using v8::Integer;
39
39
using v8::Isolate;
40
+ using v8::Just;
40
41
using v8::Local;
42
+ using v8::Maybe;
43
+ using v8::MaybeLocal;
44
+ using v8::Nothing;
41
45
using v8::Null;
42
46
using v8::Number;
43
47
using v8::Object;
@@ -372,7 +376,8 @@ void SyncProcessRunner::Spawn(const FunctionCallbackInfo<Value>& args) {
372
376
Environment* env = Environment::GetCurrent (args);
373
377
env->PrintSyncTrace ();
374
378
SyncProcessRunner p (env);
375
- Local<Value> result = p.Run (args[0 ]);
379
+ Local<Value> result;
380
+ if (!p.Run (args[0 ]).ToLocal (&result)) return ;
376
381
args.GetReturnValue ().Set (result);
377
382
}
378
383
@@ -430,22 +435,21 @@ Environment* SyncProcessRunner::env() const {
430
435
return env_;
431
436
}
432
437
433
-
434
- Local<Object> SyncProcessRunner::Run (Local<Value> options) {
438
+ MaybeLocal<Object> SyncProcessRunner::Run (Local<Value> options) {
435
439
EscapableHandleScope scope (env ()->isolate ());
436
440
437
441
CHECK_EQ (lifecycle_, kUninitialized );
438
442
439
- TryInitializeAndRunLoop (options);
443
+ Maybe< bool > r = TryInitializeAndRunLoop (options);
440
444
CloseHandlesAndDeleteLoop ();
445
+ if (r.IsNothing ()) return MaybeLocal<Object>();
441
446
442
447
Local<Object> result = BuildResultObject ();
443
448
444
449
return scope.Escape (result);
445
450
}
446
451
447
-
448
- void SyncProcessRunner::TryInitializeAndRunLoop (Local<Value> options) {
452
+ Maybe<bool > SyncProcessRunner::TryInitializeAndRunLoop (Local<Value> options) {
449
453
int r;
450
454
451
455
// There is no recovery from failure inside TryInitializeAndRunLoop - the
@@ -454,18 +458,24 @@ void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
454
458
lifecycle_ = kInitialized ;
455
459
456
460
uv_loop_ = new uv_loop_t ;
457
- if (uv_loop_ == nullptr )
458
- return SetError (UV_ENOMEM);
461
+ if (uv_loop_ == nullptr ) {
462
+ SetError (UV_ENOMEM);
463
+ return Just (false );
464
+ }
459
465
CHECK_EQ (uv_loop_init (uv_loop_), 0 );
460
466
461
- r = ParseOptions (options);
462
- if (r < 0 )
463
- return SetError (r);
467
+ if (!ParseOptions (options).To (&r)) return Nothing<bool >();
468
+ if (r < 0 ) {
469
+ SetError (r);
470
+ return Just (false );
471
+ }
464
472
465
473
if (timeout_ > 0 ) {
466
474
r = uv_timer_init (uv_loop_, &uv_timer_);
467
- if (r < 0 )
468
- return SetError (r);
475
+ if (r < 0 ) {
476
+ SetError (r);
477
+ return Just (false );
478
+ }
469
479
470
480
uv_unref (reinterpret_cast <uv_handle_t *>(&uv_timer_));
471
481
@@ -477,22 +487,28 @@ void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
477
487
// which implicitly stops it, so there is no risk that the timeout callback
478
488
// runs when the process didn't start.
479
489
r = uv_timer_start (&uv_timer_, KillTimerCallback, timeout_, 0 );
480
- if (r < 0 )
481
- return SetError (r);
490
+ if (r < 0 ) {
491
+ SetError (r);
492
+ return Just (false );
493
+ }
482
494
}
483
495
484
496
uv_process_options_.exit_cb = ExitCallback;
485
497
r = uv_spawn (uv_loop_, &uv_process_, &uv_process_options_);
486
- if (r < 0 )
487
- return SetError (r);
498
+ if (r < 0 ) {
499
+ SetError (r);
500
+ return Just (false );
501
+ }
488
502
uv_process_.data = this ;
489
503
490
504
for (uint32_t i = 0 ; i < stdio_count_; i++) {
491
505
SyncProcessStdioPipe* h = stdio_pipes_[i].get ();
492
506
if (h != nullptr ) {
493
507
r = h->Start ();
494
- if (r < 0 )
495
- return SetPipeError (r);
508
+ if (r < 0 ) {
509
+ SetPipeError (r);
510
+ return Just (false );
511
+ }
496
512
}
497
513
}
498
514
@@ -503,6 +519,7 @@ void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
503
519
504
520
// If we get here the process should have exited.
505
521
CHECK_GE (exit_status_, 0 );
522
+ return Just (true );
506
523
}
507
524
508
525
@@ -724,46 +741,41 @@ Local<Array> SyncProcessRunner::BuildOutputArray() {
724
741
return scope.Escape (js_output);
725
742
}
726
743
727
-
728
- int SyncProcessRunner::ParseOptions (Local<Value> js_value) {
744
+ Maybe<int > SyncProcessRunner::ParseOptions (Local<Value> js_value) {
729
745
HandleScope scope (env ()->isolate ());
730
746
int r;
731
747
732
- if (!js_value->IsObject ())
733
- return UV_EINVAL;
748
+ if (!js_value->IsObject ()) return Just<int >(UV_EINVAL);
734
749
735
750
Local<Context> context = env ()->context ();
736
751
Local<Object> js_options = js_value.As <Object>();
737
752
738
753
Local<Value> js_file =
739
754
js_options->Get (context, env ()->file_string ()).ToLocalChecked ();
740
- r = CopyJsString (js_file, &file_buffer_);
741
- if (r < 0 )
742
- return r;
755
+ if (!CopyJsString (js_file, &file_buffer_).To (&r)) return Nothing<int >();
756
+ if (r < 0 ) return Just (r);
743
757
uv_process_options_.file = file_buffer_;
744
758
745
759
Local<Value> js_args =
746
760
js_options->Get (context, env ()->args_string ()).ToLocalChecked ();
747
- r = CopyJsStringArray (js_args, &args_buffer_);
748
- if (r < 0 )
749
- return r;
761
+ if (!CopyJsStringArray (js_args, &args_buffer_).To (&r)) return Nothing<int >();
762
+ if (r < 0 ) return Just (r);
750
763
uv_process_options_.args = reinterpret_cast <char **>(args_buffer_);
751
764
752
765
Local<Value> js_cwd =
753
766
js_options->Get (context, env ()->cwd_string ()).ToLocalChecked ();
754
767
if (IsSet (js_cwd)) {
755
- r = CopyJsString (js_cwd, &cwd_buffer_);
756
- if (r < 0 )
757
- return r;
768
+ if (!CopyJsString (js_cwd, &cwd_buffer_).To (&r)) return Nothing<int >();
769
+ if (r < 0 ) return Just (r);
758
770
uv_process_options_.cwd = cwd_buffer_;
759
771
}
760
772
761
773
Local<Value> js_env_pairs =
762
774
js_options->Get (context, env ()->env_pairs_string ()).ToLocalChecked ();
763
775
if (IsSet (js_env_pairs)) {
764
- r = CopyJsStringArray (js_env_pairs, &env_buffer_);
765
- if (r < 0 )
766
- return r ;
776
+ if (! CopyJsStringArray (js_env_pairs, &env_buffer_). To (&r))
777
+ return Nothing< int >();
778
+ if (r < 0 ) return Just (r) ;
767
779
768
780
uv_process_options_.env = reinterpret_cast <char **>(env_buffer_);
769
781
}
@@ -827,10 +839,9 @@ int SyncProcessRunner::ParseOptions(Local<Value> js_value) {
827
839
Local<Value> js_stdio =
828
840
js_options->Get (context, env ()->stdio_string ()).ToLocalChecked ();
829
841
r = ParseStdioOptions (js_stdio);
830
- if (r < 0 )
831
- return r;
842
+ if (r < 0 ) return Just (r);
832
843
833
- return 0 ;
844
+ return Just ( 0 ) ;
834
845
}
835
846
836
847
@@ -970,44 +981,43 @@ bool SyncProcessRunner::IsSet(Local<Value> value) {
970
981
return !value->IsUndefined () && !value->IsNull ();
971
982
}
972
983
973
-
974
- int SyncProcessRunner::CopyJsString (Local<Value> js_value,
975
- const char ** target) {
984
+ Maybe<int > SyncProcessRunner::CopyJsString (Local<Value> js_value,
985
+ const char ** target) {
976
986
Isolate* isolate = env ()->isolate ();
977
987
Local<String> js_string;
978
988
size_t size, written;
979
989
char * buffer;
980
990
981
991
if (js_value->IsString ())
982
992
js_string = js_value.As <String>();
983
- else
984
- js_string = js_value-> ToString ( env ()-> isolate ()-> GetCurrentContext ( ))
985
- . ToLocalChecked ();
993
+ else if (!js_value-> ToString ( env ()-> isolate ()-> GetCurrentContext ())
994
+ . ToLocal (&js_string ))
995
+ return Nothing< int > ();
986
996
987
997
// Include space for null terminator byte.
988
- size = StringBytes::StorageSize (isolate, js_string, UTF8) + 1 ;
998
+ if (!StringBytes::StorageSize (isolate, js_string, UTF8).To (&size))
999
+ return Nothing<int >();
1000
+ size += 1 ;
989
1001
990
1002
buffer = new char [size];
991
1003
992
1004
written = StringBytes::Write (isolate, buffer, -1 , js_string, UTF8);
993
1005
buffer[written] = ' \0 ' ;
994
1006
995
1007
*target = buffer;
996
- return 0 ;
1008
+ return Just ( 0 ) ;
997
1009
}
998
1010
999
-
1000
- int SyncProcessRunner::CopyJsStringArray (Local<Value> js_value,
1001
- char ** target) {
1011
+ Maybe<int > SyncProcessRunner::CopyJsStringArray (Local<Value> js_value,
1012
+ char ** target) {
1002
1013
Isolate* isolate = env ()->isolate ();
1003
1014
Local<Array> js_array;
1004
1015
uint32_t length;
1005
1016
size_t list_size, data_size, data_offset;
1006
1017
char ** list;
1007
1018
char * buffer;
1008
1019
1009
- if (!js_value->IsArray ())
1010
- return UV_EINVAL;
1020
+ if (!js_value->IsArray ()) return Just<int >(UV_EINVAL);
1011
1021
1012
1022
Local<Context> context = env ()->context ();
1013
1023
js_array = js_value.As <Array>()->Clone ().As <Array>();
@@ -1025,15 +1035,22 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
1025
1035
for (uint32_t i = 0 ; i < length; i++) {
1026
1036
auto value = js_array->Get (context, i).ToLocalChecked ();
1027
1037
1028
- if (!value->IsString ())
1038
+ if (!value->IsString ()) {
1039
+ Local<String> string;
1040
+ if (!value->ToString (env ()->isolate ()->GetCurrentContext ())
1041
+ .ToLocal (&string))
1042
+ return Nothing<int >();
1029
1043
js_array
1030
1044
->Set (context,
1031
1045
i,
1032
1046
value->ToString (env ()->isolate ()->GetCurrentContext ())
1033
1047
.ToLocalChecked ())
1034
1048
.FromJust ();
1049
+ }
1035
1050
1036
- data_size += StringBytes::StorageSize (isolate, value, UTF8) + 1 ;
1051
+ Maybe<size_t > maybe_size = StringBytes::StorageSize (isolate, value, UTF8);
1052
+ if (maybe_size.IsNothing ()) return Nothing<int >();
1053
+ data_size += maybe_size.FromJust () + 1 ;
1037
1054
data_size = ROUND_UP (data_size, sizeof (void *));
1038
1055
}
1039
1056
@@ -1057,7 +1074,7 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
1057
1074
list[length] = nullptr ;
1058
1075
1059
1076
*target = buffer;
1060
- return 0 ;
1077
+ return Just ( 0 ) ;
1061
1078
}
1062
1079
1063
1080
0 commit comments