OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
6 | 6 |
7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
11 #include "src/v8.h" | 11 #include "src/v8.h" |
12 | 12 |
13 #include "src/wasm/decoder.h" | 13 #include "src/wasm/decoder.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 namespace wasm { | 17 namespace wasm { |
18 | 18 |
19 #if DEBUG | 19 #if DEBUG |
20 #define TRACE(...) \ | 20 #define TRACE(...) \ |
21 do { \ | 21 do { \ |
22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
23 } while (false) | 23 } while (false) |
24 #else | 24 #else |
25 #define TRACE(...) | 25 #define TRACE(...) |
26 #endif | 26 #endif |
27 | 27 |
28 | |
29 // The main logic for decoding the bytes of a module. | 28 // The main logic for decoding the bytes of a module. |
30 class ModuleDecoder : public Decoder { | 29 class ModuleDecoder : public Decoder { |
31 public: | 30 public: |
32 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, | 31 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, |
33 ModuleOrigin origin) | 32 ModuleOrigin origin) |
34 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { | 33 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { |
35 result_.start = start_; | 34 result_.start = start_; |
36 if (limit_ < start_) { | 35 if (limit_ < start_) { |
37 error(start_, "end is less than start"); | 36 error(start_, "end is less than start"); |
38 limit_ = start_; | 37 limit_ = start_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { | 71 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { |
73 pc_ = start_; | 72 pc_ = start_; |
74 module->module_start = start_; | 73 module->module_start = start_; |
75 module->module_end = limit_; | 74 module->module_end = limit_; |
76 module->min_mem_pages = 0; | 75 module->min_mem_pages = 0; |
77 module->max_mem_pages = 0; | 76 module->max_mem_pages = 0; |
78 module->mem_export = false; | 77 module->mem_export = false; |
79 module->mem_external = false; | 78 module->mem_external = false; |
80 module->origin = origin_; | 79 module->origin = origin_; |
81 | 80 |
82 bool sections[(size_t)WasmSection::Code::Max] = {false}; | |
83 | |
84 const byte* pos = pc_; | 81 const byte* pos = pc_; |
82 int current_order = 0; | |
85 uint32_t magic_word = consume_u32("wasm magic"); | 83 uint32_t magic_word = consume_u32("wasm magic"); |
86 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff | 84 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff |
87 if (magic_word != kWasmMagic) { | 85 if (magic_word != kWasmMagic) { |
88 error(pos, pos, | 86 error(pos, pos, |
89 "expected magic word %02x %02x %02x %02x, " | 87 "expected magic word %02x %02x %02x %02x, " |
90 "found %02x %02x %02x %02x", | 88 "found %02x %02x %02x %02x", |
91 BYTES(kWasmMagic), BYTES(magic_word)); | 89 BYTES(kWasmMagic), BYTES(magic_word)); |
92 goto done; | 90 goto done; |
93 } | 91 } |
94 | 92 |
95 pos = pc_; | 93 pos = pc_; |
96 { | 94 { |
97 uint32_t magic_version = consume_u32("wasm version"); | 95 uint32_t magic_version = consume_u32("wasm version"); |
98 if (magic_version != kWasmVersion) { | 96 if (magic_version != kWasmVersion) { |
99 error(pos, pos, | 97 error(pos, pos, |
100 "expected version %02x %02x %02x %02x, " | 98 "expected version %02x %02x %02x %02x, " |
101 "found %02x %02x %02x %02x", | 99 "found %02x %02x %02x %02x", |
102 BYTES(kWasmVersion), BYTES(magic_version)); | 100 BYTES(kWasmVersion), BYTES(magic_version)); |
103 goto done; | 101 goto done; |
104 } | 102 } |
105 } | 103 } |
106 | 104 |
107 // Decode the module sections. | 105 // Decode the module sections. |
108 while (pc_ < limit_) { | 106 while (pc_ < limit_) { |
109 TRACE("DecodeSection\n"); | 107 TRACE("DecodeSection\n"); |
110 pos = pc_; | 108 pos = pc_; |
111 | 109 |
112 int length; | 110 // Read and check the section size. |
113 uint32_t section_length = consume_u32v(&length, "section size"); | 111 int section_leb_length = 0; |
114 | 112 uint32_t section_length = |
115 int section_string_leb_length = 0; | 113 consume_u32v(§ion_leb_length, "section length"); |
116 uint32_t section_string_length = 0; | 114 if (!checkAvailable(section_length)) { |
117 WasmSection::Code section = consume_section_name( | 115 // The section would extend beyond the end of the module. |
118 §ion_string_leb_length, §ion_string_length); | |
119 uint32_t string_and_leb_length = | |
120 section_string_leb_length + section_string_length; | |
121 if (string_and_leb_length > section_length) { | |
122 error(pos, pos, | |
123 "section string of size %u longer than total section bytes %u", | |
124 string_and_leb_length, section_length); | |
125 break; | 116 break; |
126 } | 117 } |
118 const byte* section_start = pc_; | |
119 const byte* expected_section_end = pc_ + section_length; | |
127 | 120 |
128 if (section == WasmSection::Code::Max) { | 121 // Read the section name. |
129 // Skip unknown section. | 122 int string_leb_length = 0; |
130 uint32_t skip = section_length - string_and_leb_length; | 123 uint32_t string_length = |
131 TRACE("skipping %u bytes from unknown section\n", skip); | 124 consume_u32v(&string_leb_length, "section name length"); |
132 consume_bytes(skip); | 125 const byte* section_name_start = pc_; |
133 continue; | 126 consume_bytes(string_length); |
127 if (failed()) { | |
128 TRACE("Section name of length %u couldn't be read\n", string_length); | |
129 break; | |
130 } | |
131 if (pc_ > expected_section_end) { | |
132 error(section_name_start, pc_, | |
133 "section name string %u longer than total section bytes %u", | |
134 string_length, section_length); | |
134 } | 135 } |
135 | 136 |
136 // Each section should appear at most once. | 137 WasmSection::Code section = |
137 CheckForPreviousSection(sections, section, false); | 138 WasmSection::lookup(section_name_start, string_length); |
138 sections[(size_t)section] = true; | 139 |
140 current_order = CheckSectionOrder(current_order, section); | |
139 | 141 |
140 switch (section) { | 142 switch (section) { |
141 case WasmSection::Code::End: | 143 case WasmSection::Code::End: |
142 // Terminate section decoding. | 144 // Terminate section decoding. |
143 limit_ = pc_; | 145 limit_ = pc_; |
144 break; | 146 break; |
145 case WasmSection::Code::Memory: | 147 case WasmSection::Code::Memory: |
146 int length; | 148 int length; |
147 module->min_mem_pages = consume_u32v(&length, "min memory"); | 149 module->min_mem_pages = consume_u32v(&length, "min memory"); |
148 module->max_mem_pages = consume_u32v(&length, "max memory"); | 150 module->max_mem_pages = consume_u32v(&length, "max memory"); |
149 module->mem_export = consume_u8("export memory") != 0; | 151 module->mem_export = consume_u8("export memory") != 0; |
150 break; | 152 break; |
151 case WasmSection::Code::Signatures: { | 153 case WasmSection::Code::Signatures: { |
152 int length; | 154 int length; |
153 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
154 module->signatures.reserve(SafeReserve(signatures_count)); | 156 module->signatures.reserve(SafeReserve(signatures_count)); |
155 // Decode signatures. | 157 // Decode signatures. |
156 for (uint32_t i = 0; i < signatures_count; i++) { | 158 for (uint32_t i = 0; i < signatures_count; i++) { |
157 if (failed()) break; | 159 if (failed()) break; |
158 TRACE("DecodeSignature[%d] module+%d\n", i, | 160 TRACE("DecodeSignature[%d] module+%d\n", i, |
159 static_cast<int>(pc_ - start_)); | 161 static_cast<int>(pc_ - start_)); |
160 FunctionSig* s = consume_sig(); // read function sig. | 162 FunctionSig* s = consume_sig(); // read function sig. |
161 module->signatures.push_back(s); | 163 module->signatures.push_back(s); |
162 } | 164 } |
163 break; | 165 break; |
164 } | 166 } |
165 case WasmSection::Code::FunctionSignatures: { | 167 case WasmSection::Code::FunctionSignatures: { |
166 // Functions require a signature table first. | |
167 CheckForPreviousSection(sections, WasmSection::Code::Signatures, | |
168 true); | |
169 int length; | 168 int length; |
170 uint32_t functions_count = consume_u32v(&length, "functions count"); | 169 uint32_t functions_count = consume_u32v(&length, "functions count"); |
171 module->functions.reserve(SafeReserve(functions_count)); | 170 module->functions.reserve(SafeReserve(functions_count)); |
172 for (uint32_t i = 0; i < functions_count; i++) { | 171 for (uint32_t i = 0; i < functions_count; i++) { |
173 module->functions.push_back( | 172 module->functions.push_back( |
174 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); | 173 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); |
175 WasmFunction* function = &module->functions.back(); | 174 WasmFunction* function = &module->functions.back(); |
176 function->sig_index = consume_sig_index(module, &function->sig); | 175 function->sig_index = consume_sig_index(module, &function->sig); |
177 } | 176 } |
178 break; | 177 break; |
179 } | 178 } |
180 case WasmSection::Code::FunctionBodies: { | 179 case WasmSection::Code::FunctionBodies: { |
181 // Function bodies should follow signatures. | |
182 CheckForPreviousSection(sections, | |
183 WasmSection::Code::FunctionSignatures, true); | |
184 int length; | 180 int length; |
185 const byte* pos = pc_; | 181 const byte* pos = pc_; |
186 uint32_t functions_count = consume_u32v(&length, "functions count"); | 182 uint32_t functions_count = consume_u32v(&length, "functions count"); |
187 if (functions_count != module->functions.size()) { | 183 if (functions_count != module->functions.size()) { |
188 error(pos, pos, "function body count %u mismatch (%u expected)", | 184 error(pos, pos, "function body count %u mismatch (%u expected)", |
189 functions_count, | 185 functions_count, |
190 static_cast<uint32_t>(module->functions.size())); | 186 static_cast<uint32_t>(module->functions.size())); |
191 break; | 187 break; |
192 } | 188 } |
193 for (uint32_t i = 0; i < functions_count; i++) { | 189 for (uint32_t i = 0; i < functions_count; i++) { |
194 WasmFunction* function = &module->functions[i]; | 190 WasmFunction* function = &module->functions[i]; |
195 int length; | 191 int length; |
196 uint32_t size = consume_u32v(&length, "body size"); | 192 uint32_t size = consume_u32v(&length, "body size"); |
197 function->code_start_offset = pc_offset(); | 193 function->code_start_offset = pc_offset(); |
198 function->code_end_offset = pc_offset() + size; | 194 function->code_end_offset = pc_offset() + size; |
199 | 195 |
200 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 196 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
201 size); | 197 size); |
202 pc_ += size; | 198 pc_ += size; |
203 if (pc_ > limit_) { | 199 if (pc_ > limit_) { |
204 error(pc_, "function body extends beyond end of file"); | 200 error(pc_, "function body extends beyond end of file"); |
205 } | 201 } |
206 } | 202 } |
207 break; | 203 break; |
208 } | 204 } |
209 case WasmSection::Code::Functions: { | 205 case WasmSection::Code::Functions: { |
210 // Functions require a signature table first. | |
211 CheckForPreviousSection(sections, WasmSection::Code::Signatures, | |
212 true); | |
213 int length; | 206 int length; |
214 uint32_t functions_count = consume_u32v(&length, "functions count"); | 207 uint32_t functions_count = consume_u32v(&length, "functions count"); |
215 module->functions.reserve(SafeReserve(functions_count)); | 208 module->functions.reserve(SafeReserve(functions_count)); |
216 // Set up module environment for verification. | 209 // Set up module environment for verification. |
217 ModuleEnv menv; | 210 ModuleEnv menv; |
218 menv.module = module; | 211 menv.module = module; |
219 menv.instance = nullptr; | 212 menv.instance = nullptr; |
220 menv.origin = origin_; | 213 menv.origin = origin_; |
221 // Decode functions. | 214 // Decode functions. |
222 for (uint32_t i = 0; i < functions_count; i++) { | 215 for (uint32_t i = 0; i < functions_count; i++) { |
(...skipping 13 matching lines...) Expand all Loading... | |
236 if (!function->external) { | 229 if (!function->external) { |
237 VerifyFunctionBody(i, &menv, function); | 230 VerifyFunctionBody(i, &menv, function); |
238 if (result_.failed()) | 231 if (result_.failed()) |
239 error(result_.error_pc, result_.error_msg.get()); | 232 error(result_.error_pc, result_.error_msg.get()); |
240 } | 233 } |
241 } | 234 } |
242 } | 235 } |
243 break; | 236 break; |
244 } | 237 } |
245 case WasmSection::Code::Names: { | 238 case WasmSection::Code::Names: { |
246 // Names correspond to functions. | |
247 CheckForPreviousSection(sections, | |
248 WasmSection::Code::FunctionSignatures, true); | |
249 int length; | 239 int length; |
250 const byte* pos = pc_; | 240 const byte* pos = pc_; |
251 uint32_t functions_count = consume_u32v(&length, "functions count"); | 241 uint32_t functions_count = consume_u32v(&length, "functions count"); |
252 if (functions_count != module->functions.size()) { | 242 if (functions_count != module->functions.size()) { |
253 error(pos, pos, "function name count %u mismatch (%u expected)", | 243 error(pos, pos, "function name count %u mismatch (%u expected)", |
254 functions_count, | 244 functions_count, |
255 static_cast<uint32_t>(module->functions.size())); | 245 static_cast<uint32_t>(module->functions.size())); |
256 break; | 246 break; |
257 } | 247 } |
258 | 248 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
334 WasmFunction* func; | 324 WasmFunction* func; |
335 const byte* pos = pc_; | 325 const byte* pos = pc_; |
336 module->start_function_index = consume_func_index(module, &func); | 326 module->start_function_index = consume_func_index(module, &func); |
337 if (func && func->sig->parameter_count() > 0) { | 327 if (func && func->sig->parameter_count() > 0) { |
338 error(pos, "invalid start function: non-zero parameter count"); | 328 error(pos, "invalid start function: non-zero parameter count"); |
339 break; | 329 break; |
340 } | 330 } |
341 break; | 331 break; |
342 } | 332 } |
343 case WasmSection::Code::ImportTable: { | 333 case WasmSection::Code::ImportTable: { |
344 // Declares an import table. | |
345 CheckForPreviousSection(sections, WasmSection::Code::Signatures, | |
346 true); | |
347 int length; | 334 int length; |
348 uint32_t import_table_count = | 335 uint32_t import_table_count = |
349 consume_u32v(&length, "import table count"); | 336 consume_u32v(&length, "import table count"); |
350 module->import_table.reserve(SafeReserve(import_table_count)); | 337 module->import_table.reserve(SafeReserve(import_table_count)); |
351 // Decode import table. | 338 // Decode import table. |
352 for (uint32_t i = 0; i < import_table_count; i++) { | 339 for (uint32_t i = 0; i < import_table_count; i++) { |
353 if (failed()) break; | 340 if (failed()) break; |
354 TRACE("DecodeImportTable[%d] module+%d\n", i, | 341 TRACE("DecodeImportTable[%d] module+%d\n", i, |
355 static_cast<int>(pc_ - start_)); | 342 static_cast<int>(pc_ - start_)); |
356 | 343 |
(...skipping 28 matching lines...) Expand all Loading... | |
385 module->export_table.push_back({0, 0}); | 372 module->export_table.push_back({0, 0}); |
386 WasmExport* exp = &module->export_table.back(); | 373 WasmExport* exp = &module->export_table.back(); |
387 | 374 |
388 WasmFunction* func; | 375 WasmFunction* func; |
389 exp->func_index = consume_func_index(module, &func); | 376 exp->func_index = consume_func_index(module, &func); |
390 exp->name_offset = consume_string(&exp->name_length, "export name"); | 377 exp->name_offset = consume_string(&exp->name_length, "export name"); |
391 } | 378 } |
392 break; | 379 break; |
393 } | 380 } |
394 case WasmSection::Code::Max: | 381 case WasmSection::Code::Max: |
395 UNREACHABLE(); // Already skipped unknown sections. | 382 // Skip unknown sections. |
383 TRACE("Unknown section: '"); | |
384 for (uint32_t i = 0; i != string_length; ++i) { | |
385 TRACE("%c", *(section_name_start + i)); | |
386 } | |
387 TRACE("'\n"); | |
388 consume_bytes(section_length - string_length - string_leb_length); | |
389 break; | |
390 } | |
391 | |
392 if (pc_ != expected_section_end) { | |
393 const char* diff = pc_ < expected_section_end ? "shorter" : "longer"; | |
394 size_t expected_length = static_cast<size_t>(section_length); | |
395 size_t actual_length = static_cast<size_t>(pc_ - section_start); | |
396 error(pc_, pc_, | |
397 "section \"%s\" %s (%zu bytes) than specified (%zu bytes)", | |
398 WasmSection::getName(section), diff, actual_length, | |
399 expected_length); | |
JF
2016/04/20 17:59:54
If section is Code::Max then it'll print a slightl
titzer
2016/04/21 10:59:22
Acknowledged.
| |
400 break; | |
396 } | 401 } |
397 } | 402 } |
398 | 403 |
399 done: | 404 done: |
400 ModuleResult result = toResult(module); | 405 ModuleResult result = toResult(module); |
401 if (FLAG_dump_wasm_module) { | 406 if (FLAG_dump_wasm_module) { |
402 DumpModule(module, result); | 407 DumpModule(module, result); |
403 } | 408 } |
404 return result; | 409 return result; |
405 } | 410 } |
406 | 411 |
407 uint32_t SafeReserve(uint32_t count) { | 412 uint32_t SafeReserve(uint32_t count) { |
408 // Avoid OOM by only reserving up to a certain size. | 413 // Avoid OOM by only reserving up to a certain size. |
409 const uint32_t kMaxReserve = 20000; | 414 const uint32_t kMaxReserve = 20000; |
410 return count < kMaxReserve ? count : kMaxReserve; | 415 return count < kMaxReserve ? count : kMaxReserve; |
411 } | 416 } |
412 | 417 |
413 void CheckForFunctions(WasmModule* module, WasmSection::Code section) { | 418 void CheckForFunctions(WasmModule* module, WasmSection::Code section) { |
414 if (module->functions.size() == 0) { | 419 if (module->functions.size() == 0) { |
415 error(pc_ - 1, nullptr, "functions must appear before section %s", | 420 error(pc_ - 1, nullptr, "functions must appear before section %s", |
416 WasmSection::getName(section)); | 421 WasmSection::getName(section)); |
417 } | 422 } |
418 } | 423 } |
419 | 424 |
420 void CheckForPreviousSection(bool* sections, WasmSection::Code section, | 425 int CheckSectionOrder(int current_order, WasmSection::Code section) { |
421 bool present) { | 426 if (section == WasmSection::Code::Max) return current_order; |
422 if (section >= WasmSection::Code::Max) return; | 427 int next_order = WasmSection::getOrder(section); |
423 if (sections[(size_t)section] == present) return; | 428 if (next_order == 0) return current_order; |
424 if (present) { | 429 if (next_order == current_order) { |
425 error(pc_ - 1, nullptr, "required %s section missing", | 430 error(pc_, pc_, "section \"%s\" already defined", |
426 WasmSection::getName(section)); | |
427 } else { | |
428 error(pc_ - 1, nullptr, "%s section already present", | |
429 WasmSection::getName(section)); | 431 WasmSection::getName(section)); |
430 } | 432 } |
433 if (next_order < current_order) { | |
434 error(pc_, pc_, "section \"%s\" out of order", | |
435 WasmSection::getName(section)); | |
436 } | |
437 return next_order; | |
431 } | 438 } |
432 | 439 |
433 // Decodes a single anonymous function starting at {start_}. | 440 // Decodes a single anonymous function starting at {start_}. |
434 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, | 441 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
435 WasmFunction* function) { | 442 WasmFunction* function) { |
436 pc_ = start_; | 443 pc_ = start_; |
437 function->sig = consume_sig(); // read signature | 444 function->sig = consume_sig(); // read signature |
438 function->name_offset = 0; // ---- name | 445 function->name_offset = 0; // ---- name |
439 function->name_length = 0; // ---- name length | 446 function->name_length = 0; // ---- name length |
440 function->code_start_offset = off(pc_); // ---- code start | 447 function->code_start_offset = off(pc_); // ---- code start |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
636 if (func_index >= module->functions.size()) { | 643 if (func_index >= module->functions.size()) { |
637 error(pos, pos, "function index %u out of bounds (%d functions)", | 644 error(pos, pos, "function index %u out of bounds (%d functions)", |
638 func_index, static_cast<int>(module->functions.size())); | 645 func_index, static_cast<int>(module->functions.size())); |
639 *func = nullptr; | 646 *func = nullptr; |
640 return 0; | 647 return 0; |
641 } | 648 } |
642 *func = &module->functions[func_index]; | 649 *func = &module->functions[func_index]; |
643 return func_index; | 650 return func_index; |
644 } | 651 } |
645 | 652 |
646 // Reads a section name. | |
647 WasmSection::Code consume_section_name(int* string_leb_length, | |
648 uint32_t* string_length) { | |
649 *string_length = consume_u32v(string_leb_length, "name length"); | |
650 const byte* start = pc_; | |
651 consume_bytes(*string_length); | |
652 if (failed()) { | |
653 TRACE("Section name of length %u couldn't be read\n", *string_length); | |
654 return WasmSection::Code::Max; | |
655 } | |
656 // TODO(jfb) Linear search, it may be better to do a common-prefix search. | |
657 for (WasmSection::Code i = WasmSection::begin(); i != WasmSection::end(); | |
658 i = WasmSection::next(i)) { | |
659 if (WasmSection::getNameLength(i) == *string_length && | |
660 0 == memcmp(WasmSection::getName(i), start, *string_length)) { | |
661 return i; | |
662 } | |
663 } | |
664 TRACE("Unknown section: '"); | |
665 for (uint32_t i = 0; i != *string_length; ++i) TRACE("%c", *(start + i)); | |
666 TRACE("'\n"); | |
667 return WasmSection::Code::Max; | |
668 } | |
669 | |
670 // Reads a single 8-bit integer, interpreting it as a local type. | 653 // Reads a single 8-bit integer, interpreting it as a local type. |
671 LocalType consume_local_type() { | 654 LocalType consume_local_type() { |
672 byte val = consume_u8("local type"); | 655 byte val = consume_u8("local type"); |
673 LocalTypeCode t = static_cast<LocalTypeCode>(val); | 656 LocalTypeCode t = static_cast<LocalTypeCode>(val); |
674 switch (t) { | 657 switch (t) { |
675 case kLocalVoid: | 658 case kLocalVoid: |
676 return kAstStmt; | 659 return kAstStmt; |
677 case kLocalI32: | 660 case kLocalI32: |
678 return kAstI32; | 661 return kAstI32; |
679 case kLocalI64: | 662 case kLocalI64: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 return FunctionError("size > maximum function size"); | 787 return FunctionError("size > maximum function size"); |
805 isolate->counters()->wasm_function_size_bytes()->AddSample( | 788 isolate->counters()->wasm_function_size_bytes()->AddSample( |
806 static_cast<int>(size)); | 789 static_cast<int>(size)); |
807 WasmFunction* function = new WasmFunction(); | 790 WasmFunction* function = new WasmFunction(); |
808 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 791 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
809 return decoder.DecodeSingleFunction(module_env, function); | 792 return decoder.DecodeSingleFunction(module_env, function); |
810 } | 793 } |
811 } // namespace wasm | 794 } // namespace wasm |
812 } // namespace internal | 795 } // namespace internal |
813 } // namespace v8 | 796 } // namespace v8 |
OLD | NEW |