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/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
6 #include "src/objects.h" | 6 #include "src/objects.h" |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/wasm/decoder.h" | 9 #include "src/wasm/decoder.h" |
10 #include "src/wasm/module-decoder.h" | 10 #include "src/wasm/module-decoder.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 module->data_segments = new std::vector<WasmDataSegment>(); | 55 module->data_segments = new std::vector<WasmDataSegment>(); |
56 module->function_table = new std::vector<uint16_t>(); | 56 module->function_table = new std::vector<uint16_t>(); |
57 | 57 |
58 bool sections[kMaxModuleSectionCode]; | 58 bool sections[kMaxModuleSectionCode]; |
59 memset(sections, 0, sizeof(sections)); | 59 memset(sections, 0, sizeof(sections)); |
60 | 60 |
61 // Decode the module sections. | 61 // Decode the module sections. |
62 while (pc_ < limit_) { | 62 while (pc_ < limit_) { |
63 TRACE("DecodeSection\n"); | 63 TRACE("DecodeSection\n"); |
64 WasmSectionDeclCode section = | 64 WasmSectionDeclCode section = |
65 static_cast<WasmSectionDeclCode>(u8("section")); | 65 static_cast<WasmSectionDeclCode>(consume_u8("section")); |
66 // Each section should appear at most once. | 66 // Each section should appear at most once. |
67 if (section < kMaxModuleSectionCode) { | 67 if (section < kMaxModuleSectionCode) { |
68 CheckForPreviousSection(sections, section, false); | 68 CheckForPreviousSection(sections, section, false); |
69 sections[section] = true; | 69 sections[section] = true; |
70 } | 70 } |
71 | 71 |
72 switch (section) { | 72 switch (section) { |
73 case kDeclEnd: | 73 case kDeclEnd: |
74 // Terminate section decoding. | 74 // Terminate section decoding. |
75 limit_ = pc_; | 75 limit_ = pc_; |
76 break; | 76 break; |
77 case kDeclMemory: | 77 case kDeclMemory: |
78 module->min_mem_size_log2 = u8("min memory"); | 78 module->min_mem_size_log2 = consume_u8("min memory"); |
79 module->max_mem_size_log2 = u8("max memory"); | 79 module->max_mem_size_log2 = consume_u8("max memory"); |
80 module->mem_export = u8("export memory") != 0; | 80 module->mem_export = consume_u8("export memory") != 0; |
81 break; | 81 break; |
82 case kDeclSignatures: { | 82 case kDeclSignatures: { |
83 int length; | 83 int length; |
84 uint32_t signatures_count = u32v(&length, "signatures count"); | 84 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
85 module->signatures->reserve(SafeReserve(signatures_count)); | 85 module->signatures->reserve(SafeReserve(signatures_count)); |
86 // Decode signatures. | 86 // Decode signatures. |
87 for (uint32_t i = 0; i < signatures_count; i++) { | 87 for (uint32_t i = 0; i < signatures_count; i++) { |
88 if (failed()) break; | 88 if (failed()) break; |
89 TRACE("DecodeSignature[%d] module+%d\n", i, | 89 TRACE("DecodeSignature[%d] module+%d\n", i, |
90 static_cast<int>(pc_ - start_)); | 90 static_cast<int>(pc_ - start_)); |
91 FunctionSig* s = sig(); // read function sig. | 91 FunctionSig* s = consume_sig(); // read function sig. |
92 module->signatures->push_back(s); | 92 module->signatures->push_back(s); |
93 } | 93 } |
94 break; | 94 break; |
95 } | 95 } |
96 case kDeclFunctions: { | 96 case kDeclFunctions: { |
97 // Functions require a signature table first. | 97 // Functions require a signature table first. |
98 CheckForPreviousSection(sections, kDeclSignatures, true); | 98 CheckForPreviousSection(sections, kDeclSignatures, true); |
99 int length; | 99 int length; |
100 uint32_t functions_count = u32v(&length, "functions count"); | 100 uint32_t functions_count = consume_u32v(&length, "functions count"); |
101 module->functions->reserve(SafeReserve(functions_count)); | 101 module->functions->reserve(SafeReserve(functions_count)); |
102 // Set up module environment for verification. | 102 // Set up module environment for verification. |
103 ModuleEnv menv; | 103 ModuleEnv menv; |
104 menv.module = module; | 104 menv.module = module; |
105 menv.instance = nullptr; | 105 menv.instance = nullptr; |
106 menv.asm_js = asm_js_; | 106 menv.asm_js = asm_js_; |
107 // Decode functions. | 107 // Decode functions. |
108 for (uint32_t i = 0; i < functions_count; i++) { | 108 for (uint32_t i = 0; i < functions_count; i++) { |
109 if (failed()) break; | 109 if (failed()) break; |
110 TRACE("DecodeFunction[%d] module+%d\n", i, | 110 TRACE("DecodeFunction[%d] module+%d\n", i, |
(...skipping 12 matching lines...) Expand all Loading... | |
123 VerifyFunctionBody(i, &menv, function); | 123 VerifyFunctionBody(i, &menv, function); |
124 if (result_.failed()) | 124 if (result_.failed()) |
125 error(result_.error_pc, result_.error_msg.get()); | 125 error(result_.error_pc, result_.error_msg.get()); |
126 } | 126 } |
127 } | 127 } |
128 } | 128 } |
129 break; | 129 break; |
130 } | 130 } |
131 case kDeclGlobals: { | 131 case kDeclGlobals: { |
132 int length; | 132 int length; |
133 uint32_t globals_count = u32v(&length, "globals count"); | 133 uint32_t globals_count = consume_u32v(&length, "globals count"); |
134 module->globals->reserve(SafeReserve(globals_count)); | 134 module->globals->reserve(SafeReserve(globals_count)); |
135 // Decode globals. | 135 // Decode globals. |
136 for (uint32_t i = 0; i < globals_count; i++) { | 136 for (uint32_t i = 0; i < globals_count; i++) { |
137 if (failed()) break; | 137 if (failed()) break; |
138 TRACE("DecodeGlobal[%d] module+%d\n", i, | 138 TRACE("DecodeGlobal[%d] module+%d\n", i, |
139 static_cast<int>(pc_ - start_)); | 139 static_cast<int>(pc_ - start_)); |
140 module->globals->push_back({0, MachineType::Int32(), 0, false}); | 140 module->globals->push_back({0, MachineType::Int32(), 0, false}); |
141 WasmGlobal* global = &module->globals->back(); | 141 WasmGlobal* global = &module->globals->back(); |
142 DecodeGlobalInModule(global); | 142 DecodeGlobalInModule(global); |
143 } | 143 } |
144 break; | 144 break; |
145 } | 145 } |
146 case kDeclDataSegments: { | 146 case kDeclDataSegments: { |
147 int length; | 147 int length; |
148 uint32_t data_segments_count = u32v(&length, "data segments count"); | 148 uint32_t data_segments_count = |
149 consume_u32v(&length, "data segments count"); | |
149 module->data_segments->reserve(SafeReserve(data_segments_count)); | 150 module->data_segments->reserve(SafeReserve(data_segments_count)); |
150 // Decode data segments. | 151 // Decode data segments. |
151 for (uint32_t i = 0; i < data_segments_count; i++) { | 152 for (uint32_t i = 0; i < data_segments_count; i++) { |
152 if (failed()) break; | 153 if (failed()) break; |
153 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 154 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
154 static_cast<int>(pc_ - start_)); | 155 static_cast<int>(pc_ - start_)); |
155 module->data_segments->push_back({0, 0, 0}); | 156 module->data_segments->push_back({0, 0, 0}); |
156 WasmDataSegment* segment = &module->data_segments->back(); | 157 WasmDataSegment* segment = &module->data_segments->back(); |
157 DecodeDataSegmentInModule(module, segment); | 158 DecodeDataSegmentInModule(module, segment); |
158 } | 159 } |
159 break; | 160 break; |
160 } | 161 } |
161 case kDeclFunctionTable: { | 162 case kDeclFunctionTable: { |
162 // An indirect function table requires functions first. | 163 // An indirect function table requires functions first. |
163 CheckForPreviousSection(sections, kDeclFunctions, true); | 164 CheckForPreviousSection(sections, kDeclFunctions, true); |
164 int length; | 165 int length; |
165 uint32_t function_table_count = u32v(&length, "function table count"); | 166 uint32_t function_table_count = |
167 consume_u32v(&length, "function table count"); | |
166 module->function_table->reserve(SafeReserve(function_table_count)); | 168 module->function_table->reserve(SafeReserve(function_table_count)); |
167 // Decode function table. | 169 // Decode function table. |
168 for (uint32_t i = 0; i < function_table_count; i++) { | 170 for (uint32_t i = 0; i < function_table_count; i++) { |
169 if (failed()) break; | 171 if (failed()) break; |
170 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 172 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
171 static_cast<int>(pc_ - start_)); | 173 static_cast<int>(pc_ - start_)); |
172 uint16_t index = u16(); | 174 uint16_t index = consume_u16(); |
173 if (index >= module->functions->size()) { | 175 if (index >= module->functions->size()) { |
174 error(pc_ - 2, "invalid function index"); | 176 error(pc_ - 2, "invalid function index"); |
175 break; | 177 break; |
176 } | 178 } |
177 module->function_table->push_back(index); | 179 module->function_table->push_back(index); |
178 } | 180 } |
179 break; | 181 break; |
180 } | 182 } |
181 case kDeclWLL: { | 183 case kDeclWLL: { |
182 // Reserved for experimentation by the Web Low-level Language project | 184 // Reserved for experimentation by the Web Low-level Language project |
183 // which is augmenting the binary encoding with source code meta | 185 // which is augmenting the binary encoding with source code meta |
184 // information. This section does not affect the semantics of the code | 186 // information. This section does not affect the semantics of the code |
185 // and can be ignored by the runtime. https://github.com/JSStats/wll | 187 // and can be ignored by the runtime. https://github.com/JSStats/wll |
186 int length = 0; | 188 int length = 0; |
187 uint32_t section_size = u32v(&length, "section size"); | 189 uint32_t section_size = consume_u32v(&length, "section size"); |
188 if (pc_ + section_size > limit_ || pc_ + section_size < pc_) { | 190 if (pc_ + section_size > limit_ || pc_ + section_size < pc_) { |
189 error(pc_ - length, "invalid section size"); | 191 error(pc_ - length, "invalid section size"); |
190 break; | 192 break; |
191 } | 193 } |
192 pc_ += section_size; | 194 pc_ += section_size; |
193 break; | 195 break; |
194 } | 196 } |
195 default: | 197 default: |
196 error(pc_ - 1, nullptr, "unrecognized section 0x%02x", section); | 198 error(pc_ - 1, nullptr, "unrecognized section 0x%02x", section); |
197 break; | 199 break; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 error(pc_ - 1, nullptr, "required %s section missing", name); | 241 error(pc_ - 1, nullptr, "required %s section missing", name); |
240 } else { | 242 } else { |
241 error(pc_ - 1, nullptr, "%s section already present", name); | 243 error(pc_ - 1, nullptr, "%s section already present", name); |
242 } | 244 } |
243 } | 245 } |
244 | 246 |
245 // Decodes a single anonymous function starting at {start_}. | 247 // Decodes a single anonymous function starting at {start_}. |
246 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, | 248 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
247 WasmFunction* function) { | 249 WasmFunction* function) { |
248 pc_ = start_; | 250 pc_ = start_; |
249 function->sig = sig(); // read signature | 251 function->sig = consume_sig(); // read signature |
250 function->name_offset = 0; // ---- name | 252 function->name_offset = 0; // ---- name |
251 function->code_start_offset = off(pc_ + 8); // ---- code start | 253 function->code_start_offset = off(pc_ + 8); // ---- code start |
252 function->code_end_offset = off(limit_); // ---- code end | 254 function->code_end_offset = off(limit_); // ---- code end |
253 function->local_int32_count = u16(); // read u16 | 255 function->local_int32_count = consume_u16(); // read u16 |
254 function->local_int64_count = u16(); // read u16 | 256 function->local_int64_count = consume_u16(); // read u16 |
255 function->local_float32_count = u16(); // read u16 | 257 function->local_float32_count = consume_u16(); // read u16 |
256 function->local_float64_count = u16(); // read u16 | 258 function->local_float64_count = consume_u16(); // read u16 |
257 function->exported = false; // ---- exported | 259 function->exported = false; // ---- exported |
258 function->external = false; // ---- external | 260 function->external = false; // ---- external |
259 | 261 |
260 if (ok()) VerifyFunctionBody(0, module_env, function); | 262 if (ok()) VerifyFunctionBody(0, module_env, function); |
261 | 263 |
262 FunctionResult result; | 264 FunctionResult result; |
263 result.CopyFrom(result_); // Copy error code and location. | 265 result.CopyFrom(result_); // Copy error code and location. |
264 result.val = function; | 266 result.val = function; |
265 return result; | 267 return result; |
266 } | 268 } |
267 | 269 |
268 // Decodes a single function signature at {start}. | 270 // Decodes a single function signature at {start}. |
269 FunctionSig* DecodeFunctionSignature(const byte* start) { | 271 FunctionSig* DecodeFunctionSignature(const byte* start) { |
270 pc_ = start; | 272 pc_ = start; |
271 FunctionSig* result = sig(); | 273 FunctionSig* result = consume_sig(); |
272 return ok() ? result : nullptr; | 274 return ok() ? result : nullptr; |
273 } | 275 } |
274 | 276 |
275 private: | 277 private: |
276 Zone* module_zone; | 278 Zone* module_zone; |
277 ModuleResult result_; | 279 ModuleResult result_; |
278 bool asm_js_; | 280 bool asm_js_; |
279 | 281 |
280 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } | 282 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } |
281 | 283 |
282 // Decodes a single global entry inside a module starting at {pc_}. | 284 // Decodes a single global entry inside a module starting at {pc_}. |
283 void DecodeGlobalInModule(WasmGlobal* global) { | 285 void DecodeGlobalInModule(WasmGlobal* global) { |
284 global->name_offset = string("global name"); | 286 global->name_offset = consume_string("global name"); |
285 global->type = mem_type(); | 287 global->type = mem_type(); |
286 global->offset = 0; | 288 global->offset = 0; |
287 global->exported = u8("exported") != 0; | 289 global->exported = consume_u8("exported") != 0; |
288 } | 290 } |
289 | 291 |
290 // Decodes a single function entry inside a module starting at {pc_}. | 292 // Decodes a single function entry inside a module starting at {pc_}. |
291 void DecodeFunctionInModule(WasmModule* module, WasmFunction* function, | 293 void DecodeFunctionInModule(WasmModule* module, WasmFunction* function, |
292 bool verify_body = true) { | 294 bool verify_body = true) { |
293 byte decl_bits = u8("function decl"); | 295 byte decl_bits = consume_u8("function decl"); |
294 | 296 |
295 const byte* sigpos = pc_; | 297 const byte* sigpos = pc_; |
296 function->sig_index = u16("signature index"); | 298 function->sig_index = consume_u16("signature index"); |
297 | 299 |
298 if (function->sig_index >= module->signatures->size()) { | 300 if (function->sig_index >= module->signatures->size()) { |
299 return error(sigpos, "invalid signature index"); | 301 return error(sigpos, "invalid signature index"); |
300 } else { | 302 } else { |
301 function->sig = module->signatures->at(function->sig_index); | 303 function->sig = module->signatures->at(function->sig_index); |
302 } | 304 } |
303 | 305 |
304 TRACE(" +%d <function attributes:%s%s%s%s%s>\n", | 306 TRACE(" +%d <function attributes:%s%s%s%s%s>\n", |
305 static_cast<int>(pc_ - start_), | 307 static_cast<int>(pc_ - start_), |
306 decl_bits & kDeclFunctionName ? " name" : "", | 308 decl_bits & kDeclFunctionName ? " name" : "", |
307 decl_bits & kDeclFunctionImport ? " imported" : "", | 309 decl_bits & kDeclFunctionImport ? " imported" : "", |
308 decl_bits & kDeclFunctionLocals ? " locals" : "", | 310 decl_bits & kDeclFunctionLocals ? " locals" : "", |
309 decl_bits & kDeclFunctionExport ? " exported" : "", | 311 decl_bits & kDeclFunctionExport ? " exported" : "", |
310 (decl_bits & kDeclFunctionImport) == 0 ? " body" : ""); | 312 (decl_bits & kDeclFunctionImport) == 0 ? " body" : ""); |
311 | 313 |
312 if (decl_bits & kDeclFunctionName) { | 314 if (decl_bits & kDeclFunctionName) { |
313 function->name_offset = string("function name"); | 315 function->name_offset = consume_string("function name"); |
314 } | 316 } |
315 | 317 |
316 function->exported = decl_bits & kDeclFunctionExport; | 318 function->exported = decl_bits & kDeclFunctionExport; |
317 | 319 |
318 // Imported functions have no locals or body. | 320 // Imported functions have no locals or body. |
319 if (decl_bits & kDeclFunctionImport) { | 321 if (decl_bits & kDeclFunctionImport) { |
320 function->external = true; | 322 function->external = true; |
321 return; | 323 return; |
322 } | 324 } |
323 | 325 |
324 if (decl_bits & kDeclFunctionLocals) { | 326 if (decl_bits & kDeclFunctionLocals) { |
325 function->local_int32_count = u16("int32 count"); | 327 function->local_int32_count = consume_u16("int32 count"); |
326 function->local_int64_count = u16("int64 count"); | 328 function->local_int64_count = consume_u16("int64 count"); |
327 function->local_float32_count = u16("float32 count"); | 329 function->local_float32_count = consume_u16("float32 count"); |
328 function->local_float64_count = u16("float64 count"); | 330 function->local_float64_count = consume_u16("float64 count"); |
329 } | 331 } |
330 | 332 |
331 uint16_t size = u16("body size"); | 333 uint16_t size = consume_u16("body size"); |
332 if (ok()) { | 334 if (ok()) { |
333 if ((pc_ + size) > limit_) { | 335 if ((pc_ + size) > limit_) { |
334 return error(pc_, limit_, | 336 return error(pc_, limit_, |
335 "expected %d bytes for function body, fell off end", size); | 337 "expected %d bytes for function body, fell off end", size); |
336 } | 338 } |
337 function->code_start_offset = static_cast<uint32_t>(pc_ - start_); | 339 function->code_start_offset = static_cast<uint32_t>(pc_ - start_); |
338 function->code_end_offset = function->code_start_offset + size; | 340 function->code_end_offset = function->code_start_offset + size; |
339 TRACE(" +%d %-20s: (%d bytes)\n", static_cast<int>(pc_ - start_), | 341 TRACE(" +%d %-20s: (%d bytes)\n", static_cast<int>(pc_ - start_), |
340 "function body", size); | 342 "function body", size); |
341 pc_ += size; | 343 pc_ += size; |
342 } | 344 } |
343 } | 345 } |
344 | 346 |
345 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { | 347 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { |
346 if (offset > limit) return false; | 348 if (offset > limit) return false; |
347 if ((offset + size) < offset) return false; // overflow | 349 if ((offset + size) < offset) return false; // overflow |
348 return (offset + size) <= limit; | 350 return (offset + size) <= limit; |
349 } | 351 } |
350 | 352 |
351 // Decodes a single data segment entry inside a module starting at {pc_}. | 353 // Decodes a single data segment entry inside a module starting at {pc_}. |
352 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { | 354 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
353 segment->dest_addr = u32("destination"); | 355 segment->dest_addr = consume_u32("destination"); |
354 segment->source_offset = offset("source offset"); | 356 segment->source_offset = consume_offset("source offset"); |
355 segment->source_size = u32("source size"); | 357 segment->source_size = consume_u32("source size"); |
356 segment->init = u8("init"); | 358 segment->init = consume_u8("init"); |
357 | 359 |
358 // Validate the data is in the module. | 360 // Validate the data is in the module. |
359 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); | 361 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); |
360 if (!IsWithinLimit(module_limit, segment->source_offset, | 362 if (!IsWithinLimit(module_limit, segment->source_offset, |
361 segment->source_size)) { | 363 segment->source_size)) { |
362 error(pc_ - sizeof(uint32_t), "segment out of bounds of module"); | 364 error(pc_ - sizeof(uint32_t), "segment out of bounds of module"); |
363 } | 365 } |
364 | 366 |
365 // Validate that the segment will fit into the (minimum) memory. | 367 // Validate that the segment will fit into the (minimum) memory. |
366 uint32_t memory_limit = | 368 uint32_t memory_limit = |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 buffer[len - 1] = 0; | 411 buffer[len - 1] = 0; |
410 | 412 |
411 // Copy error code and location. | 413 // Copy error code and location. |
412 result_.CopyFrom(result); | 414 result_.CopyFrom(result); |
413 result_.error_msg.Reset(buffer); | 415 result_.error_msg.Reset(buffer); |
414 } | 416 } |
415 } | 417 } |
416 | 418 |
417 // Reads a single 32-bit unsigned integer interpreted as an offset, checking | 419 // Reads a single 32-bit unsigned integer interpreted as an offset, checking |
418 // the offset is within bounds and advances. | 420 // the offset is within bounds and advances. |
419 uint32_t offset(const char* name = nullptr) { | 421 uint32_t consume_offset(const char* name = nullptr) { |
420 uint32_t offset = u32(name ? name : "offset"); | 422 uint32_t offset = consume_u32(name ? name : "offset"); |
421 if (offset > static_cast<uint32_t>(limit_ - start_)) { | 423 if (offset > static_cast<uint32_t>(limit_ - start_)) { |
422 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); | 424 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); |
423 } | 425 } |
424 return offset; | 426 return offset; |
425 } | 427 } |
426 | 428 |
427 // Reads a single 32-bit unsigned integer interpreted as an offset into the | 429 // Reads a single 32-bit unsigned integer interpreted as an offset into the |
428 // data and validating the string there and advances. | 430 // data and validating the string there and advances. |
429 uint32_t string(const char* name = nullptr) { | 431 uint32_t consume_string(const char* name = nullptr) { |
430 return offset(name ? name : "string"); // TODO(titzer): validate string | 432 return consume_offset(name ? name |
433 : "string"); // TODO(titzer): validate string | |
ahaas
2016/01/28 18:58:33
Put the comment into a separate line, so that the
| |
431 } | 434 } |
432 | 435 |
433 // Reads a single 8-bit integer, interpreting it as a local type. | 436 // Reads a single 8-bit integer, interpreting it as a local type. |
434 LocalType local_type() { | 437 LocalType consume_local_type() { |
435 byte val = u8("local type"); | 438 byte val = consume_u8("local type"); |
436 LocalTypeCode t = static_cast<LocalTypeCode>(val); | 439 LocalTypeCode t = static_cast<LocalTypeCode>(val); |
437 switch (t) { | 440 switch (t) { |
438 case kLocalVoid: | 441 case kLocalVoid: |
439 return kAstStmt; | 442 return kAstStmt; |
440 case kLocalI32: | 443 case kLocalI32: |
441 return kAstI32; | 444 return kAstI32; |
442 case kLocalI64: | 445 case kLocalI64: |
443 return kAstI64; | 446 return kAstI64; |
444 case kLocalF32: | 447 case kLocalF32: |
445 return kAstF32; | 448 return kAstF32; |
446 case kLocalF64: | 449 case kLocalF64: |
447 return kAstF64; | 450 return kAstF64; |
448 default: | 451 default: |
449 error(pc_ - 1, "invalid local type"); | 452 error(pc_ - 1, "invalid local type"); |
450 return kAstStmt; | 453 return kAstStmt; |
451 } | 454 } |
452 } | 455 } |
453 | 456 |
454 // Reads a single 8-bit integer, interpreting it as a memory type. | 457 // Reads a single 8-bit integer, interpreting it as a memory type. |
455 MachineType mem_type() { | 458 MachineType mem_type() { |
456 byte val = u8("memory type"); | 459 byte val = consume_u8("memory type"); |
457 MemTypeCode t = static_cast<MemTypeCode>(val); | 460 MemTypeCode t = static_cast<MemTypeCode>(val); |
458 switch (t) { | 461 switch (t) { |
459 case kMemI8: | 462 case kMemI8: |
460 return MachineType::Int8(); | 463 return MachineType::Int8(); |
461 case kMemU8: | 464 case kMemU8: |
462 return MachineType::Uint8(); | 465 return MachineType::Uint8(); |
463 case kMemI16: | 466 case kMemI16: |
464 return MachineType::Int16(); | 467 return MachineType::Int16(); |
465 case kMemU16: | 468 case kMemU16: |
466 return MachineType::Uint16(); | 469 return MachineType::Uint16(); |
467 case kMemI32: | 470 case kMemI32: |
468 return MachineType::Int32(); | 471 return MachineType::Int32(); |
469 case kMemU32: | 472 case kMemU32: |
470 return MachineType::Uint32(); | 473 return MachineType::Uint32(); |
471 case kMemI64: | 474 case kMemI64: |
472 return MachineType::Int64(); | 475 return MachineType::Int64(); |
473 case kMemU64: | 476 case kMemU64: |
474 return MachineType::Uint64(); | 477 return MachineType::Uint64(); |
475 case kMemF32: | 478 case kMemF32: |
476 return MachineType::Float32(); | 479 return MachineType::Float32(); |
477 case kMemF64: | 480 case kMemF64: |
478 return MachineType::Float64(); | 481 return MachineType::Float64(); |
479 default: | 482 default: |
480 error(pc_ - 1, "invalid memory type"); | 483 error(pc_ - 1, "invalid memory type"); |
481 return MachineType::None(); | 484 return MachineType::None(); |
482 } | 485 } |
483 } | 486 } |
484 | 487 |
485 // Parses an inline function signature. | 488 // Parses an inline function signature. |
486 FunctionSig* sig() { | 489 FunctionSig* consume_sig() { |
487 byte count = u8("param count"); | 490 byte count = consume_u8("param count"); |
488 LocalType ret = local_type(); | 491 LocalType ret = consume_local_type(); |
489 FunctionSig::Builder builder(module_zone, ret == kAstStmt ? 0 : 1, count); | 492 FunctionSig::Builder builder(module_zone, ret == kAstStmt ? 0 : 1, count); |
490 if (ret != kAstStmt) builder.AddReturn(ret); | 493 if (ret != kAstStmt) builder.AddReturn(ret); |
491 | 494 |
492 for (int i = 0; i < count; i++) { | 495 for (int i = 0; i < count; i++) { |
493 LocalType param = local_type(); | 496 LocalType param = consume_local_type(); |
494 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 497 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
495 builder.AddParam(param); | 498 builder.AddParam(param); |
496 } | 499 } |
497 return builder.Build(); | 500 return builder.Build(); |
498 } | 501 } |
499 }; | 502 }; |
500 | 503 |
501 | 504 |
502 // Helpers for nice error messages. | 505 // Helpers for nice error messages. |
503 class ModuleError : public ModuleResult { | 506 class ModuleError : public ModuleResult { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 if (function_start > function_end) return FunctionError("start > end"); | 557 if (function_start > function_end) return FunctionError("start > end"); |
555 if (size > kMaxFunctionSize) | 558 if (size > kMaxFunctionSize) |
556 return FunctionError("size > maximum function size"); | 559 return FunctionError("size > maximum function size"); |
557 WasmFunction* function = new WasmFunction(); | 560 WasmFunction* function = new WasmFunction(); |
558 ModuleDecoder decoder(zone, function_start, function_end, false); | 561 ModuleDecoder decoder(zone, function_start, function_end, false); |
559 return decoder.DecodeSingleFunction(module_env, function); | 562 return decoder.DecodeSingleFunction(module_env, function); |
560 } | 563 } |
561 } // namespace wasm | 564 } // namespace wasm |
562 } // namespace internal | 565 } // namespace internal |
563 } // namespace v8 | 566 } // namespace v8 |
OLD | NEW |