History

Ensure a C++ object exists for all static const members of structs or create constexpr functions. - This is an attempt to adhere to the letter of the C++ specification.

arr committed 9 years ago

Commit af5c7a91 parent 4d839d714 files · +86 −64Browse files

Unified · Split

14 files
  1. src/asm/sbl_reader.cpp +13 −6
  2. src/asm/type_signature.cpp +6 −0
  3. src/exec/main.cpp +1 −1
  4. src/include/buffered_reader.h +3 −6
  5. src/include/builtin_module.h +6 −6
  6. src/include/disvm.h +3 −6
  7. src/include/module_reader.h +3 −3
  8. src/include/runtime.h +3 −3
  9. src/include/utf8.h +7 −7
  10. src/include/vm_asm.h +17 −8
  11. src/vm/execution_table.cpp +9 −9
  12. src/vm/module_reader.cpp +7 −7
  13. src/vm/stack.cpp +2 −2
  14. src/vm/vm.cpp +6 −0
src/asm/sbl_reader.cpp+13−6
@@ -96,12 +96,12 @@ namespace · 95 unmodified lines
96 96
97 struct type_table_t97 struct type_table_t
98 {98 {
99 static const uint32_t string_table_mask = 0x80000000;99 static const uint32_t string_table_mask;
100 static const uint32_t inner_type_table_mask = 0x40000000;100 static const uint32_t inner_type_table_mask;
101 static const uint32_t source_table_mask = 0x20000000;101 static const uint32_t source_table_mask;
102 static const uint32_t adt_table_mask = 0x10000000;102 static const uint32_t adt_table_mask;
103 static const uint32_t tuple_type_mask = 0x08000000;103 static const uint32_t tuple_type_mask;
104 static const uint32_t types_mask = 0;104 static const uint32_t types_mask;
105 105
106 std::vector<type_t> types;106 std::vector<type_t> types;
107 std::vector<std::string> strings_table;107 std::vector<std::string> strings_table;
@@ -114,6 +114,13 @@ namespace · 6 unmodified lines
114 const T &resolve_table_index(int32_t idx) const;114 const T &resolve_table_index(int32_t idx) const;
115 };115 };
116 116
117 const uint32_t type_table_t::string_table_mask = 0x80000000;
118 const uint32_t type_table_t::inner_type_table_mask = 0x40000000;
119 const uint32_t type_table_t::source_table_mask = 0x20000000;
120 const uint32_t type_table_t::adt_table_mask = 0x10000000;
121 const uint32_t type_table_t::tuple_type_mask = 0x08000000;
122 const uint32_t type_table_t::types_mask = 0;
123
117 template<>124 template<>
118 const std::string &type_table_t::resolve_table_index<std::string>(int32_t idx) const125 const std::string &type_table_t::resolve_table_index<std::string>(int32_t idx) const
119 {126 {
src/asm/type_signature.cpp+6−0
@@ -34,6 +34,8 @@ namespace · 33 unmodified lines
34 }34 }
35}35}
36 36
37const char sig_stream_t::delim = ',';
38
37uint32_t sig_stream_t::compute_signature_hash(const char *sig)39uint32_t sig_stream_t::compute_signature_hash(const char *sig)
38{40{
39 std::string sig_local{ sig };41 std::string sig_local{ sig };
@@ -124,6 +126,8 @@ sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tchan · 84 unmodified lines
124 return os << c._s;126 return os << c._s;
125}127}
126 128
129const char Ttype_ref::id = '@';
130
127Ttype_ref::Ttype_ref(uint32_t num)131Ttype_ref::Ttype_ref(uint32_t num)
128 : _num{ num }132 : _num{ num }
129{ }133{ }
@@ -155,6 +159,8 @@ sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tmodu · 25 unmodified lines
155}159}
156 160
157const char *Tadt_pick_tag::tag_delim = "=>";161const char *Tadt_pick_tag::tag_delim = "=>";
162const char Tadt_pick_tag::begin = '(';
163const char Tadt_pick_tag::end = ')';
158 164
159Tadt_pick_tag Tadt_pick_tag::create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms)165Tadt_pick_tag Tadt_pick_tag::create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms)
160{166{
src/exec/main.cpp+1−1
@@ -102,7 +102,7 @@ namespace · 101 unmodified lines
102 mp_base[1] = args->get_allocation();102 mp_base[1] = args->get_allocation();
103 103
104 // Define the frame offset for the argument104 // Define the frame offset for the argument
105 const auto first_arg_offset = vm_frame_constants::limbo_first_arg_register_offset;105 const auto first_arg_offset = vm_frame_constants::limbo_first_arg_register_offset();
106 106
107 e.code_section =107 e.code_section =
108 {108 {
src/include/buffered_reader.h+3−6
@@ -20,12 +20,9 @@ namespace disvm · 19 unmodified lines
20 {20 {
21 class buffered_reader_t21 class buffered_reader_t
22 {22 {
23 private: // static
24 static const std::size_t buffer_size = 64 * 1024; // 64k is an optimization for the Windows filesystem manager
25
26 public:23 public:
27 buffered_reader_t(std::istream &stream)24 buffered_reader_t(std::istream &stream)
28 : _buffer(buffered_reader_t::buffer_size)25 : _buffer(64 * 1024) // 64k is an optimization for the Windows filesystem manager
29 , _current_index{ 0 }26 , _current_index{ 0 }
30 , _current_size{ 0 }27 , _current_size{ 0 }
31 , _stream{ stream }28 , _stream{ stream }
@@ -141,10 +138,10 @@ namespace disvm · 109 unmodified lines
141 if (_stream.fail())138 if (_stream.fail())
142 return 0;139 return 0;
143 140
144 _stream.read(_buffer.data(), buffered_reader_t::buffer_size);141 _stream.read(_buffer.data(), _buffer.size());
145 142
146 // If the stream has failed, set the current size, otherwise the buffer size143 // If the stream has failed, set the current size, otherwise the buffer size
147 _current_size = _stream.fail() ? static_cast<std::size_t>(_stream.gcount()) : buffered_reader_t::buffer_size;144 _current_size = _stream.fail() ? static_cast<std::size_t>(_stream.gcount()) : _buffer.size();
148 }145 }
149 146
150 return _current_size - _current_index;147 return _current_size - _current_index;
src/include/builtin_module.h+6−6
@@ -61,23 +61,23 @@ namespace disvm · 60 unmodified lines
61 61
62 struct vm_frame_constants62 struct vm_frame_constants
63 {63 {
64 static const auto register_size_in_bytes = sizeof(word_t);64 static constexpr auto register_size_in_bytes() { return sizeof(word_t); }
65 65
66 // Includes registers on base frame plus the implied return register66 // Includes registers on base frame plus the implied return register
67 static const auto default_register_count = (sizeof(vm_frame_base_alloc_t) / register_size_in_bytes) + 1;67 static constexpr auto default_register_count() { return (sizeof(vm_frame_base_alloc_t) / register_size_in_bytes()) + 1; }
68 68
69 // [SPEC] The fixed point registers are defined by their usage in the69 // [SPEC] The fixed point registers are defined by their usage in the
70 // Inferno implementation. They rely on the 'temp' registers defined below.70 // Inferno implementation. They rely on the 'temp' registers defined below.
71 // See fixed point opcodes in Inferno (libinterp/xec.c).71 // See fixed point opcodes in Inferno (libinterp/xec.c).
72 static const auto fixed_point_register_1_offset = default_register_count * register_size_in_bytes;72 static constexpr auto fixed_point_register_1_offset() { return default_register_count() * register_size_in_bytes(); }
73 static const auto fixed_point_register_2_offset = fixed_point_register_1_offset + (2 * register_size_in_bytes);73 static constexpr auto fixed_point_register_2_offset() { return fixed_point_register_1_offset() + (2 * register_size_in_bytes()); }
74 74
75 // [SPEC] The official Limbo compiler allocates additional 'temp' registers on all call frames.75 // [SPEC] The official Limbo compiler allocates additional 'temp' registers on all call frames.
76 // See 'STemp', 'RTemp', and 'DTemp' in Inferno (limbo/limbo.h)76 // See 'STemp', 'RTemp', and 'DTemp' in Inferno (limbo/limbo.h)
77 static const auto limbo_temp_register_count = 3;77 static constexpr auto limbo_temp_register_count() { return 3; }
78 78
79 // Define the first argument offset in a Limbo compiler generated call frame.79 // Define the first argument offset in a Limbo compiler generated call frame.
80 static const auto limbo_first_arg_register_offset = (default_register_count + limbo_temp_register_count) * register_size_in_bytes;80 static constexpr auto limbo_first_arg_register_offset() { return (default_register_count() + limbo_temp_register_count()) * register_size_in_bytes(); }
81 };81 };
82 82
83 //83 //
src/include/disvm.h+3−6
@@ -55,12 +55,9 @@ namespace disvm · 54 unmodified lines
55 class vm_t final55 class vm_t final
56 {56 {
57 public: // static57 public: // static
58 static const uint32_t root_vm_thread_id = 0;58 static const uint32_t root_vm_thread_id;
59 59 static const uint32_t default_system_thread_count;
60 static const uint32_t default_system_thread_count = 1;60 static const uint32_t default_thread_quanta;
61
62 // The Inferno implementation defined the thread quanta as 2048 (include/interp.h)
63 static const uint32_t default_thread_quanta = 2048;
64 61
65 public:62 public:
66 explicit vm_t(63 explicit vm_t(
src/include/module_reader.h+3−3
@@ -18,10 +18,10 @@ namespace disvm · 17 unmodified lines
18 static_assert(sizeof(operand_t) == sizeof(runtime::word_t), "Operand and word should be the same size");18 static_assert(sizeof(operand_t) == sizeof(runtime::word_t), "Operand and word should be the same size");
19 static_assert(sizeof(operand_t) == sizeof(runtime::vm_pc_t), "Operand and VM program counter type should be the same size");19 static_assert(sizeof(operand_t) == sizeof(runtime::vm_pc_t), "Operand and VM program counter type should be the same size");
20 20
21 struct magic_number_constants final21 namespace magic_number_constants
22 {22 {
23 static const auto xmagic = operand_t{ 819248 }; // Normal module (0xC8030)23 const auto xmagic = operand_t{ 819248 }; // Normal module (0xC8030)
24 static const auto smagic = operand_t{ 923426 }; // Signed module (0xE1722)24 const auto smagic = operand_t{ 923426 }; // Signed module (0xE1722)
25 };25 };
26 }26 }
27}27}
src/include/runtime.h+3−3
@@ -364,11 +364,11 @@ namespace disvm · 363 unmodified lines
364 };364 };
365 365
366 // Runtime constants366 // Runtime constants
367 struct runtime_constants367 namespace runtime_constants
368 {368 {
369 static const auto nil = std::size_t{ 0 };369 const auto nil = std::size_t{ 0 };
370 370
371 static const auto invalid_program_counter = vm_pc_t{ ~0 };371 const auto invalid_program_counter = vm_pc_t{ ~0 };
372 };372 };
373 373
374 // Addressing mode for middle instruction data374 // Addressing mode for middle instruction data
src/include/utf8.h+7−7
@@ -17,16 +17,16 @@ namespace disvm · 16 unmodified lines
17 namespace utf817 namespace utf8
18 {18 {
19 // As defined in http://tools.ietf.org/html/rfc362919 // As defined in http://tools.ietf.org/html/rfc3629
20 struct constants20 namespace constants
21 {21 {
22 static const rune_t multi_byte_value_mask = 0x3f;22 const disvm::runtime::rune_t multi_byte_value_mask = 0x3f;
23 23
24 static const rune_t max_codepoint_ascii = 0x7f;24 const disvm::runtime::rune_t max_codepoint_ascii = 0x7f;
25 static const rune_t max_codepoint_2_byte = 0x7ff;25 const disvm::runtime::rune_t max_codepoint_2_byte = 0x7ff;
26 static const rune_t max_codepoint_3_byte = 0xffff;26 const disvm::runtime::rune_t max_codepoint_3_byte = 0xffff;
27 static const rune_t max_codepoint_4_byte = 0x10ffff;27 const disvm::runtime::rune_t max_codepoint_4_byte = 0x10ffff;
28 28
29 static const rune_t max_supported_codepoint = max_codepoint_4_byte;29 const disvm::runtime::rune_t max_supported_codepoint = max_codepoint_4_byte;
30 };30 };
31 31
32 // Compute the number of code points in the supplied string32 // Compute the number of code points in the supplied string
src/include/vm_asm.h+17−8
@@ -46,7 +46,7 @@ namespace disvm · 45 unmodified lines
46 static uint32_t compute_signature_hash(const char *);46 static uint32_t compute_signature_hash(const char *);
47 47
48 // Type delimiter48 // Type delimiter
49 static const char delim = ',';49 static const char delim;
50 50
51 public:51 public:
52 std::string get_signature() const;52 std::string get_signature() const;
@@ -100,7 +100,7 @@ namespace disvm · 47 unmodified lines
100 template<type_id_t T>100 template<type_id_t T>
101 struct Tbasic_type101 struct Tbasic_type
102 {102 {
103 static const type_id_t id = T;103 static const type_id_t id;
104 104
105 constexpr operator type_id_t() const105 constexpr operator type_id_t() const
106 {106 {
@@ -108,6 +108,9 @@ namespace disvm · 1 unmodified line
108 }108 }
109 };109 };
110 110
111 template<type_id_t T>
112 const type_id_t Tbasic_type<T>::id = T;
113
111 using Tnone = Tbasic_type<type_id_t::none>;114 using Tnone = Tbasic_type<type_id_t::none>;
112 using Tbyte = Tbasic_type<type_id_t::byte>;115 using Tbyte = Tbasic_type<type_id_t::byte>;
113 using Tinteger = Tbasic_type<type_id_t::integer>;116 using Tinteger = Tbasic_type<type_id_t::integer>;
@@ -164,7 +167,7 @@ namespace disvm · 50 unmodified lines
164 class Ttype_ref final167 class Ttype_ref final
165 {168 {
166 public: // static169 public: // static
167 static const char id = '@';170 static const char id;
168 171
169 public:172 public:
170 Ttype_ref(uint32_t num);173 Ttype_ref(uint32_t num);
@@ -218,7 +221,7 @@ namespace disvm · 47 unmodified lines
218 template <type_id_t ID>221 template <type_id_t ID>
219 class Tnested_aggregate_type : public Tbasic_type<ID>222 class Tnested_aggregate_type : public Tbasic_type<ID>
220 {223 {
221 public: // static224 public: // static
222 static const char begin;225 static const char begin;
223 static const char end;226 static const char end;
224 227
@@ -258,8 +261,8 @@ namespace disvm · 33 unmodified lines
258 {261 {
259 public: // static262 public: // static
260 static const char *tag_delim;263 static const char *tag_delim;
261 static const char begin = '(';264 static const char begin;
262 static const char end = ')';265 static const char end;
263 266
264 static Tadt_pick_tag create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms);267 static Tadt_pick_tag create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms);
265 268
@@ -325,8 +328,8 @@ namespace disvm · 59 unmodified lines
325 class Tfunction_base_type final : public Tbasic_type<T>328 class Tfunction_base_type final : public Tbasic_type<T>
326 {329 {
327 public: // static330 public: // static
328 static const char begin = '(';331 static const char begin;
329 static const char end = ')';332 static const char end;
330 333
331 template<typename ...AT>334 template<typename ...AT>
332 static Tfunction_base_type create(AT... argTypes)335 static Tfunction_base_type create(AT... argTypes)
@@ -360,6 +363,12 @@ namespace disvm · 27 unmodified lines
360 Tfunction_base_type() : _fully_defined{ false } { }363 Tfunction_base_type() : _fully_defined{ false } { }
361 };364 };
362 365
366 template<type_id_t T>
367 const char Tfunction_base_type<T>::begin = '(';
368
369 template<type_id_t T>
370 const char Tfunction_base_type<T>::end = ')';
371
363 using Tfunction = Tfunction_base_type<type_id_t::function>;372 using Tfunction = Tfunction_base_type<type_id_t::function>;
364 using Tfunction_varargs = Tfunction_base_type<type_id_t::function_varargs>;373 using Tfunction_varargs = Tfunction_base_type<type_id_t::function_varargs>;
365 374
src/vm/execution_table.cpp+9−9
@@ -579,15 +579,15 @@ namespace · 578 unmodified lines
579 // Define case table constants579 // Define case table constants
580 // [SPEC]Table format is partially defined in Dis VM specification580 // [SPEC]Table format is partially defined in Dis VM specification
581 // [element count] ([low value (inc)][high value (exc)][program counter])* [fallback program counter]581 // [element count] ([low value (inc)][high value (exc)][program counter])* [fallback program counter]
582 struct case_op_constants582 namespace case_op_constants
583 {583 {
584 static const auto table_length_index = std::size_t{ 0 };584 const auto table_length_index = std::size_t{ 0 };
585 static const auto first_entry_index = std::size_t{ 1 };585 const auto first_entry_index = std::size_t{ 1 };
586 static const auto entry_low_index = std::size_t{ 0 };586 const auto entry_low_index = std::size_t{ 0 };
587 static const auto entry_high_index = std::size_t{ 1 };587 const auto entry_high_index = std::size_t{ 1 };
588 static const auto entry_pc_index = std::size_t{ 2 };588 const auto entry_pc_index = std::size_t{ 2 };
589 static const auto entry_length = std::size_t{ 3 };589 const auto entry_length = std::size_t{ 3 };
590 };590 }
591 591
592 template<typename PrimitiveType>592 template<typename PrimitiveType>
593 void _case(vm_registers_t &r)593 void _case(vm_registers_t &r)
src/vm/module_reader.cpp+7−7
@@ -25,14 +25,14 @@ using namespace disvm::format; · 24 unmodified lines
25namespace25namespace
26{26{
27 // constants used in module processing27 // constants used in module processing
28 struct module_constants28 namespace module_constants
29 {29 {
30 static const auto max_type_pointer_count = operand_t{ 128 * 1024 };30 const auto max_type_pointer_count = operand_t{ 128 * 1024 };
31 static const auto no_error_handle_type_desc = operand_t{ -1 };31 const auto no_error_handle_type_desc = operand_t{ -1 };
32 static const auto no_entry_pc = vm_pc_t{ -1 };32 const auto no_entry_pc = vm_pc_t{ -1 };
33 static const auto vm_module_type_desc_number = std::size_t{ 0 };33 const auto vm_module_type_desc_number = std::size_t{ 0 };
34 static const auto max_module_name_bytes = std::size_t{ 128 }; // Including null34 const auto max_module_name_bytes = std::size_t{ 128 }; // Including null
35 static const auto array_address_stack_size = std::size_t{ 4 };35 const auto array_address_stack_size = std::size_t{ 4 };
36 };36 };
37 37
38 // enumeration for types in the data section38 // enumeration for types in the data section
src/vm/stack.cpp+2−2
@@ -161,7 +161,7 @@ vm_module_ref_t *&vm_frame_t::prev_module_ref() const · 160 unmodified lines
161 161
162pointer_t vm_frame_t::fixed_point_register_1() const162pointer_t vm_frame_t::fixed_point_register_1() const
163{163{
164 const auto offset = vm_frame_constants::fixed_point_register_1_offset;164 const auto offset = vm_frame_constants::fixed_point_register_1_offset();
165 assert(offset < frame_type->size_in_bytes);165 assert(offset < frame_type->size_in_bytes);
166 166
167 auto p = reinterpret_cast<uint8_t *>(base()) + offset;167 auto p = reinterpret_cast<uint8_t *>(base()) + offset;
@@ -170,7 +170,7 @@ pointer_t vm_frame_t::fixed_point_register_1() const · 2 unmodified lines
170 170
171pointer_t vm_frame_t::fixed_point_register_2() const171pointer_t vm_frame_t::fixed_point_register_2() const
172{172{
173 const auto offset = vm_frame_constants::fixed_point_register_2_offset;173 const auto offset = vm_frame_constants::fixed_point_register_2_offset();
174 assert(offset < frame_type->size_in_bytes);174 assert(offset < frame_type->size_in_bytes);
175 175
176 auto p = reinterpret_cast<uint8_t *>(base()) + offset;176 auto p = reinterpret_cast<uint8_t *>(base()) + offset;
src/vm/vm.cpp+6−0
@@ -20,6 +20,12 @@ · 19 unmodified lines
20using namespace disvm;20using namespace disvm;
21using namespace disvm::runtime;21using namespace disvm::runtime;
22 22
23const uint32_t vm_t::root_vm_thread_id = 0;
24const uint32_t vm_t::default_system_thread_count = 1;
25
26// The Inferno implementation defined the thread quanta as 2048 (include/interp.h)
27const uint32_t vm_t::default_thread_quanta = 2048;
28
23vm_t::vm_t(29vm_t::vm_t(
24 create_vm_interface_callback_t<runtime::vm_scheduler_t> create_scheduler,30 create_vm_interface_callback_t<runtime::vm_scheduler_t> create_scheduler,
25 create_vm_interface_callback_t<runtime::vm_garbage_collector_t> create_gc)31 create_vm_interface_callback_t<runtime::vm_garbage_collector_t> create_gc)