| 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" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 goto done; | 101 goto done; |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 // Decode the module sections. | 105 // Decode the module sections. |
| 106 while (pc_ < limit_) { | 106 while (pc_ < limit_) { |
| 107 TRACE("DecodeSection\n"); | 107 TRACE("DecodeSection\n"); |
| 108 pos = pc_; | 108 pos = pc_; |
| 109 | 109 |
| 110 // Read the section name. | 110 // Read the section name. |
| 111 int string_leb_length = 0; | 111 unsigned string_leb_length = 0; |
| 112 uint32_t string_length = | 112 uint32_t string_length = |
| 113 consume_u32v(&string_leb_length, "section name length"); | 113 consume_u32v(&string_leb_length, "section name length"); |
| 114 const byte* section_name_start = pc_; | 114 const byte* section_name_start = pc_; |
| 115 consume_bytes(string_length); | 115 consume_bytes(string_length); |
| 116 if (failed()) { | 116 if (failed()) { |
| 117 TRACE("Section name of length %u couldn't be read\n", string_length); | 117 TRACE("Section name of length %u couldn't be read\n", string_length); |
| 118 break; | 118 break; |
| 119 } | 119 } |
| 120 | 120 |
| 121 TRACE(" +%d section name : \"%.*s\"\n", | 121 TRACE(" +%d section name : \"%.*s\"\n", |
| 122 static_cast<int>(section_name_start - start_), | 122 static_cast<int>(section_name_start - start_), |
| 123 string_length < 20 ? string_length : 20, section_name_start); | 123 string_length < 20 ? string_length : 20, section_name_start); |
| 124 | 124 |
| 125 WasmSection::Code section = | 125 WasmSection::Code section = |
| 126 WasmSection::lookup(section_name_start, string_length); | 126 WasmSection::lookup(section_name_start, string_length); |
| 127 | 127 |
| 128 // Read and check the section size. | 128 // Read and check the section size. |
| 129 int section_leb_length = 0; | 129 unsigned section_leb_length = 0; |
| 130 uint32_t section_length = | 130 uint32_t section_length = |
| 131 consume_u32v(§ion_leb_length, "section length"); | 131 consume_u32v(§ion_leb_length, "section length"); |
| 132 if (!checkAvailable(section_length)) { | 132 if (!checkAvailable(section_length)) { |
| 133 // The section would extend beyond the end of the module. | 133 // The section would extend beyond the end of the module. |
| 134 break; | 134 break; |
| 135 } | 135 } |
| 136 const byte* section_start = pc_; | 136 const byte* section_start = pc_; |
| 137 const byte* expected_section_end = pc_ + section_length; | 137 const byte* expected_section_end = pc_ + section_length; |
| 138 | 138 |
| 139 current_order = CheckSectionOrder(current_order, section); | 139 current_order = CheckSectionOrder(current_order, section); |
| 140 | 140 |
| 141 switch (section) { | 141 switch (section) { |
| 142 case WasmSection::Code::End: | 142 case WasmSection::Code::End: |
| 143 // Terminate section decoding. | 143 // Terminate section decoding. |
| 144 limit_ = pc_; | 144 limit_ = pc_; |
| 145 break; | 145 break; |
| 146 case WasmSection::Code::Memory: { | 146 case WasmSection::Code::Memory: { |
| 147 int length; | 147 unsigned length; |
| 148 module->min_mem_pages = consume_u32v(&length, "min memory"); | 148 module->min_mem_pages = consume_u32v(&length, "min memory"); |
| 149 module->max_mem_pages = consume_u32v(&length, "max memory"); | 149 module->max_mem_pages = consume_u32v(&length, "max memory"); |
| 150 module->mem_export = consume_u8("export memory") != 0; | 150 module->mem_export = consume_u8("export memory") != 0; |
| 151 break; | 151 break; |
| 152 } | 152 } |
| 153 case WasmSection::Code::Signatures: { | 153 case WasmSection::Code::Signatures: { |
| 154 int length; | 154 unsigned length; |
| 155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
| 156 module->signatures.reserve(SafeReserve(signatures_count)); | 156 module->signatures.reserve(SafeReserve(signatures_count)); |
| 157 // Decode signatures. | 157 // Decode signatures. |
| 158 for (uint32_t i = 0; i < signatures_count; i++) { | 158 for (uint32_t i = 0; i < signatures_count; i++) { |
| 159 if (failed()) break; | 159 if (failed()) break; |
| 160 TRACE("DecodeSignature[%d] module+%d\n", i, | 160 TRACE("DecodeSignature[%d] module+%d\n", i, |
| 161 static_cast<int>(pc_ - start_)); | 161 static_cast<int>(pc_ - start_)); |
| 162 FunctionSig* s = consume_sig(); | 162 FunctionSig* s = consume_sig(); |
| 163 module->signatures.push_back(s); | 163 module->signatures.push_back(s); |
| 164 } | 164 } |
| 165 break; | 165 break; |
| 166 } | 166 } |
| 167 case WasmSection::Code::FunctionSignatures: { | 167 case WasmSection::Code::FunctionSignatures: { |
| 168 int length; | 168 unsigned length; |
| 169 uint32_t functions_count = consume_u32v(&length, "functions count"); | 169 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 170 module->functions.reserve(SafeReserve(functions_count)); | 170 module->functions.reserve(SafeReserve(functions_count)); |
| 171 for (uint32_t i = 0; i < functions_count; i++) { | 171 for (uint32_t i = 0; i < functions_count; i++) { |
| 172 module->functions.push_back({nullptr, // sig | 172 module->functions.push_back({nullptr, // sig |
| 173 i, // func_index | 173 i, // func_index |
| 174 0, // sig_index | 174 0, // sig_index |
| 175 0, // name_offset | 175 0, // name_offset |
| 176 0, // name_length | 176 0, // name_length |
| 177 0, // code_start_offset | 177 0, // code_start_offset |
| 178 0}); // code_end_offset | 178 0}); // code_end_offset |
| 179 WasmFunction* function = &module->functions.back(); | 179 WasmFunction* function = &module->functions.back(); |
| 180 function->sig_index = consume_sig_index(module, &function->sig); | 180 function->sig_index = consume_sig_index(module, &function->sig); |
| 181 } | 181 } |
| 182 break; | 182 break; |
| 183 } | 183 } |
| 184 case WasmSection::Code::FunctionBodies: { | 184 case WasmSection::Code::FunctionBodies: { |
| 185 int length; | 185 unsigned length; |
| 186 const byte* pos = pc_; | 186 const byte* pos = pc_; |
| 187 uint32_t functions_count = consume_u32v(&length, "functions count"); | 187 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 188 if (functions_count != module->functions.size()) { | 188 if (functions_count != module->functions.size()) { |
| 189 error(pos, pos, "function body count %u mismatch (%u expected)", | 189 error(pos, pos, "function body count %u mismatch (%u expected)", |
| 190 functions_count, | 190 functions_count, |
| 191 static_cast<uint32_t>(module->functions.size())); | 191 static_cast<uint32_t>(module->functions.size())); |
| 192 break; | 192 break; |
| 193 } | 193 } |
| 194 for (uint32_t i = 0; i < functions_count; i++) { | 194 for (uint32_t i = 0; i < functions_count; i++) { |
| 195 WasmFunction* function = &module->functions[i]; | 195 WasmFunction* function = &module->functions[i]; |
| 196 int length; | 196 unsigned length; |
| 197 uint32_t size = consume_u32v(&length, "body size"); | 197 uint32_t size = consume_u32v(&length, "body size"); |
| 198 function->code_start_offset = pc_offset(); | 198 function->code_start_offset = pc_offset(); |
| 199 function->code_end_offset = pc_offset() + size; | 199 function->code_end_offset = pc_offset() + size; |
| 200 | 200 |
| 201 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 201 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
| 202 size); | 202 size); |
| 203 pc_ += size; | 203 pc_ += size; |
| 204 if (pc_ > limit_) { | 204 if (pc_ > limit_) { |
| 205 error(pc_, "function body extends beyond end of file"); | 205 error(pc_, "function body extends beyond end of file"); |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 break; | 208 break; |
| 209 } | 209 } |
| 210 case WasmSection::Code::Names: { | 210 case WasmSection::Code::Names: { |
| 211 int length; | 211 unsigned length; |
| 212 const byte* pos = pc_; | 212 const byte* pos = pc_; |
| 213 uint32_t functions_count = consume_u32v(&length, "functions count"); | 213 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 214 if (functions_count != module->functions.size()) { | 214 if (functions_count != module->functions.size()) { |
| 215 error(pos, pos, "function name count %u mismatch (%u expected)", | 215 error(pos, pos, "function name count %u mismatch (%u expected)", |
| 216 functions_count, | 216 functions_count, |
| 217 static_cast<uint32_t>(module->functions.size())); | 217 static_cast<uint32_t>(module->functions.size())); |
| 218 break; | 218 break; |
| 219 } | 219 } |
| 220 | 220 |
| 221 for (uint32_t i = 0; i < functions_count; i++) { | 221 for (uint32_t i = 0; i < functions_count; i++) { |
| 222 WasmFunction* function = &module->functions[i]; | 222 WasmFunction* function = &module->functions[i]; |
| 223 function->name_offset = | 223 function->name_offset = |
| 224 consume_string(&function->name_length, false); | 224 consume_string(&function->name_length, false); |
| 225 | 225 |
| 226 uint32_t local_names_count = | 226 uint32_t local_names_count = |
| 227 consume_u32v(&length, "local names count"); | 227 consume_u32v(&length, "local names count"); |
| 228 for (uint32_t j = 0; j < local_names_count; j++) { | 228 for (uint32_t j = 0; j < local_names_count; j++) { |
| 229 uint32_t unused = 0; | 229 uint32_t unused = 0; |
| 230 uint32_t offset = consume_string(&unused, false); | 230 uint32_t offset = consume_string(&unused, false); |
| 231 USE(unused); | 231 USE(unused); |
| 232 USE(offset); | 232 USE(offset); |
| 233 } | 233 } |
| 234 } | 234 } |
| 235 break; | 235 break; |
| 236 } | 236 } |
| 237 case WasmSection::Code::Globals: { | 237 case WasmSection::Code::Globals: { |
| 238 int length; | 238 unsigned length; |
| 239 uint32_t globals_count = consume_u32v(&length, "globals count"); | 239 uint32_t globals_count = consume_u32v(&length, "globals count"); |
| 240 module->globals.reserve(SafeReserve(globals_count)); | 240 module->globals.reserve(SafeReserve(globals_count)); |
| 241 // Decode globals. | 241 // Decode globals. |
| 242 for (uint32_t i = 0; i < globals_count; i++) { | 242 for (uint32_t i = 0; i < globals_count; i++) { |
| 243 if (failed()) break; | 243 if (failed()) break; |
| 244 TRACE("DecodeGlobal[%d] module+%d\n", i, | 244 TRACE("DecodeGlobal[%d] module+%d\n", i, |
| 245 static_cast<int>(pc_ - start_)); | 245 static_cast<int>(pc_ - start_)); |
| 246 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); | 246 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
| 247 WasmGlobal* global = &module->globals.back(); | 247 WasmGlobal* global = &module->globals.back(); |
| 248 DecodeGlobalInModule(global); | 248 DecodeGlobalInModule(global); |
| 249 } | 249 } |
| 250 break; | 250 break; |
| 251 } | 251 } |
| 252 case WasmSection::Code::DataSegments: { | 252 case WasmSection::Code::DataSegments: { |
| 253 int length; | 253 unsigned length; |
| 254 uint32_t data_segments_count = | 254 uint32_t data_segments_count = |
| 255 consume_u32v(&length, "data segments count"); | 255 consume_u32v(&length, "data segments count"); |
| 256 module->data_segments.reserve(SafeReserve(data_segments_count)); | 256 module->data_segments.reserve(SafeReserve(data_segments_count)); |
| 257 // Decode data segments. | 257 // Decode data segments. |
| 258 for (uint32_t i = 0; i < data_segments_count; i++) { | 258 for (uint32_t i = 0; i < data_segments_count; i++) { |
| 259 if (failed()) break; | 259 if (failed()) break; |
| 260 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 260 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
| 261 static_cast<int>(pc_ - start_)); | 261 static_cast<int>(pc_ - start_)); |
| 262 module->data_segments.push_back({0, // dest_addr | 262 module->data_segments.push_back({0, // dest_addr |
| 263 0, // source_offset | 263 0, // source_offset |
| 264 0, // source_size | 264 0, // source_size |
| 265 false}); // init | 265 false}); // init |
| 266 WasmDataSegment* segment = &module->data_segments.back(); | 266 WasmDataSegment* segment = &module->data_segments.back(); |
| 267 DecodeDataSegmentInModule(module, segment); | 267 DecodeDataSegmentInModule(module, segment); |
| 268 } | 268 } |
| 269 break; | 269 break; |
| 270 } | 270 } |
| 271 case WasmSection::Code::FunctionTable: { | 271 case WasmSection::Code::FunctionTable: { |
| 272 // An indirect function table requires functions first. | 272 // An indirect function table requires functions first. |
| 273 CheckForFunctions(module, section); | 273 CheckForFunctions(module, section); |
| 274 int length; | 274 unsigned length; |
| 275 uint32_t function_table_count = | 275 uint32_t function_table_count = |
| 276 consume_u32v(&length, "function table count"); | 276 consume_u32v(&length, "function table count"); |
| 277 module->function_table.reserve(SafeReserve(function_table_count)); | 277 module->function_table.reserve(SafeReserve(function_table_count)); |
| 278 // Decode function table. | 278 // Decode function table. |
| 279 for (uint32_t i = 0; i < function_table_count; i++) { | 279 for (uint32_t i = 0; i < function_table_count; i++) { |
| 280 if (failed()) break; | 280 if (failed()) break; |
| 281 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 281 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
| 282 static_cast<int>(pc_ - start_)); | 282 static_cast<int>(pc_ - start_)); |
| 283 uint16_t index = consume_u32v(&length); | 283 uint16_t index = consume_u32v(&length); |
| 284 if (index >= module->functions.size()) { | 284 if (index >= module->functions.size()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 299 WasmFunction* func; | 299 WasmFunction* func; |
| 300 const byte* pos = pc_; | 300 const byte* pos = pc_; |
| 301 module->start_function_index = consume_func_index(module, &func); | 301 module->start_function_index = consume_func_index(module, &func); |
| 302 if (func && func->sig->parameter_count() > 0) { | 302 if (func && func->sig->parameter_count() > 0) { |
| 303 error(pos, "invalid start function: non-zero parameter count"); | 303 error(pos, "invalid start function: non-zero parameter count"); |
| 304 break; | 304 break; |
| 305 } | 305 } |
| 306 break; | 306 break; |
| 307 } | 307 } |
| 308 case WasmSection::Code::ImportTable: { | 308 case WasmSection::Code::ImportTable: { |
| 309 int length; | 309 unsigned length; |
| 310 uint32_t import_table_count = | 310 uint32_t import_table_count = |
| 311 consume_u32v(&length, "import table count"); | 311 consume_u32v(&length, "import table count"); |
| 312 module->import_table.reserve(SafeReserve(import_table_count)); | 312 module->import_table.reserve(SafeReserve(import_table_count)); |
| 313 // Decode import table. | 313 // Decode import table. |
| 314 for (uint32_t i = 0; i < import_table_count; i++) { | 314 for (uint32_t i = 0; i < import_table_count; i++) { |
| 315 if (failed()) break; | 315 if (failed()) break; |
| 316 TRACE("DecodeImportTable[%d] module+%d\n", i, | 316 TRACE("DecodeImportTable[%d] module+%d\n", i, |
| 317 static_cast<int>(pc_ - start_)); | 317 static_cast<int>(pc_ - start_)); |
| 318 | 318 |
| 319 module->import_table.push_back({nullptr, // sig | 319 module->import_table.push_back({nullptr, // sig |
| (...skipping 12 matching lines...) Expand all Loading... |
| 332 error(pos, "import module name cannot be NULL"); | 332 error(pos, "import module name cannot be NULL"); |
| 333 } | 333 } |
| 334 import->function_name_offset = | 334 import->function_name_offset = |
| 335 consume_string(&import->function_name_length, true); | 335 consume_string(&import->function_name_length, true); |
| 336 } | 336 } |
| 337 break; | 337 break; |
| 338 } | 338 } |
| 339 case WasmSection::Code::ExportTable: { | 339 case WasmSection::Code::ExportTable: { |
| 340 // Declares an export table. | 340 // Declares an export table. |
| 341 CheckForFunctions(module, section); | 341 CheckForFunctions(module, section); |
| 342 int length; | 342 unsigned length; |
| 343 uint32_t export_table_count = | 343 uint32_t export_table_count = |
| 344 consume_u32v(&length, "export table count"); | 344 consume_u32v(&length, "export table count"); |
| 345 module->export_table.reserve(SafeReserve(export_table_count)); | 345 module->export_table.reserve(SafeReserve(export_table_count)); |
| 346 // Decode export table. | 346 // Decode export table. |
| 347 for (uint32_t i = 0; i < export_table_count; i++) { | 347 for (uint32_t i = 0; i < export_table_count; i++) { |
| 348 if (failed()) break; | 348 if (failed()) break; |
| 349 TRACE("DecodeExportTable[%d] module+%d\n", i, | 349 TRACE("DecodeExportTable[%d] module+%d\n", i, |
| 350 static_cast<int>(pc_ - start_)); | 350 static_cast<int>(pc_ - start_)); |
| 351 | 351 |
| 352 module->export_table.push_back({0, // func_index | 352 module->export_table.push_back({0, // func_index |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 464 |
| 465 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { | 465 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { |
| 466 if (offset > limit) return false; | 466 if (offset > limit) return false; |
| 467 if ((offset + size) < offset) return false; // overflow | 467 if ((offset + size) < offset) return false; // overflow |
| 468 return (offset + size) <= limit; | 468 return (offset + size) <= limit; |
| 469 } | 469 } |
| 470 | 470 |
| 471 // Decodes a single data segment entry inside a module starting at {pc_}. | 471 // Decodes a single data segment entry inside a module starting at {pc_}. |
| 472 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { | 472 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
| 473 const byte* start = pc_; | 473 const byte* start = pc_; |
| 474 int length; | 474 unsigned length; |
| 475 segment->dest_addr = consume_u32v(&length, "destination"); | 475 segment->dest_addr = consume_u32v(&length, "destination"); |
| 476 segment->source_size = consume_u32v(&length, "source size"); | 476 segment->source_size = consume_u32v(&length, "source size"); |
| 477 segment->source_offset = static_cast<uint32_t>(pc_ - start_); | 477 segment->source_offset = static_cast<uint32_t>(pc_ - start_); |
| 478 segment->init = true; | 478 segment->init = true; |
| 479 | 479 |
| 480 // Validate the data is in the module. | 480 // Validate the data is in the module. |
| 481 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); | 481 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); |
| 482 if (!IsWithinLimit(module_limit, segment->source_offset, | 482 if (!IsWithinLimit(module_limit, segment->source_offset, |
| 483 segment->source_size)) { | 483 segment->source_size)) { |
| 484 error(start, "segment out of bounds of module"); | 484 error(start, "segment out of bounds of module"); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 uint32_t offset = consume_u32(name ? name : "offset"); | 548 uint32_t offset = consume_u32(name ? name : "offset"); |
| 549 if (offset > static_cast<uint32_t>(limit_ - start_)) { | 549 if (offset > static_cast<uint32_t>(limit_ - start_)) { |
| 550 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); | 550 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); |
| 551 } | 551 } |
| 552 return offset; | 552 return offset; |
| 553 } | 553 } |
| 554 | 554 |
| 555 // Reads a length-prefixed string, checking that it is within bounds. Returns | 555 // Reads a length-prefixed string, checking that it is within bounds. Returns |
| 556 // the offset of the string, and the length as an out parameter. | 556 // the offset of the string, and the length as an out parameter. |
| 557 uint32_t consume_string(uint32_t* length, bool validate_utf8) { | 557 uint32_t consume_string(uint32_t* length, bool validate_utf8) { |
| 558 int varint_length; | 558 unsigned varint_length; |
| 559 *length = consume_u32v(&varint_length, "string length"); | 559 *length = consume_u32v(&varint_length, "string length"); |
| 560 uint32_t offset = pc_offset(); | 560 uint32_t offset = pc_offset(); |
| 561 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); | 561 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); |
| 562 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { | 562 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { |
| 563 error(pc_, "no valid UTF-8 string"); | 563 error(pc_, "no valid UTF-8 string"); |
| 564 } | 564 } |
| 565 consume_bytes(*length); | 565 consume_bytes(*length); |
| 566 return offset; | 566 return offset; |
| 567 } | 567 } |
| 568 | 568 |
| 569 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { | 569 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { |
| 570 const byte* pos = pc_; | 570 const byte* pos = pc_; |
| 571 int length; | 571 unsigned length; |
| 572 uint32_t sig_index = consume_u32v(&length, "signature index"); | 572 uint32_t sig_index = consume_u32v(&length, "signature index"); |
| 573 if (sig_index >= module->signatures.size()) { | 573 if (sig_index >= module->signatures.size()) { |
| 574 error(pos, pos, "signature index %u out of bounds (%d signatures)", | 574 error(pos, pos, "signature index %u out of bounds (%d signatures)", |
| 575 sig_index, static_cast<int>(module->signatures.size())); | 575 sig_index, static_cast<int>(module->signatures.size())); |
| 576 *sig = nullptr; | 576 *sig = nullptr; |
| 577 return 0; | 577 return 0; |
| 578 } | 578 } |
| 579 *sig = module->signatures[sig_index]; | 579 *sig = module->signatures[sig_index]; |
| 580 return sig_index; | 580 return sig_index; |
| 581 } | 581 } |
| 582 | 582 |
| 583 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { | 583 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { |
| 584 const byte* pos = pc_; | 584 const byte* pos = pc_; |
| 585 int length; | 585 unsigned length; |
| 586 uint32_t func_index = consume_u32v(&length, "function index"); | 586 uint32_t func_index = consume_u32v(&length, "function index"); |
| 587 if (func_index >= module->functions.size()) { | 587 if (func_index >= module->functions.size()) { |
| 588 error(pos, pos, "function index %u out of bounds (%d functions)", | 588 error(pos, pos, "function index %u out of bounds (%d functions)", |
| 589 func_index, static_cast<int>(module->functions.size())); | 589 func_index, static_cast<int>(module->functions.size())); |
| 590 *func = nullptr; | 590 *func = nullptr; |
| 591 return 0; | 591 return 0; |
| 592 } | 592 } |
| 593 *func = &module->functions[func_index]; | 593 *func = &module->functions[func_index]; |
| 594 return func_index; | 594 return func_index; |
| 595 } | 595 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 | 650 |
| 651 // Parses a type entry, which is currently limited to functions only. | 651 // Parses a type entry, which is currently limited to functions only. |
| 652 FunctionSig* consume_sig() { | 652 FunctionSig* consume_sig() { |
| 653 const byte* pos = pc_; | 653 const byte* pos = pc_; |
| 654 byte form = consume_u8("type form"); | 654 byte form = consume_u8("type form"); |
| 655 if (form != kWasmFunctionTypeForm) { | 655 if (form != kWasmFunctionTypeForm) { |
| 656 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", | 656 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
| 657 kWasmFunctionTypeForm, form); | 657 kWasmFunctionTypeForm, form); |
| 658 return nullptr; | 658 return nullptr; |
| 659 } | 659 } |
| 660 int length; | 660 unsigned length; |
| 661 // parse parameter types | 661 // parse parameter types |
| 662 uint32_t param_count = consume_u32v(&length, "param count"); | 662 uint32_t param_count = consume_u32v(&length, "param count"); |
| 663 std::vector<LocalType> params; | 663 std::vector<LocalType> params; |
| 664 for (uint32_t i = 0; i < param_count; i++) { | 664 for (uint32_t i = 0; i < param_count; i++) { |
| 665 LocalType param = consume_local_type(); | 665 LocalType param = consume_local_type(); |
| 666 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 666 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
| 667 params.push_back(param); | 667 params.push_back(param); |
| 668 } | 668 } |
| 669 | 669 |
| 670 // parse return types | 670 // parse return types |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 return FunctionError("size > maximum function size"); | 758 return FunctionError("size > maximum function size"); |
| 759 isolate->counters()->wasm_function_size_bytes()->AddSample( | 759 isolate->counters()->wasm_function_size_bytes()->AddSample( |
| 760 static_cast<int>(size)); | 760 static_cast<int>(size)); |
| 761 WasmFunction* function = new WasmFunction(); | 761 WasmFunction* function = new WasmFunction(); |
| 762 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 762 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
| 763 return decoder.DecodeSingleFunction(module_env, function); | 763 return decoder.DecodeSingleFunction(module_env, function); |
| 764 } | 764 } |
| 765 } // namespace wasm | 765 } // namespace wasm |
| 766 } // namespace internal | 766 } // namespace internal |
| 767 } // namespace v8 | 767 } // namespace v8 |
| OLD | NEW |