Chromium Code Reviews| 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 |