| Index: src/flags.cc
|
| diff --git a/src/flags.cc b/src/flags.cc
|
| index 4daea395b09a38102258329731248a2e5f3f9f24..db1e892e3317ae83c2af40bc11f55ba492ac8f99 100644
|
| --- a/src/flags.cc
|
| +++ b/src/flags.cc
|
| @@ -48,7 +48,7 @@ namespace {
|
| // to the actual flag, default value, comment, etc. This is designed to be POD
|
| // initialized as to avoid requiring static constructors.
|
| struct Flag {
|
| - enum FlagType { TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING };
|
| + enum FlagType { TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS };
|
|
|
| FlagType type_; // What type of flag, bool, int, or string.
|
| const char* name_; // Name of the flag, ex "my_flag".
|
| @@ -82,6 +82,11 @@ struct Flag {
|
| return reinterpret_cast<const char**>(valptr_);
|
| }
|
|
|
| + JSArguments* args_variable() const {
|
| + ASSERT(type_ == TYPE_ARGS);
|
| + return reinterpret_cast<JSArguments*>(valptr_);
|
| + }
|
| +
|
| bool bool_default() const {
|
| ASSERT(type_ == TYPE_BOOL);
|
| return *reinterpret_cast<const bool*>(defptr_);
|
| @@ -102,6 +107,11 @@ struct Flag {
|
| return *reinterpret_cast<const char* const *>(defptr_);
|
| }
|
|
|
| + JSArguments args_default() const {
|
| + ASSERT(type_ == TYPE_ARGS);
|
| + return *reinterpret_cast<const JSArguments*>(defptr_);
|
| + }
|
| +
|
| // Compare this flag's current value against the default.
|
| bool IsDefault() const {
|
| switch (type_) {
|
| @@ -111,12 +121,15 @@ struct Flag {
|
| return *int_variable() == int_default();
|
| case TYPE_FLOAT:
|
| return *float_variable() == float_default();
|
| - case TYPE_STRING:
|
| + case TYPE_STRING: {
|
| const char* str1 = *string_variable();
|
| const char* str2 = string_default();
|
| if (str2 == NULL) return str1 == NULL;
|
| if (str1 == NULL) return str2 == NULL;
|
| return strcmp(str1, str2) == 0;
|
| + }
|
| + case TYPE_ARGS:
|
| + return args_variable()->argc() == 0;
|
| }
|
| UNREACHABLE();
|
| return true;
|
| @@ -137,6 +150,9 @@ struct Flag {
|
| case TYPE_STRING:
|
| *string_variable() = string_default();
|
| break;
|
| + case TYPE_ARGS:
|
| + *args_variable() = args_default();
|
| + break;
|
| }
|
| }
|
| };
|
| @@ -157,6 +173,7 @@ static const char* Type2String(Flag::FlagType type) {
|
| case Flag::TYPE_INT: return "int";
|
| case Flag::TYPE_FLOAT: return "float";
|
| case Flag::TYPE_STRING: return "string";
|
| + case Flag::TYPE_ARGS: return "arguments";
|
| }
|
| UNREACHABLE();
|
| return NULL;
|
| @@ -178,7 +195,7 @@ static char* ToString(Flag* flag) {
|
| value = Vector<char>::New(20);
|
| OS::SNPrintF(value, "%f", *flag->float_variable());
|
| break;
|
| - case Flag::TYPE_STRING:
|
| + case Flag::TYPE_STRING: {
|
| const char* str = *flag->string_variable();
|
| if (str) {
|
| int length = strlen(str) + 1;
|
| @@ -189,6 +206,26 @@ static char* ToString(Flag* flag) {
|
| OS::SNPrintF(value, "NULL");
|
| }
|
| break;
|
| + }
|
| + case Flag::TYPE_ARGS: {
|
| + JSArguments args = *flag->args_variable();
|
| + if (args.argc() == 0) {
|
| + value = Vector<char>::New(0);
|
| + break;
|
| + }
|
| + int len = args.argc() - 1;
|
| + for (int i = 0; i < args.argc(); i++) {
|
| + len += strlen(args[i]);
|
| + }
|
| + value = Vector<char>::New(len);
|
| + for (int i = 0; i < args.argc(); i++) {
|
| + if (i > 0) {
|
| + OS::SNPrintF(value, " ");
|
| + }
|
| + OS::SNPrintF(value, "%s", args[i]);
|
| + }
|
| + break;
|
| + }
|
| }
|
| ASSERT(!value.is_empty());
|
| return value.start();
|
| @@ -239,8 +276,14 @@ static void SplitArgument(const char* arg,
|
| if (*arg == '-') {
|
| // find the begin of the flag name
|
| arg++; // remove 1st '-'
|
| - if (*arg == '-')
|
| + if (*arg == '-') {
|
| arg++; // remove 2nd '-'
|
| + if (arg[0] == '\0') {
|
| + const char* kJSArgumentsFlagName = "js_arguments";
|
| + *name = kJSArgumentsFlagName;
|
| + return;
|
| + }
|
| + }
|
| if (arg[0] == 'n' && arg[1] == 'o') {
|
| arg += 2; // remove "no"
|
| *is_bool = true;
|
| @@ -324,7 +367,9 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
|
| }
|
|
|
| // if we still need a flag value, use the next argument if available
|
| - if (flag->type() != Flag::TYPE_BOOL && value == NULL) {
|
| + if (flag->type() != Flag::TYPE_BOOL &&
|
| + flag->type() != Flag::TYPE_ARGS &&
|
| + value == NULL) {
|
| if (i < *argc) {
|
| value = argv[i++];
|
| } else {
|
| @@ -350,6 +395,19 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
|
| case Flag::TYPE_STRING:
|
| *flag->string_variable() = value;
|
| break;
|
| + case Flag::TYPE_ARGS:
|
| + int start_pos = (value == NULL) ? i : i - 1;
|
| + int js_argc = *argc - start_pos;
|
| + const char** js_argv = new const char*[js_argc];
|
| + if (value != NULL) {
|
| + js_argv[0] = value;
|
| + }
|
| + for (int k = i; k < *argc; k++) {
|
| + js_argv[k - start_pos] = argv[k];
|
| + }
|
| + *flag->args_variable() = JSArguments(js_argc, js_argv);
|
| + i = *argc; // Consume all arguments
|
| + break;
|
| }
|
|
|
| // handle errors
|
| @@ -474,4 +532,18 @@ void FlagList::PrintHelp() {
|
| }
|
| }
|
|
|
| +JSArguments::JSArguments()
|
| + : argc_(0), argv_(NULL) {}
|
| +JSArguments::JSArguments(int argc, const char** argv)
|
| + : argc_(argc), argv_(argv) {}
|
| +int JSArguments::argc() const { return argc_; }
|
| +const char** JSArguments::argv() { return argv_; }
|
| +const char*& JSArguments::operator[](int idx) { return argv_[idx]; }
|
| +JSArguments& JSArguments::operator=(JSArguments args) {
|
| + argc_ = args.argc_;
|
| + argv_ = args.argv_;
|
| + return *this;
|
| +}
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|