blob: f7ae004ac26e2bf7e80583b0c4e87b19fdddb5ca [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/flags.h"
6
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007#include <cctype>
8#include <cstdlib>
9#include <sstream>
Steve Blocka7e24c12009-10-30 11:49:00 +000010
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/allocation.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "src/assembler.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040013#include "src/base/functional.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014#include "src/base/platform/platform.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "src/list-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/ostreams.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017#include "src/utils.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000018
19namespace v8 {
20namespace internal {
21
22// Define all of our flags.
23#define FLAG_MODE_DEFINE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024#include "src/flag-definitions.h" // NOLINT(build/include)
Steve Blocka7e24c12009-10-30 11:49:00 +000025
26// Define all of our flags default values.
27#define FLAG_MODE_DEFINE_DEFAULTS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028#include "src/flag-definitions.h" // NOLINT(build/include)
Steve Blocka7e24c12009-10-30 11:49:00 +000029
30namespace {
31
32// This structure represents a single entry in the flag system, with a pointer
33// to the actual flag, default value, comment, etc. This is designed to be POD
34// initialized as to avoid requiring static constructors.
35struct Flag {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 enum FlagType { TYPE_BOOL, TYPE_MAYBE_BOOL, TYPE_INT, TYPE_FLOAT,
37 TYPE_STRING, TYPE_ARGS };
Steve Blocka7e24c12009-10-30 11:49:00 +000038
39 FlagType type_; // What type of flag, bool, int, or string.
40 const char* name_; // Name of the flag, ex "my_flag".
41 void* valptr_; // Pointer to the global flag variable.
42 const void* defptr_; // Pointer to the default value.
43 const char* cmt_; // A comment about the flags purpose.
44 bool owns_ptr_; // Does the flag own its string value?
45
46 FlagType type() const { return type_; }
47
48 const char* name() const { return name_; }
49
50 const char* comment() const { return cmt_; }
51
52 bool* bool_variable() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053 DCHECK(type_ == TYPE_BOOL);
Steve Blocka7e24c12009-10-30 11:49:00 +000054 return reinterpret_cast<bool*>(valptr_);
55 }
56
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 MaybeBoolFlag* maybe_bool_variable() const {
58 DCHECK(type_ == TYPE_MAYBE_BOOL);
59 return reinterpret_cast<MaybeBoolFlag*>(valptr_);
60 }
61
Steve Blocka7e24c12009-10-30 11:49:00 +000062 int* int_variable() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 DCHECK(type_ == TYPE_INT);
Steve Blocka7e24c12009-10-30 11:49:00 +000064 return reinterpret_cast<int*>(valptr_);
65 }
66
67 double* float_variable() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 DCHECK(type_ == TYPE_FLOAT);
Steve Blocka7e24c12009-10-30 11:49:00 +000069 return reinterpret_cast<double*>(valptr_);
70 }
71
72 const char* string_value() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073 DCHECK(type_ == TYPE_STRING);
Steve Blocka7e24c12009-10-30 11:49:00 +000074 return *reinterpret_cast<const char**>(valptr_);
75 }
76
77 void set_string_value(const char* value, bool owns_ptr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 DCHECK(type_ == TYPE_STRING);
Steve Blocka7e24c12009-10-30 11:49:00 +000079 const char** ptr = reinterpret_cast<const char**>(valptr_);
80 if (owns_ptr_ && *ptr != NULL) DeleteArray(*ptr);
81 *ptr = value;
82 owns_ptr_ = owns_ptr;
83 }
84
85 JSArguments* args_variable() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086 DCHECK(type_ == TYPE_ARGS);
Steve Blocka7e24c12009-10-30 11:49:00 +000087 return reinterpret_cast<JSArguments*>(valptr_);
88 }
89
90 bool bool_default() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 DCHECK(type_ == TYPE_BOOL);
Steve Blocka7e24c12009-10-30 11:49:00 +000092 return *reinterpret_cast<const bool*>(defptr_);
93 }
94
95 int int_default() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 DCHECK(type_ == TYPE_INT);
Steve Blocka7e24c12009-10-30 11:49:00 +000097 return *reinterpret_cast<const int*>(defptr_);
98 }
99
100 double float_default() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101 DCHECK(type_ == TYPE_FLOAT);
Steve Blocka7e24c12009-10-30 11:49:00 +0000102 return *reinterpret_cast<const double*>(defptr_);
103 }
104
105 const char* string_default() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106 DCHECK(type_ == TYPE_STRING);
Steve Blocka7e24c12009-10-30 11:49:00 +0000107 return *reinterpret_cast<const char* const *>(defptr_);
108 }
109
110 JSArguments args_default() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 DCHECK(type_ == TYPE_ARGS);
Steve Blocka7e24c12009-10-30 11:49:00 +0000112 return *reinterpret_cast<const JSArguments*>(defptr_);
113 }
114
115 // Compare this flag's current value against the default.
116 bool IsDefault() const {
117 switch (type_) {
118 case TYPE_BOOL:
119 return *bool_variable() == bool_default();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 case TYPE_MAYBE_BOOL:
121 return maybe_bool_variable()->has_value == false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 case TYPE_INT:
123 return *int_variable() == int_default();
124 case TYPE_FLOAT:
125 return *float_variable() == float_default();
126 case TYPE_STRING: {
127 const char* str1 = string_value();
128 const char* str2 = string_default();
129 if (str2 == NULL) return str1 == NULL;
130 if (str1 == NULL) return str2 == NULL;
131 return strcmp(str1, str2) == 0;
132 }
133 case TYPE_ARGS:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134 return args_variable()->argc == 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000135 }
136 UNREACHABLE();
137 return true;
138 }
139
140 // Set a flag back to it's default value.
141 void Reset() {
142 switch (type_) {
143 case TYPE_BOOL:
144 *bool_variable() = bool_default();
145 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146 case TYPE_MAYBE_BOOL:
147 *maybe_bool_variable() = MaybeBoolFlag::Create(false, false);
148 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000149 case TYPE_INT:
150 *int_variable() = int_default();
151 break;
152 case TYPE_FLOAT:
153 *float_variable() = float_default();
154 break;
155 case TYPE_STRING:
156 set_string_value(string_default(), false);
157 break;
158 case TYPE_ARGS:
159 *args_variable() = args_default();
160 break;
161 }
162 }
163};
164
165Flag flags[] = {
166#define FLAG_MODE_META
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167#include "src/flag-definitions.h" // NOLINT(build/include)
Steve Blocka7e24c12009-10-30 11:49:00 +0000168};
169
170const size_t num_flags = sizeof(flags) / sizeof(*flags);
171
172} // namespace
173
174
175static const char* Type2String(Flag::FlagType type) {
176 switch (type) {
177 case Flag::TYPE_BOOL: return "bool";
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 case Flag::TYPE_MAYBE_BOOL: return "maybe_bool";
Steve Blocka7e24c12009-10-30 11:49:00 +0000179 case Flag::TYPE_INT: return "int";
180 case Flag::TYPE_FLOAT: return "float";
181 case Flag::TYPE_STRING: return "string";
182 case Flag::TYPE_ARGS: return "arguments";
183 }
184 UNREACHABLE();
185 return NULL;
186}
187
188
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400189std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 switch (flag.type()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000191 case Flag::TYPE_BOOL:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192 os << (*flag.bool_variable() ? "true" : "false");
193 break;
194 case Flag::TYPE_MAYBE_BOOL:
195 os << (flag.maybe_bool_variable()->has_value
196 ? (flag.maybe_bool_variable()->value ? "true" : "false")
197 : "unset");
Steve Blocka7e24c12009-10-30 11:49:00 +0000198 break;
199 case Flag::TYPE_INT:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000200 os << *flag.int_variable();
Steve Blocka7e24c12009-10-30 11:49:00 +0000201 break;
202 case Flag::TYPE_FLOAT:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 os << *flag.float_variable();
Steve Blocka7e24c12009-10-30 11:49:00 +0000204 break;
205 case Flag::TYPE_STRING: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000206 const char* str = flag.string_value();
207 os << (str ? str : "NULL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000208 break;
209 }
210 case Flag::TYPE_ARGS: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211 JSArguments args = *flag.args_variable();
212 if (args.argc > 0) {
213 os << args[0];
214 for (int i = 1; i < args.argc; i++) {
215 os << args[i];
Steve Blocka7e24c12009-10-30 11:49:00 +0000216 }
217 }
218 break;
219 }
220 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221 return os;
Steve Blocka7e24c12009-10-30 11:49:00 +0000222}
223
224
225// static
226List<const char*>* FlagList::argv() {
227 List<const char*>* args = new List<const char*>(8);
228 Flag* args_flag = NULL;
229 for (size_t i = 0; i < num_flags; ++i) {
230 Flag* f = &flags[i];
231 if (!f->IsDefault()) {
232 if (f->type() == Flag::TYPE_ARGS) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233 DCHECK(args_flag == NULL);
Steve Blocka7e24c12009-10-30 11:49:00 +0000234 args_flag = f; // Must be last in arguments.
235 continue;
236 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 {
238 bool disabled = f->type() == Flag::TYPE_BOOL && !*f->bool_variable();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400239 std::ostringstream os;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 os << (disabled ? "--no" : "--") << f->name();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400241 args->Add(StrDup(os.str().c_str()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000242 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000243 if (f->type() != Flag::TYPE_BOOL) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400244 std::ostringstream os;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000245 os << *f;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400246 args->Add(StrDup(os.str().c_str()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000247 }
248 }
249 }
250 if (args_flag != NULL) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400251 std::ostringstream os;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 os << "--" << args_flag->name();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400253 args->Add(StrDup(os.str().c_str()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000254 JSArguments jsargs = *args_flag->args_variable();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255 for (int j = 0; j < jsargs.argc; j++) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000256 args->Add(StrDup(jsargs[j]));
257 }
258 }
259 return args;
260}
261
262
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000263inline char NormalizeChar(char ch) {
264 return ch == '_' ? '-' : ch;
265}
266
267
Steve Blocka7e24c12009-10-30 11:49:00 +0000268// Helper function to parse flags: Takes an argument arg and splits it into
269// a flag name and flag value (or NULL if they are missing). is_bool is set
270// if the arg started with "-no" or "--no". The buffer may be used to NUL-
271// terminate the name, it must be large enough to hold any possible name.
272static void SplitArgument(const char* arg,
273 char* buffer,
274 int buffer_size,
275 const char** name,
276 const char** value,
277 bool* is_bool) {
278 *name = NULL;
279 *value = NULL;
280 *is_bool = false;
281
Ben Murdochb0fe1622011-05-05 13:52:32 +0100282 if (arg != NULL && *arg == '-') {
Steve Blocka7e24c12009-10-30 11:49:00 +0000283 // find the begin of the flag name
284 arg++; // remove 1st '-'
285 if (*arg == '-') {
286 arg++; // remove 2nd '-'
287 if (arg[0] == '\0') {
288 const char* kJSArgumentsFlagName = "js_arguments";
289 *name = kJSArgumentsFlagName;
290 return;
291 }
292 }
293 if (arg[0] == 'n' && arg[1] == 'o') {
294 arg += 2; // remove "no"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000295 if (NormalizeChar(arg[0]) == '-') arg++; // remove dash after "no".
Steve Blocka7e24c12009-10-30 11:49:00 +0000296 *is_bool = true;
297 }
298 *name = arg;
299
300 // find the end of the flag name
301 while (*arg != '\0' && *arg != '=')
302 arg++;
303
304 // get the value if any
305 if (*arg == '=') {
306 // make a copy so we can NUL-terminate flag name
Steve Blockd0582a62009-12-15 09:54:21 +0000307 size_t n = arg - *name;
308 CHECK(n < static_cast<size_t>(buffer_size)); // buffer is too small
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309 MemCopy(buffer, *name, n);
Steve Blocka7e24c12009-10-30 11:49:00 +0000310 buffer[n] = '\0';
311 *name = buffer;
312 // get the value
313 *value = arg + 1;
314 }
315 }
316}
317
318
Steve Blocka7e24c12009-10-30 11:49:00 +0000319static bool EqualNames(const char* a, const char* b) {
320 for (int i = 0; NormalizeChar(a[i]) == NormalizeChar(b[i]); i++) {
321 if (a[i] == '\0') {
322 return true;
323 }
324 }
325 return false;
326}
327
328
329static Flag* FindFlag(const char* name) {
330 for (size_t i = 0; i < num_flags; ++i) {
331 if (EqualNames(name, flags[i].name()))
332 return &flags[i];
333 }
334 return NULL;
335}
336
337
338// static
339int FlagList::SetFlagsFromCommandLine(int* argc,
340 char** argv,
341 bool remove_flags) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342 int return_code = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000343 // parse arguments
344 for (int i = 1; i < *argc;) {
345 int j = i; // j > 0
346 const char* arg = argv[i++];
347
348 // split arg into flag components
349 char buffer[1*KB];
350 const char* name;
351 const char* value;
352 bool is_bool;
353 SplitArgument(arg, buffer, sizeof buffer, &name, &value, &is_bool);
354
355 if (name != NULL) {
356 // lookup the flag
357 Flag* flag = FindFlag(name);
358 if (flag == NULL) {
359 if (remove_flags) {
360 // We don't recognize this flag but since we're removing
361 // the flags we recognize we assume that the remaining flags
362 // will be processed somewhere else so this flag might make
363 // sense there.
364 continue;
365 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000366 PrintF(stderr, "Error: unrecognized flag %s\n"
367 "Try --help for options\n", arg);
368 return_code = j;
369 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000370 }
371 }
372
373 // if we still need a flag value, use the next argument if available
374 if (flag->type() != Flag::TYPE_BOOL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375 flag->type() != Flag::TYPE_MAYBE_BOOL &&
Steve Blocka7e24c12009-10-30 11:49:00 +0000376 flag->type() != Flag::TYPE_ARGS &&
377 value == NULL) {
378 if (i < *argc) {
379 value = argv[i++];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000380 }
381 if (!value) {
382 PrintF(stderr, "Error: missing value for flag %s of type %s\n"
383 "Try --help for options\n",
384 arg, Type2String(flag->type()));
385 return_code = j;
386 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000387 }
388 }
389
390 // set the flag
391 char* endp = const_cast<char*>(""); // *endp is only read
392 switch (flag->type()) {
393 case Flag::TYPE_BOOL:
394 *flag->bool_variable() = !is_bool;
395 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000396 case Flag::TYPE_MAYBE_BOOL:
397 *flag->maybe_bool_variable() = MaybeBoolFlag::Create(true, !is_bool);
398 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 case Flag::TYPE_INT:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000400 *flag->int_variable() = static_cast<int>(strtol(value, &endp, 10));
Steve Blocka7e24c12009-10-30 11:49:00 +0000401 break;
402 case Flag::TYPE_FLOAT:
403 *flag->float_variable() = strtod(value, &endp);
404 break;
405 case Flag::TYPE_STRING:
406 flag->set_string_value(value ? StrDup(value) : NULL, true);
407 break;
408 case Flag::TYPE_ARGS: {
409 int start_pos = (value == NULL) ? i : i - 1;
410 int js_argc = *argc - start_pos;
411 const char** js_argv = NewArray<const char*>(js_argc);
412 if (value != NULL) {
413 js_argv[0] = StrDup(value);
414 }
415 for (int k = i; k < *argc; k++) {
416 js_argv[k - start_pos] = StrDup(argv[k]);
417 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100418 *flag->args_variable() = JSArguments::Create(js_argc, js_argv);
Steve Blocka7e24c12009-10-30 11:49:00 +0000419 i = *argc; // Consume all arguments
420 break;
421 }
422 }
423
424 // handle errors
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 bool is_bool_type = flag->type() == Flag::TYPE_BOOL ||
426 flag->type() == Flag::TYPE_MAYBE_BOOL;
427 if ((is_bool_type && value != NULL) || (!is_bool_type && is_bool) ||
Steve Blocka7e24c12009-10-30 11:49:00 +0000428 *endp != '\0') {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000429 PrintF(stderr, "Error: illegal value for flag %s of type %s\n"
430 "Try --help for options\n",
431 arg, Type2String(flag->type()));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100432 if (is_bool_type) {
433 PrintF(stderr,
434 "To set or unset a boolean flag, use --flag or --no-flag.\n");
435 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000436 return_code = j;
437 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000438 }
439
440 // remove the flag & value from the command
441 if (remove_flags) {
442 while (j < i) {
443 argv[j++] = NULL;
444 }
445 }
446 }
447 }
448
449 // shrink the argument list
450 if (remove_flags) {
451 int j = 1;
452 for (int i = 1; i < *argc; i++) {
453 if (argv[i] != NULL)
454 argv[j++] = argv[i];
455 }
456 *argc = j;
457 }
458
459 if (FLAG_help) {
460 PrintHelp();
461 exit(0);
462 }
463 // parsed all flags successfully
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000464 return return_code;
Steve Blocka7e24c12009-10-30 11:49:00 +0000465}
466
467
468static char* SkipWhiteSpace(char* p) {
469 while (*p != '\0' && isspace(*p) != 0) p++;
470 return p;
471}
472
473
474static char* SkipBlackSpace(char* p) {
475 while (*p != '\0' && isspace(*p) == 0) p++;
476 return p;
477}
478
479
480// static
481int FlagList::SetFlagsFromString(const char* str, int len) {
482 // make a 0-terminated copy of str
Kristian Monsen25f61362010-05-21 11:50:48 +0100483 ScopedVector<char> copy0(len + 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000484 MemCopy(copy0.start(), str, len);
Steve Blocka7e24c12009-10-30 11:49:00 +0000485 copy0[len] = '\0';
486
487 // strip leading white space
Kristian Monsen25f61362010-05-21 11:50:48 +0100488 char* copy = SkipWhiteSpace(copy0.start());
Steve Blocka7e24c12009-10-30 11:49:00 +0000489
490 // count the number of 'arguments'
491 int argc = 1; // be compatible with SetFlagsFromCommandLine()
492 for (char* p = copy; *p != '\0'; argc++) {
493 p = SkipBlackSpace(p);
494 p = SkipWhiteSpace(p);
495 }
496
497 // allocate argument array
Kristian Monsen25f61362010-05-21 11:50:48 +0100498 ScopedVector<char*> argv(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000499
500 // split the flags string into arguments
501 argc = 1; // be compatible with SetFlagsFromCommandLine()
502 for (char* p = copy; *p != '\0'; argc++) {
503 argv[argc] = p;
504 p = SkipBlackSpace(p);
505 if (*p != '\0') *p++ = '\0'; // 0-terminate argument
506 p = SkipWhiteSpace(p);
507 }
508
509 // set the flags
Kristian Monsen25f61362010-05-21 11:50:48 +0100510 int result = SetFlagsFromCommandLine(&argc, argv.start(), false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000511
512 return result;
513}
514
515
516// static
517void FlagList::ResetAllFlags() {
518 for (size_t i = 0; i < num_flags; ++i) {
519 flags[i].Reset();
520 }
521}
522
523
524// static
525void FlagList::PrintHelp() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 CpuFeatures::Probe(false);
527 CpuFeatures::PrintTarget();
528 CpuFeatures::PrintFeatures();
529
530 OFStream os(stdout);
531 os << "Usage:\n"
532 << " shell [options] -e string\n"
533 << " execute string in V8\n"
534 << " shell [options] file1 file2 ... filek\n"
535 << " run JavaScript scripts in file1, file2, ..., filek\n"
536 << " shell [options]\n"
537 << " shell [options] --shell [file1 file2 ... filek]\n"
538 << " run an interactive JavaScript shell\n"
539 << " d8 [options] file1 file2 ... filek\n"
540 << " d8 [options]\n"
541 << " d8 [options] --shell [file1 file2 ... filek]\n"
542 << " run the new debugging shell\n\n"
543 << "Options:\n";
Steve Blocka7e24c12009-10-30 11:49:00 +0000544 for (size_t i = 0; i < num_flags; ++i) {
545 Flag* f = &flags[i];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000546 os << " --" << f->name() << " (" << f->comment() << ")\n"
547 << " type: " << Type2String(f->type()) << " default: " << *f
548 << "\n";
Steve Blocka7e24c12009-10-30 11:49:00 +0000549 }
550}
551
Ben Murdochc7cc0282012-03-05 14:35:55 +0000552
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000553static uint32_t flag_hash = 0;
Ben Murdoch85b71792012-04-11 18:30:58 +0100554
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400555
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556void ComputeFlagListHash() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400557 std::ostringstream modified_args_as_string;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000558#ifdef DEBUG
559 modified_args_as_string << "debug";
560#endif // DEBUG
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400561 for (size_t i = 0; i < num_flags; ++i) {
562 Flag* current = &flags[i];
563 if (!current->IsDefault()) {
564 modified_args_as_string << i;
565 modified_args_as_string << *current;
566 }
567 }
568 std::string args(modified_args_as_string.str());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 flag_hash = static_cast<uint32_t>(
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400570 base::hash_range(args.c_str(), args.c_str() + args.length()));
571}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572
573
574// static
575void FlagList::EnforceFlagImplications() {
576#define FLAG_MODE_DEFINE_IMPLICATIONS
577#include "src/flag-definitions.h" // NOLINT(build/include)
578#undef FLAG_MODE_DEFINE_IMPLICATIONS
579 ComputeFlagListHash();
580}
581
582
583uint32_t FlagList::Hash() { return flag_hash; }
584} // namespace internal
585} // namespace v8