src: refactor node options parsers to mitigate MSVC bug · nodejs/node@62f9049 (original) (raw)

`@@ -111,19 +111,60 @@ void EnvironmentOptions::CheckOptions(std::vectorstd::string* errors) {

`

111

111

``

112

112

`namespace options_parser {

`

113

113

``

114

``

`-

// Explicitly access the singelton instances in their dependancy order.

`

115

``

`-

// This was moved here to workaround a compiler bug.

`

116

``

`-

// Refs: https://github.com/nodejs/node/issues/25593

`

``

114

`+

class DebugOptionsParser : public OptionsParser {

`

``

115

`+

public:

`

``

116

`+

DebugOptionsParser();

`

``

117

`+

};

`

``

118

+

``

119

`+

class EnvironmentOptionsParser : public OptionsParser {

`

``

120

`+

public:

`

``

121

`+

EnvironmentOptionsParser();

`

``

122

`+

explicit EnvironmentOptionsParser(const DebugOptionsParser& dop)

`

``

123

`+

: EnvironmentOptionsParser() {

`

``

124

`+

Insert(&dop, &EnvironmentOptions::get_debug_options);

`

``

125

`+

}

`

``

126

`+

};

`

117

127

``

118

``

`-

#if HAVE_INSPECTOR

`

119

``

`-

const DebugOptionsParser DebugOptionsParser::instance;

`

120

``

`-

#endif // HAVE_INSPECTOR

`

``

128

`+

class PerIsolateOptionsParser : public OptionsParser {

`

``

129

`+

public:

`

``

130

`+

PerIsolateOptionsParser() = delete;

`

``

131

`+

explicit PerIsolateOptionsParser(const EnvironmentOptionsParser& eop);

`

``

132

`+

};

`

121

133

``

122

``

`-

const EnvironmentOptionsParser EnvironmentOptionsParser::instance;

`

``

134

`+

class PerProcessOptionsParser : public OptionsParser {

`

``

135

`+

public:

`

``

136

`+

PerProcessOptionsParser() = delete;

`

``

137

`+

explicit PerProcessOptionsParser(const PerIsolateOptionsParser& iop);

`

``

138

`+

};

`

123

139

``

124

``

`-

const PerIsolateOptionsParser PerIsolateOptionsParser::instance;

`

``

140

`+

#if HAVE_INSPECTOR

`

``

141

`+

const DebugOptionsParser _dop_instance{};

`

``

142

`+

const EnvironmentOptionsParser _eop_instance{_dop_instance};

`

``

143

`+

#else

`

``

144

`+

const EnvironmentOptionsParser _eop_instance{};

`

``

145

`+

#endif // HAVE_INSPECTOR

`

``

146

`+

const PerIsolateOptionsParser _piop_instance{_eop_instance};

`

``

147

`+

const PerProcessOptionsParser _ppop_instance{_piop_instance};

`

``

148

+

``

149

`+

template <>

`

``

150

`+

void Parse(

`

``

151

`+

StringVector* const args, StringVector* const exec_args,

`

``

152

`+

StringVector* const v8_args,

`

``

153

`+

PerIsolateOptions* const options,

`

``

154

`+

OptionEnvvarSettings required_env_settings, StringVector* const errors) {

`

``

155

`+

_piop_instance.Parse(

`

``

156

`+

args, exec_args, v8_args, options, required_env_settings, errors);

`

``

157

`+

}

`

125

158

``

126

``

`-

const PerProcessOptionsParser PerProcessOptionsParser::instance;

`

``

159

`+

template <>

`

``

160

`+

void Parse(

`

``

161

`+

StringVector* const args, StringVector* const exec_args,

`

``

162

`+

StringVector* const v8_args,

`

``

163

`+

PerProcessOptions* const options,

`

``

164

`+

OptionEnvvarSettings required_env_settings, StringVector* const errors) {

`

``

165

`+

_ppop_instance.Parse(

`

``

166

`+

args, exec_args, v8_args, options, required_env_settings, errors);

`

``

167

`+

}

`

127

168

``

128

169

`// XXX: If you add an option here, please also add it to doc/node.1 and

`

129

170

`// doc/api/cli.md

`

`@@ -286,14 +327,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {

`

286

327

`AddAlias("-i", "--interactive");

`

287

328

``

288

329

`AddOption("--napi-modules", "", NoOp{}, kAllowedInEnvironment);

`

289

``

-

290

``

`-

#if HAVE_INSPECTOR

`

291

``

`-

Insert(&DebugOptionsParser::instance,

`

292

``

`-

&EnvironmentOptions::get_debug_options);

`

293

``

`-

#endif // HAVE_INSPECTOR

`

294

330

`}

`

295

331

``

296

``

`-

PerIsolateOptionsParser::PerIsolateOptionsParser() {

`

``

332

`+

PerIsolateOptionsParser::PerIsolateOptionsParser(

`

``

333

`+

const EnvironmentOptionsParser& eop) {

`

297

334

`AddOption("--track-heap-objects",

`

298

335

`"track heap object allocations for heap snapshots",

`

299

336

` &PerIsolateOptions::track_heap_objects,

`

`@@ -349,11 +386,11 @@ PerIsolateOptionsParser::PerIsolateOptionsParser() {

`

349

386

`kAllowedInEnvironment);

`

350

387

`#endif // NODE_REPORT

`

351

388

``

352

``

`-

Insert(&EnvironmentOptionsParser::instance,

`

353

``

`-

&PerIsolateOptions::get_per_env_options);

`

``

389

`+

Insert(&eop, &PerIsolateOptions::get_per_env_options);

`

354

390

`}

`

355

391

``

356

``

`-

PerProcessOptionsParser::PerProcessOptionsParser() {

`

``

392

`+

PerProcessOptionsParser::PerProcessOptionsParser(

`

``

393

`+

const PerIsolateOptionsParser& iop) {

`

357

394

`AddOption("--title",

`

358

395

`"the process title to use on startup",

`

359

396

` &PerProcessOptions::title,

`

`@@ -459,8 +496,7 @@ PerProcessOptionsParser::PerProcessOptionsParser() {

`

459

496

`#endif

`

460

497

`#endif

`

461

498

``

462

``

`-

Insert(&PerIsolateOptionsParser::instance,

`

463

``

`-

&PerProcessOptions::get_per_isolate_options);

`

``

499

`+

Insert(&iop, &PerProcessOptions::get_per_isolate_options);

`

464

500

`}

`

465

501

``

466

502

`inline std::string RemoveBrackets(const std::string& host) {

`

`@@ -526,10 +562,8 @@ void GetOptions(const FunctionCallbackInfo& args) {

`

526

562

` per_process::cli_options->per_isolate = original_per_isolate;

`

527

563

` });

`

528

564

``

529

``

`-

const auto& parser = PerProcessOptionsParser::instance;

`

530

``

-

531

565

` Local options = Map::New(isolate);

`

532

``

`-

for (const auto& item : parser.options_) {

`

``

566

`+

for (const auto& item : ppop_instance.options) {

`

533

567

` Local value;

`

534

568

`const auto& option_info = item.second;

`

535

569

`auto field = option_info.field;

`

`@@ -547,29 +581,34 @@ void GetOptions(const FunctionCallbackInfo& args) {

`

547

581

` }

`

548

582

`break;

`

549

583

`case kBoolean:

`

550

``

`-

value = Boolean::New(isolate, *parser.Lookup(field, opts));

`

``

584

`+

value = Boolean::New(isolate,

`

``

585

`+

*_ppop_instance.Lookup(field, opts));

`

551

586

`break;

`

552

587

`case kInteger:

`

553

``

`-

value = Number::New(isolate, *parser.Lookup(field, opts));

`

``

588

`+

value = Number::New(isolate,

`

``

589

`+

*_ppop_instance.Lookup(field, opts));

`

554

590

`break;

`

555

591

`case kUInteger:

`

556

``

`-

value = Number::New(isolate, *parser.Lookup(field, opts));

`

``

592

`+

value = Number::New(isolate,

`

``

593

`+

*_ppop_instance.Lookup(field, opts));

`

557

594

`break;

`

558

595

`case kString:

`

559

``

`-

if (!ToV8Value(context, *parser.Lookupstd::string(field, opts))

`

``

596

`+

if (!ToV8Value(context,

`

``

597

`+

*_ppop_instance.Lookupstd::string(field, opts))

`

560

598

` .ToLocal(&value)) {

`

561

599

`return;

`

562

600

` }

`

563

601

`break;

`

564

602

`case kStringList:

`

565

603

`if (!ToV8Value(context,

`

566

``

`-

*parser.Lookup<std::vectorstd::string>(field, opts))

`

``

604

`+

*_ppop_instance.Lookup(field, opts))

`

567

605

` .ToLocal(&value)) {

`

568

606

`return;

`

569

607

` }

`

570

608

`break;

`

571

609

`case kHostPort: {

`

572

``

`-

const HostPort& host_port = *parser.Lookup(field, opts);

`

``

610

`+

const HostPort& host_port =

`

``

611

`+

*_ppop_instance.Lookup(field, opts);

`

573

612

` Local obj = Object::New(isolate);

`

574

613

` Local host;

`

575

614

`if (!ToV8Value(context, host_port.host()).ToLocal(&host) ||

`

`@@ -610,7 +649,7 @@ void GetOptions(const FunctionCallbackInfo& args) {

`

610

649

` }

`

611

650

``

612

651

` Local aliases;

`

613

``

`-

if (!ToV8Value(context, parser.aliases_).ToLocal(&aliases)) return;

`

``

652

`+

if (!ToV8Value(context, ppop_instance.aliases).ToLocal(&aliases)) return;

`

614

653

``

615

654

` Local ret = Object::New(isolate);

`

616

655

`if (ret->Set(context, env->options_string(), options).IsNothing() ||

`