1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_FLAGS_H_
6#define RUNTIME_VM_FLAGS_H_
7
8#include "platform/assert.h"
9#include "vm/flag_list.h"
10#include "vm/globals.h"
11
12typedef const char* charp;
13
14#define DECLARE_FLAG(type, name) extern type FLAG_##name
15
16#define DEFINE_FLAG(type, name, default_value, comment) \
17 type FLAG_##name = \
18 Flags::Register_##type(&FLAG_##name, #name, default_value, comment);
19
20#define DEFINE_FLAG_HANDLER(handler, name, comment) \
21 bool DUMMY_##name = Flags::RegisterFlagHandler(handler, #name, comment);
22
23#define DEFINE_OPTION_HANDLER(handler, name, comment) \
24 bool DUMMY_##name = Flags::RegisterOptionHandler(handler, #name, comment);
25
26namespace dart {
27
28typedef void (*FlagHandler)(bool value);
29typedef void (*OptionHandler)(const char* value);
30
31// Forward declarations.
32class Flag;
33class JSONArray;
34class JSONStream;
35
36class Flags {
37 public:
38 static bool Register_bool(bool* addr,
39 const char* name,
40 bool default_value,
41 const char* comment);
42
43 static int Register_int(int* addr,
44 const char* name,
45 int default_value,
46 const char* comment);
47
48 static uint64_t Register_uint64_t(uint64_t* addr,
49 const char* name,
50 uint64_t default_value,
51 const char* comment);
52
53 static const char* Register_charp(charp* addr,
54 const char* name,
55 const char* default_value,
56 const char* comment);
57
58 static bool RegisterFlagHandler(FlagHandler handler,
59 const char* name,
60 const char* comment);
61
62 static bool RegisterOptionHandler(OptionHandler handler,
63 const char* name,
64 const char* comment);
65
66 static char* ProcessCommandLineFlags(int argc, const char** argv);
67
68 static Flag* Lookup(const char* name);
69
70 static bool IsSet(const char* name);
71
72 static bool Initialized() { return initialized_; }
73
74 static void Cleanup();
75
76#ifndef PRODUCT
77 static void PrintJSON(JSONStream* js);
78#endif // !PRODUCT
79
80 static bool SetFlag(const char* name, const char* value, const char** error);
81
82 private:
83 static Flag** flags_;
84 static intptr_t capacity_;
85 static intptr_t num_flags_;
86
87 static bool initialized_;
88
89 static void AddFlag(Flag* flag);
90
91 static bool SetFlagFromString(Flag* flag, const char* argument);
92
93 static void Parse(const char* option);
94
95 static int CompareFlagNames(const void* left, const void* right);
96
97 static void PrintFlags();
98
99#ifndef PRODUCT
100 static void PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag);
101#endif // !PRODUCT
102
103 // Testing needs direct access to private methods.
104 friend void Dart_TestParseFlags();
105
106 DISALLOW_ALLOCATION();
107 DISALLOW_IMPLICIT_CONSTRUCTORS(Flags);
108};
109
110#define PRODUCT_FLAG_MACRO(name, type, default_value, comment) \
111 extern type FLAG_##name;
112
113#if defined(DEBUG)
114#define DEBUG_FLAG_MACRO(name, type, default_value, comment) \
115 extern type FLAG_##name;
116#else // defined(DEBUG)
117#define DEBUG_FLAG_MACRO(name, type, default_value, comment) \
118 const type FLAG_##name = default_value;
119#endif // defined(DEBUG)
120
121#if defined(PRODUCT) && defined(DART_PRECOMPILED_RUNTIME)
122#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \
123 const type FLAG_##name = product_value;
124#define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \
125 default_value, comment) \
126 const type FLAG_##name = precompiled_value;
127
128#elif defined(PRODUCT) // !PRECOMPILED
129#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \
130 const type FLAG_##name = product_value;
131#define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \
132 default_value, comment) \
133 const type FLAG_##name = product_value;
134
135#elif defined(DART_PRECOMPILED_RUNTIME) // !PRODUCT
136#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \
137 extern type FLAG_##name;
138#define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \
139 default_value, comment) \
140 const type FLAG_##name = precompiled_value;
141
142#else // !PRODUCT && !PRECOMPILED
143#define RELEASE_FLAG_MACRO(name, product_value, type, default_value, comment) \
144 extern type FLAG_##name;
145#define PRECOMPILE_FLAG_MACRO(name, precompiled_value, product_value, type, \
146 default_value, comment) \
147 extern type FLAG_##name;
148
149#endif
150
151// Now declare all flags here.
152FLAG_LIST(PRODUCT_FLAG_MACRO,
153 RELEASE_FLAG_MACRO,
154 PRECOMPILE_FLAG_MACRO,
155 DEBUG_FLAG_MACRO)
156
157#undef RELEASE_FLAG_MACRO
158#undef DEBUG_FLAG_MACRO
159#undef PRODUCT_FLAG_MACRO
160#undef PRECOMPILE_FLAG_MACRO
161
162} // namespace dart
163
164#endif // RUNTIME_VM_FLAGS_H_
165