| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 09ae62b commit 7b1e153
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -80,8 +80,11 @@ const { | |||
| 80 | 80 | validateInteger, | |
| 81 | 81 | } = require('internal/validators'); | |
| 82 | 82 | const { | |
| 83 | - exiting_aliased_Uint32Array, | ||
| 83 | + exit_info_private_symbol, | ||
| 84 | 84 | getHiddenValue, | |
| 85 | + kExitCode, | ||
| 86 | + kExiting, | ||
| 87 | + kHasExitCode, | ||
| 85 | 88 | } = internalBinding('util'); | |
| 86 | 89 | ||
| 87 | 90 | setupProcessObject(); | |
@@ -90,26 +93,24 @@ setupGlobalProxy(); | |||
| 90 | 93 | setupBuffer(); | |
| 91 | 94 | ||
| 92 | 95 | process.domain = null; | |
| 96 | + | ||
| 97 | + // process._exiting and process.exitCode | ||
| 93 | 98 | { | |
| 94 | - const exitingAliasedUint32Array = | ||
| 95 | - getHiddenValue(process, exiting_aliased_Uint32Array); | ||
| 99 | + const fields = getHiddenValue(process, exit_info_private_symbol); | ||
| 100 | + | ||
| 96 | 101 | ObjectDefineProperty(process, '_exiting', { | |
| 97 | 102 | __proto__: null, | |
| 98 | 103 | get() { | |
| 99 | - return exitingAliasedUint32Array[0] === 1; | ||
| 104 | + return fields[kExiting] === 1; | ||
| 100 | 105 | }, | |
| 101 | 106 | set(value) { | |
| 102 | - exitingAliasedUint32Array[0] = value ? 1 : 0; | ||
| 107 | + fields[kExiting] = value ? 1 : 0; | ||
| 103 | 108 | }, | |
| 104 | 109 | enumerable: true, | |
| 105 | 110 | configurable: true, | |
| 106 | 111 | }); | |
| 107 | - } | ||
| 108 | - process._exiting = false; | ||
| 109 | 112 | ||
| 110 | - { | ||
| 111 | 113 | let exitCode; | |
| 112 | - | ||
| 113 | 114 | ObjectDefineProperty(process, 'exitCode', { | |
| 114 | 115 | __proto__: null, | |
| 115 | 116 | get() { | |
@@ -123,13 +124,18 @@ process._exiting = false; | |||
| 123 | 124 | value = code; | |
| 124 | 125 | } | |
| 125 | 126 | validateInteger(value, 'code'); | |
| 127 | + fields[kExitCode] = value; | ||
| 128 | + fields[kHasExitCode] = 1; | ||
| 129 | + } else { | ||
| 130 | + fields[kHasExitCode] = 0; | ||
| 126 | 131 | } | |
| 127 | 132 | exitCode = code; | |
| 128 | 133 | }, | |
| 129 | 134 | enumerable: true, | |
| 130 | 135 | configurable: false, | |
| 131 | 136 | }); | |
| 132 | 137 | } | |
| 138 | + process._exiting = false; | ||
| 133 | 139 | ||
| 134 | 140 | // process.config is serialized config.gypi | |
| 135 | 141 | const nativeModule = internalBinding('builtins'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,7 +16,6 @@ using v8::NewStringType; | |||
| 16 | 16 | using v8::Nothing; | |
| 17 | 17 | using v8::Object; | |
| 18 | 18 | using v8::String; | |
| 19 | - using v8::Value; | ||
| 20 | 19 | ||
| 21 | 20 | void RunAtExit(Environment* env) { | |
| 22 | 21 | env->RunAtExitCallbacks(); | |
@@ -36,19 +35,17 @@ Maybe<bool> EmitProcessBeforeExit(Environment* env) { | |||
| 36 | 35 | if (!env->destroy_async_id_list()->empty()) | |
| 37 | 36 | AsyncWrap::DestroyAsyncIdsCallback(env); | |
| 38 | 37 | ||
| 39 | - HandleScope handle_scope(env->isolate()); | ||
| 40 | - Local<Context> context = env->context(); | ||
| 41 | - Context::Scope context_scope(context); | ||
| 42 | - | ||
| 43 | - Local<Value> exit_code_v; | ||
| 44 | - if (!env->process_object()->Get(context, env->exit_code_string()) | ||
| 45 | - .ToLocal(&exit_code_v)) return Nothing<bool>(); | ||
| 38 | + Isolate* isolate = env->isolate(); | ||
| 39 | + HandleScope handle_scope(isolate); | ||
| 40 | + Context::Scope context_scope(env->context()); | ||
| 46 | 41 | ||
| 47 | - Local<Integer> exit_code; | ||
| 48 | - if (!exit_code_v->ToInteger(context).ToLocal(&exit_code)) { | ||
| 42 | + if (!env->can_call_into_js()) { | ||
| 49 | 43 | return Nothing<bool>(); | |
| 50 | 44 | } | |
| 51 | 45 | ||
| 46 | + Local<Integer> exit_code = Integer::New( | ||
| 47 | + isolate, static_cast<int32_t>(env->exit_code(ExitCode::kNoFailure))); | ||
| 48 | + | ||
| 52 | 49 | return ProcessEmit(env, "beforeExit", exit_code).IsEmpty() ? | |
| 53 | 50 | Nothing<bool>() : Just(true); | |
| 54 | 51 | } | |
@@ -65,29 +62,22 @@ Maybe<ExitCode> EmitProcessExitInternal(Environment* env) { | |||
| 65 | 62 | // process.emit('exit') | |
| 66 | 63 | Isolate* isolate = env->isolate(); | |
| 67 | 64 | HandleScope handle_scope(isolate); | |
| 68 | - Local<Context> context = env->context(); | ||
| 69 | - Context::Scope context_scope(context); | ||
| 70 | - Local<Object> process_object = env->process_object(); | ||
| 71 | - | ||
| 72 | - // TODO(addaleax): It might be nice to share process.exitCode via | ||
| 73 | - // getter/setter pairs that pass data directly to the native side, so that we | ||
| 74 | - // don't manually have to read and write JS properties here. These getters | ||
| 75 | - // could use e.g. a typed array for performance. | ||
| 65 | + Context::Scope context_scope(env->context()); | ||
| 66 | + | ||
| 76 | 67 | env->set_exiting(true); | |
| 77 | 68 | ||
| 78 | - Local<String> exit_code = env->exit_code_string(); | ||
| 79 | - Local<Value> code_v; | ||
| 80 | - int code; | ||
| 81 | - if (!process_object->Get(context, exit_code).ToLocal(&code_v) || | ||
| 82 | - !code_v->Int32Value(context).To(&code) || | ||
| 83 | - ProcessEmit(env, "exit", Integer::New(isolate, code)).IsEmpty() || | ||
| 84 | - // Reload exit code, it may be changed by `emit('exit')` | ||
| 85 | - !process_object->Get(context, exit_code).ToLocal(&code_v) || | ||
| 86 | - !code_v->Int32Value(context).To(&code)) { | ||
| 69 | + if (!env->can_call_into_js()) { | ||
| 87 | 70 | return Nothing<ExitCode>(); | |
| 88 | 71 | } | |
| 89 | 72 | ||
| 90 | - return Just(static_cast<ExitCode>(code)); | ||
| 73 | + Local<Integer> exit_code = Integer::New( | ||
| 74 | + isolate, static_cast<int32_t>(env->exit_code(ExitCode::kNoFailure))); | ||
| 75 | + | ||
| 76 | + if (ProcessEmit(env, "exit", exit_code).IsEmpty()) { | ||
| 77 | + return Nothing<ExitCode>(); | ||
| 78 | + } | ||
| 79 | + // Reload exit code, it may be changed by `emit('exit')` | ||
| 80 | + return Just(env->exit_code(ExitCode::kNoFailure)); | ||
| 91 | 81 | } | |
| 92 | 82 | ||
| 93 | 83 | Maybe<int> EmitProcessExit(Environment* env) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -364,11 +364,17 @@ inline bool Environment::force_context_aware() const { | |||
| 364 | 364 | } | |
| 365 | 365 | ||
| 366 | 366 | inline void Environment::set_exiting(bool value) { | |
| 367 | - exiting_[0] = value ? 1 : 0; | ||
| 367 | + exit_info_[kExiting] = value ? 1 : 0; | ||
| 368 | 368 | } | |
| 369 | 369 | ||
| 370 | - inline AliasedUint32Array& Environment::exiting() { | ||
| 371 | - return exiting_; | ||
| 370 | + inline ExitCode Environment::exit_code(const ExitCode default_code) const { | ||
| 371 | + return exit_info_[kHasExitCode] == 0 | ||
| 372 | + ? default_code | ||
| 373 | + : static_cast<ExitCode>(exit_info_[kExitCode]); | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + inline AliasedInt32Array& Environment::exit_info() { | ||
| 377 | + return exit_info_; | ||
| 372 | 378 | } | |
| 373 | 379 | ||
| 374 | 380 | inline void Environment::set_abort_on_uncaught_exception(bool value) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -655,7 +655,8 @@ Environment::Environment(IsolateData* isolate_data, | |||
| 655 | 655 | exec_argv_(exec_args), | |
| 656 | 656 | argv_(args), | |
| 657 | 657 | exec_path_(GetExecPath(args)), | |
| 658 | - exiting_(isolate_, 1, MAYBE_FIELD_PTR(env_info, exiting)), | ||
| 658 | + exit_info_( | ||
| 659 | + isolate_, kExitInfoFieldCount, MAYBE_FIELD_PTR(env_info, exit_info)), | ||
| 659 | 660 | should_abort_on_uncaught_toggle_( | |
| 660 | 661 | isolate_, | |
| 661 | 662 | 1, | |
@@ -1608,7 +1609,7 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) { | |||
| 1608 | 1609 | info.immediate_info = immediate_info_.Serialize(ctx, creator); | |
| 1609 | 1610 | info.tick_info = tick_info_.Serialize(ctx, creator); | |
| 1610 | 1611 | info.performance_state = performance_state_->Serialize(ctx, creator); | |
| 1611 | - info.exiting = exiting_.Serialize(ctx, creator); | ||
| 1612 | + info.exit_info = exit_info_.Serialize(ctx, creator); | ||
| 1612 | 1613 | info.stream_base_state = stream_base_state_.Serialize(ctx, creator); | |
| 1613 | 1614 | info.should_abort_on_uncaught_toggle = | |
| 1614 | 1615 | should_abort_on_uncaught_toggle_.Serialize(ctx, creator); | |
@@ -1654,7 +1655,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) { | |||
| 1654 | 1655 | immediate_info_.Deserialize(ctx); | |
| 1655 | 1656 | tick_info_.Deserialize(ctx); | |
| 1656 | 1657 | performance_state_->Deserialize(ctx); | |
| 1657 | - exiting_.Deserialize(ctx); | ||
| 1658 | + exit_info_.Deserialize(ctx); | ||
| 1658 | 1659 | stream_base_state_.Deserialize(ctx); | |
| 1659 | 1660 | should_abort_on_uncaught_toggle_.Deserialize(ctx); | |
| 1660 | 1661 | ||
@@ -1844,7 +1845,7 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const { | |||
| 1844 | 1845 | tracker->TrackField("builtins_without_cache", builtins_without_cache); | |
| 1845 | 1846 | tracker->TrackField("destroy_async_id_list", destroy_async_id_list_); | |
| 1846 | 1847 | tracker->TrackField("exec_argv", exec_argv_); | |
| 1847 | - tracker->TrackField("exiting", exiting_); | ||
| 1848 | + tracker->TrackField("exit_info", exit_info_); | ||
| 1848 | 1849 | tracker->TrackField("should_abort_on_uncaught_toggle", | |
| 1849 | 1850 | should_abort_on_uncaught_toggle_); | |
| 1850 | 1851 | tracker->TrackField("stream_base_state", stream_base_state_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -510,7 +510,7 @@ struct EnvSerializeInfo { | |||
| 510 | 510 | TickInfo::SerializeInfo tick_info; | |
| 511 | 511 | ImmediateInfo::SerializeInfo immediate_info; | |
| 512 | 512 | performance::PerformanceState::SerializeInfo performance_state; | |
| 513 | - AliasedBufferIndex exiting; | ||
| 513 | + AliasedBufferIndex exit_info; | ||
| 514 | 514 | AliasedBufferIndex stream_base_state; | |
| 515 | 515 | AliasedBufferIndex should_abort_on_uncaught_toggle; | |
| 516 | 516 | ||
@@ -743,10 +743,12 @@ class Environment : public MemoryRetainer { | |||
| 743 | 743 | inline void set_force_context_aware(bool value); | |
| 744 | 744 | inline bool force_context_aware() const; | |
| 745 | 745 | ||
| 746 | - // This is a pseudo-boolean that keeps track of whether the process is | ||
| 747 | - // exiting. | ||
| 746 | + // This contains fields that are a pseudo-boolean that keeps track of whether | ||
| 747 | + // the process is exiting, an integer representing the process exit code, and | ||
| 748 | + // a pseudo-boolean to indicate whether the exit code is undefined. | ||
| 749 | + inline AliasedInt32Array& exit_info(); | ||
| 748 | 750 | inline void set_exiting(bool value); | |
| 749 | - inline AliasedUint32Array& exiting(); | ||
| 751 | + inline ExitCode exit_code(const ExitCode default_code) const; | ||
| 750 | 752 | ||
| 751 | 753 | // This stores whether the --abort-on-uncaught-exception flag was passed | |
| 752 | 754 | // to Node. | |
@@ -1038,6 +1040,14 @@ class Environment : public MemoryRetainer { | |||
| 1038 | 1040 | ||
| 1039 | 1041 | inline void RemoveHeapSnapshotNearHeapLimitCallback(size_t heap_limit); | |
| 1040 | 1042 | ||
| 1043 | + // Field identifiers for exit_info_ | ||
| 1044 | + enum ExitInfoField { | ||
| 1045 | + kExiting = 0, | ||
| 1046 | + kExitCode, | ||
| 1047 | + kHasExitCode, | ||
| 1048 | + kExitInfoFieldCount | ||
| 1049 | + }; | ||
| 1050 | + | ||
| 1041 | 1051 | private: | |
| 1042 | 1052 | inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), | |
| 1043 | 1053 | const char* errmsg); | |
@@ -1103,7 +1113,7 @@ class Environment : public MemoryRetainer { | |||
| 1103 | 1113 | uint32_t script_id_counter_ = 0; | |
| 1104 | 1114 | uint32_t function_id_counter_ = 0; | |
| 1105 | 1115 | ||
| 1106 | - AliasedUint32Array exiting_; | ||
| 1116 | + AliasedInt32Array exit_info_; | ||
| 1107 | 1117 | ||
| 1108 | 1118 | AliasedUint32Array should_abort_on_uncaught_toggle_; | |
| 1109 | 1119 | int should_not_abort_scope_counter_ = 0; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,7 @@ | |||
| 24 | 24 | V(napi_type_tag, "node:napi:type_tag") \ | |
| 25 | 25 | V(napi_wrapper, "node:napi:wrapper") \ | |
| 26 | 26 | V(untransferable_object_private_symbol, "node:untransferableObject") \ | |
| 27 | - V(exiting_aliased_Uint32Array, "node:exiting_aliased_Uint32Array") | ||
| 27 | + V(exit_info_private_symbol, "node:exit_info_private_symbol") | ||
| 28 | 28 | ||
| 29 | 29 | // Symbols are per-isolate primitives but Environment proxies them | |
| 30 | 30 | // for the sake of convenience. | |
@@ -114,7 +114,6 @@ | |||
| 114 | 114 | V(errno_string, "errno") \ | |
| 115 | 115 | V(error_string, "error") \ | |
| 116 | 116 | V(exchange_string, "exchange") \ | |
| 117 | - V(exit_code_string, "exitCode") \ | ||
| 118 | 117 | V(expire_string, "expire") \ | |
| 119 | 118 | V(exponent_string, "exponent") \ | |
| 120 | 119 | V(exports_string, "exports") \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1151,15 +1151,8 @@ void TriggerUncaughtException(Isolate* isolate, | |||
| 1151 | 1151 | RunAtExit(env); | |
| 1152 | 1152 | ||
| 1153 | 1153 | // If the global uncaught exception handler sets process.exitCode, | |
| 1154 | - // exit with that code. Otherwise, exit with 1. | ||
| 1155 | - Local<String> exit_code = env->exit_code_string(); | ||
| 1156 | - Local<Value> code; | ||
| 1157 | - if (process_object->Get(env->context(), exit_code).ToLocal(&code) && | ||
| 1158 | - code->IsInt32()) { | ||
| 1159 | - env->Exit(static_cast<ExitCode>(code.As<Int32>()->Value())); | ||
| 1160 | - } else { | ||
| 1161 | - env->Exit(ExitCode::kGenericUserError); | ||
| 1162 | - } | ||
| 1154 | + // exit with that code. Otherwise, exit with `ExitCode::kGenericUserError`. | ||
| 1155 | + env->Exit(env->exit_code(ExitCode::kGenericUserError)); | ||
| 1163 | 1156 | } | |
| 1164 | 1157 | ||
| 1165 | 1158 | void TriggerUncaughtException(Isolate* isolate, const v8::TryCatch& try_catch) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -92,11 +92,11 @@ MaybeLocal<Object> CreateProcessObject(Realm* realm) { | |||
| 92 | 92 | return MaybeLocal<Object>(); | |
| 93 | 93 | } | |
| 94 | 94 | ||
| 95 | - // process[exiting_aliased_Uint32Array] | ||
| 95 | + // process[exit_info_private_symbol] | ||
| 96 | 96 | if (process | |
| 97 | 97 | ->SetPrivate(context, | |
| 98 | - realm->env()->exiting_aliased_Uint32Array(), | ||
| 99 | - realm->env()->exiting().GetJSArray()) | ||
| 98 | + realm->env()->exit_info_private_symbol(), | ||
| 99 | + realm->env()->exit_info().GetJSArray()) | ||
| 100 | 100 | .IsNothing()) { | |
| 101 | 101 | return {}; | |
| 102 | 102 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -123,7 +123,7 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) { | |||
| 123 | 123 | << "// -- performance_state begins --\n" | |
| 124 | 124 | << i.performance_state << ",\n" | |
| 125 | 125 | << "// -- performance_state ends --\n" | |
| 126 | - << i.exiting << ", // exiting\n" | ||
| 126 | + << i.exit_info << ", // exit_info\n" | ||
| 127 | 127 | << i.stream_base_state << ", // stream_base_state\n" | |
| 128 | 128 | << i.should_abort_on_uncaught_toggle | |
| 129 | 129 | << ", // should_abort_on_uncaught_toggle\n" | |
@@ -736,7 +736,7 @@ EnvSerializeInfo FileReader::Read() { | |||
| 736 | 736 | result.immediate_info = Read<ImmediateInfo::SerializeInfo>(); | |
| 737 | 737 | result.performance_state = | |
| 738 | 738 | Read<performance::PerformanceState::SerializeInfo>(); | |
| 739 | - result.exiting = Read<AliasedBufferIndex>(); | ||
| 739 | + result.exit_info = Read<AliasedBufferIndex>(); | ||
| 740 | 740 | result.stream_base_state = Read<AliasedBufferIndex>(); | |
| 741 | 741 | result.should_abort_on_uncaught_toggle = Read<AliasedBufferIndex>(); | |
| 742 | 742 | result.principal_realm = Read<RealmSerializeInfo>(); | |
@@ -757,7 +757,7 @@ size_t FileWriter::Write(const EnvSerializeInfo& data) { | |||
| 757 | 757 | written_total += Write<ImmediateInfo::SerializeInfo>(data.immediate_info); | |
| 758 | 758 | written_total += Write<performance::PerformanceState::SerializeInfo>( | |
| 759 | 759 | data.performance_state); | |
| 760 | - written_total += Write<AliasedBufferIndex>(data.exiting); | ||
| 760 | + written_total += Write<AliasedBufferIndex>(data.exit_info); | ||
| 761 | 761 | written_total += Write<AliasedBufferIndex>(data.stream_base_state); | |
| 762 | 762 | written_total += | |
| 763 | 763 | Write<AliasedBufferIndex>(data.should_abort_on_uncaught_toggle); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -424,6 +424,17 @@ void Initialize(Local<Object> target, | |||
| 424 | 424 | V(kRejected); | |
| 425 | 425 | #undef V | |
| 426 | 426 | ||
| 427 | + #define V(name) \ | ||
| 428 | + target \ | ||
| 429 | + ->Set(context, \ | ||
| 430 | + FIXED_ONE_BYTE_STRING(env->isolate(), #name), \ | ||
| 431 | + Integer::New(env->isolate(), Environment::ExitInfoField::name)) \ | ||
| 432 | + .FromJust() | ||
| 433 | + V(kExiting); | ||
| 434 | + V(kExitCode); | ||
| 435 | + V(kHasExitCode); | ||
| 436 | + #undef V | ||
| 437 | + | ||
| 427 | 438 | SetMethodNoSideEffect(context, target, "getHiddenValue", GetHiddenValue); | |
| 428 | 439 | SetMethod(context, target, "setHiddenValue", SetHiddenValue); | |
| 429 | 440 | SetMethodNoSideEffect( | |
| Back | FazBrowse Home | New Git URL |
0 commit comments