| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 goto done; | 103 goto done; |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 | 106 |
| 107 // Decode the module sections. | 107 // Decode the module sections. |
| 108 while (pc_ < limit_) { | 108 while (pc_ < limit_) { |
| 109 TRACE("DecodeSection\n"); | 109 TRACE("DecodeSection\n"); |
| 110 pos = pc_; | 110 pos = pc_; |
| 111 | 111 |
| 112 // Read the section name. | 112 // Read the section name. |
| 113 int string_leb_length = 0; | 113 uint32_t string_length = consume_u32v("section name length"); |
| 114 uint32_t string_length = | |
| 115 consume_u32v(&string_leb_length, "section name length"); | |
| 116 const byte* section_name_start = pc_; | 114 const byte* section_name_start = pc_; |
| 117 consume_bytes(string_length); | 115 consume_bytes(string_length); |
| 118 if (failed()) { | 116 if (failed()) { |
| 119 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); |
| 120 break; | 118 break; |
| 121 } | 119 } |
| 122 | 120 |
| 123 TRACE(" +%d section name : \"%.*s\"\n", | 121 TRACE(" +%d section name : \"%.*s\"\n", |
| 124 static_cast<int>(section_name_start - start_), | 122 static_cast<int>(section_name_start - start_), |
| 125 string_length < 20 ? string_length : 20, section_name_start); | 123 string_length < 20 ? string_length : 20, section_name_start); |
| 126 | 124 |
| 127 WasmSection::Code section = | 125 WasmSection::Code section = |
| 128 WasmSection::lookup(section_name_start, string_length); | 126 WasmSection::lookup(section_name_start, string_length); |
| 129 | 127 |
| 130 // Read and check the section size. | 128 // Read and check the section size. |
| 131 int section_leb_length = 0; | 129 uint32_t section_length = consume_u32v("section length"); |
| 132 uint32_t section_length = | |
| 133 consume_u32v(§ion_leb_length, "section length"); | |
| 134 if (!checkAvailable(section_length)) { | 130 if (!checkAvailable(section_length)) { |
| 135 // The section would extend beyond the end of the module. | 131 // The section would extend beyond the end of the module. |
| 136 break; | 132 break; |
| 137 } | 133 } |
| 138 const byte* section_start = pc_; | 134 const byte* section_start = pc_; |
| 139 const byte* expected_section_end = pc_ + section_length; | 135 const byte* expected_section_end = pc_ + section_length; |
| 140 | 136 |
| 141 current_order = CheckSectionOrder(current_order, section); | 137 current_order = CheckSectionOrder(current_order, section); |
| 142 | 138 |
| 143 switch (section) { | 139 switch (section) { |
| 144 case WasmSection::Code::End: | 140 case WasmSection::Code::End: |
| 145 // Terminate section decoding. | 141 // Terminate section decoding. |
| 146 limit_ = pc_; | 142 limit_ = pc_; |
| 147 break; | 143 break; |
| 148 case WasmSection::Code::Memory: { | 144 case WasmSection::Code::Memory: { |
| 149 int length; | 145 module->min_mem_pages = consume_u32v("min memory"); |
| 150 module->min_mem_pages = consume_u32v(&length, "min memory"); | 146 module->max_mem_pages = consume_u32v("max memory"); |
| 151 module->max_mem_pages = consume_u32v(&length, "max memory"); | |
| 152 module->mem_export = consume_u8("export memory") != 0; | 147 module->mem_export = consume_u8("export memory") != 0; |
| 153 break; | 148 break; |
| 154 } | 149 } |
| 155 case WasmSection::Code::Signatures: { | 150 case WasmSection::Code::Signatures: { |
| 156 int length; | 151 uint32_t signatures_count = consume_u32v("signatures count"); |
| 157 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | |
| 158 module->signatures.reserve(SafeReserve(signatures_count)); | 152 module->signatures.reserve(SafeReserve(signatures_count)); |
| 159 // Decode signatures. | 153 // Decode signatures. |
| 160 for (uint32_t i = 0; i < signatures_count; ++i) { | 154 for (uint32_t i = 0; i < signatures_count; ++i) { |
| 161 if (failed()) break; | 155 if (failed()) break; |
| 162 TRACE("DecodeSignature[%d] module+%d\n", i, | 156 TRACE("DecodeSignature[%d] module+%d\n", i, |
| 163 static_cast<int>(pc_ - start_)); | 157 static_cast<int>(pc_ - start_)); |
| 164 FunctionSig* s = consume_sig(); | 158 FunctionSig* s = consume_sig(); |
| 165 module->signatures.push_back(s); | 159 module->signatures.push_back(s); |
| 166 } | 160 } |
| 167 break; | 161 break; |
| 168 } | 162 } |
| 169 case WasmSection::Code::FunctionSignatures: { | 163 case WasmSection::Code::FunctionSignatures: { |
| 170 int length; | 164 uint32_t functions_count = consume_u32v("functions count"); |
| 171 uint32_t functions_count = consume_u32v(&length, "functions count"); | |
| 172 module->functions.reserve(SafeReserve(functions_count)); | 165 module->functions.reserve(SafeReserve(functions_count)); |
| 173 for (uint32_t i = 0; i < functions_count; ++i) { | 166 for (uint32_t i = 0; i < functions_count; ++i) { |
| 174 module->functions.push_back({nullptr, // sig | 167 module->functions.push_back({nullptr, // sig |
| 175 i, // func_index | 168 i, // func_index |
| 176 0, // sig_index | 169 0, // sig_index |
| 177 0, // name_offset | 170 0, // name_offset |
| 178 0, // name_length | 171 0, // name_length |
| 179 0, // code_start_offset | 172 0, // code_start_offset |
| 180 0}); // code_end_offset | 173 0}); // code_end_offset |
| 181 WasmFunction* function = &module->functions.back(); | 174 WasmFunction* function = &module->functions.back(); |
| 182 function->sig_index = consume_sig_index(module, &function->sig); | 175 function->sig_index = consume_sig_index(module, &function->sig); |
| 183 } | 176 } |
| 184 break; | 177 break; |
| 185 } | 178 } |
| 186 case WasmSection::Code::FunctionBodies: { | 179 case WasmSection::Code::FunctionBodies: { |
| 187 int length; | |
| 188 const byte* pos = pc_; | 180 const byte* pos = pc_; |
| 189 uint32_t functions_count = consume_u32v(&length, "functions count"); | 181 uint32_t functions_count = consume_u32v("functions count"); |
| 190 if (functions_count != module->functions.size()) { | 182 if (functions_count != module->functions.size()) { |
| 191 error(pos, pos, "function body count %u mismatch (%u expected)", | 183 error(pos, pos, "function body count %u mismatch (%u expected)", |
| 192 functions_count, | 184 functions_count, |
| 193 static_cast<uint32_t>(module->functions.size())); | 185 static_cast<uint32_t>(module->functions.size())); |
| 194 break; | 186 break; |
| 195 } | 187 } |
| 196 for (uint32_t i = 0; i < functions_count; ++i) { | 188 for (uint32_t i = 0; i < functions_count; ++i) { |
| 197 WasmFunction* function = &module->functions[i]; | 189 WasmFunction* function = &module->functions[i]; |
| 198 int length; | 190 uint32_t size = consume_u32v("body size"); |
| 199 uint32_t size = consume_u32v(&length, "body size"); | |
| 200 function->code_start_offset = pc_offset(); | 191 function->code_start_offset = pc_offset(); |
| 201 function->code_end_offset = pc_offset() + size; | 192 function->code_end_offset = pc_offset() + size; |
| 202 | 193 |
| 203 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 194 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
| 204 size); | 195 size); |
| 205 pc_ += size; | 196 pc_ += size; |
| 206 if (pc_ > limit_) { | 197 if (pc_ > limit_) { |
| 207 error(pc_, "function body extends beyond end of file"); | 198 error(pc_, "function body extends beyond end of file"); |
| 208 } | 199 } |
| 209 } | 200 } |
| 210 break; | 201 break; |
| 211 } | 202 } |
| 212 case WasmSection::Code::Names: { | 203 case WasmSection::Code::Names: { |
| 213 int length; | |
| 214 const byte* pos = pc_; | 204 const byte* pos = pc_; |
| 215 uint32_t functions_count = consume_u32v(&length, "functions count"); | 205 uint32_t functions_count = consume_u32v("functions count"); |
| 216 if (functions_count != module->functions.size()) { | 206 if (functions_count != module->functions.size()) { |
| 217 error(pos, pos, "function name count %u mismatch (%u expected)", | 207 error(pos, pos, "function name count %u mismatch (%u expected)", |
| 218 functions_count, | 208 functions_count, |
| 219 static_cast<uint32_t>(module->functions.size())); | 209 static_cast<uint32_t>(module->functions.size())); |
| 220 break; | 210 break; |
| 221 } | 211 } |
| 222 | 212 |
| 223 for (uint32_t i = 0; i < functions_count; ++i) { | 213 for (uint32_t i = 0; i < functions_count; ++i) { |
| 224 WasmFunction* function = &module->functions[i]; | 214 WasmFunction* function = &module->functions[i]; |
| 225 function->name_offset = | 215 function->name_offset = |
| 226 consume_string(&function->name_length, false); | 216 consume_string(&function->name_length, false); |
| 227 | 217 |
| 228 uint32_t local_names_count = | 218 uint32_t local_names_count = consume_u32v("local names count"); |
| 229 consume_u32v(&length, "local names count"); | |
| 230 for (uint32_t j = 0; j < local_names_count; j++) { | 219 for (uint32_t j = 0; j < local_names_count; j++) { |
| 231 uint32_t unused = 0; | 220 uint32_t unused = 0; |
| 232 uint32_t offset = consume_string(&unused, false); | 221 uint32_t offset = consume_string(&unused, false); |
| 233 USE(unused); | 222 USE(unused); |
| 234 USE(offset); | 223 USE(offset); |
| 235 } | 224 } |
| 236 } | 225 } |
| 237 break; | 226 break; |
| 238 } | 227 } |
| 239 case WasmSection::Code::Globals: { | 228 case WasmSection::Code::Globals: { |
| 240 int length; | 229 uint32_t globals_count = consume_u32v("globals count"); |
| 241 uint32_t globals_count = consume_u32v(&length, "globals count"); | |
| 242 module->globals.reserve(SafeReserve(globals_count)); | 230 module->globals.reserve(SafeReserve(globals_count)); |
| 243 // Decode globals. | 231 // Decode globals. |
| 244 for (uint32_t i = 0; i < globals_count; ++i) { | 232 for (uint32_t i = 0; i < globals_count; ++i) { |
| 245 if (failed()) break; | 233 if (failed()) break; |
| 246 TRACE("DecodeGlobal[%d] module+%d\n", i, | 234 TRACE("DecodeGlobal[%d] module+%d\n", i, |
| 247 static_cast<int>(pc_ - start_)); | 235 static_cast<int>(pc_ - start_)); |
| 248 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); | 236 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
| 249 WasmGlobal* global = &module->globals.back(); | 237 WasmGlobal* global = &module->globals.back(); |
| 250 DecodeGlobalInModule(global); | 238 DecodeGlobalInModule(global); |
| 251 } | 239 } |
| 252 break; | 240 break; |
| 253 } | 241 } |
| 254 case WasmSection::Code::DataSegments: { | 242 case WasmSection::Code::DataSegments: { |
| 255 int length; | 243 uint32_t data_segments_count = consume_u32v("data segments count"); |
| 256 uint32_t data_segments_count = | |
| 257 consume_u32v(&length, "data segments count"); | |
| 258 module->data_segments.reserve(SafeReserve(data_segments_count)); | 244 module->data_segments.reserve(SafeReserve(data_segments_count)); |
| 259 // Decode data segments. | 245 // Decode data segments. |
| 260 for (uint32_t i = 0; i < data_segments_count; ++i) { | 246 for (uint32_t i = 0; i < data_segments_count; ++i) { |
| 261 if (failed()) break; | 247 if (failed()) break; |
| 262 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 248 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
| 263 static_cast<int>(pc_ - start_)); | 249 static_cast<int>(pc_ - start_)); |
| 264 module->data_segments.push_back({0, // dest_addr | 250 module->data_segments.push_back({0, // dest_addr |
| 265 0, // source_offset | 251 0, // source_offset |
| 266 0, // source_size | 252 0, // source_size |
| 267 false}); // init | 253 false}); // init |
| 268 WasmDataSegment* segment = &module->data_segments.back(); | 254 WasmDataSegment* segment = &module->data_segments.back(); |
| 269 DecodeDataSegmentInModule(module, segment); | 255 DecodeDataSegmentInModule(module, segment); |
| 270 } | 256 } |
| 271 break; | 257 break; |
| 272 } | 258 } |
| 273 case WasmSection::Code::FunctionTablePad: { | 259 case WasmSection::Code::FunctionTablePad: { |
| 274 if (!FLAG_wasm_jit_prototype) { | 260 if (!FLAG_wasm_jit_prototype) { |
| 275 error("FunctionTablePad section without jiting enabled"); | 261 error("FunctionTablePad section without jiting enabled"); |
| 276 } | 262 } |
| 277 // An indirect function table requires functions first. | 263 // An indirect function table requires functions first. |
| 278 int length; | 264 module->indirect_table_size = consume_u32v("indirect entry count"); |
| 279 module->indirect_table_size = | |
| 280 consume_u32v(&length, "indirect entry count"); | |
| 281 if (module->indirect_table_size > 0 && | 265 if (module->indirect_table_size > 0 && |
| 282 module->indirect_table_size < module->function_table.size()) { | 266 module->indirect_table_size < module->function_table.size()) { |
| 283 error("more predefined indirect entries than table can hold"); | 267 error("more predefined indirect entries than table can hold"); |
| 284 } | 268 } |
| 285 break; | 269 break; |
| 286 } | 270 } |
| 287 case WasmSection::Code::FunctionTable: { | 271 case WasmSection::Code::FunctionTable: { |
| 288 // An indirect function table requires functions first. | 272 // An indirect function table requires functions first. |
| 289 CheckForFunctions(module, section); | 273 CheckForFunctions(module, section); |
| 290 int length; | 274 uint32_t function_table_count = consume_u32v("function table count"); |
| 291 uint32_t function_table_count = | |
| 292 consume_u32v(&length, "function table count"); | |
| 293 module->function_table.reserve(SafeReserve(function_table_count)); | 275 module->function_table.reserve(SafeReserve(function_table_count)); |
| 294 // Decode function table. | 276 // Decode function table. |
| 295 for (uint32_t i = 0; i < function_table_count; ++i) { | 277 for (uint32_t i = 0; i < function_table_count; ++i) { |
| 296 if (failed()) break; | 278 if (failed()) break; |
| 297 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 279 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
| 298 static_cast<int>(pc_ - start_)); | 280 static_cast<int>(pc_ - start_)); |
| 299 uint16_t index = consume_u32v(&length); | 281 uint16_t index = consume_u32v(); |
| 300 if (index >= module->functions.size()) { | 282 if (index >= module->functions.size()) { |
| 301 error(pc_ - 2, "invalid function index"); | 283 error(pc_ - 2, "invalid function index"); |
| 302 break; | 284 break; |
| 303 } | 285 } |
| 304 module->function_table.push_back(index); | 286 module->function_table.push_back(index); |
| 305 } | 287 } |
| 306 if (module->indirect_table_size > 0 && | 288 if (module->indirect_table_size > 0 && |
| 307 module->indirect_table_size < module->function_table.size()) { | 289 module->indirect_table_size < module->function_table.size()) { |
| 308 error("more predefined indirect entries than table can hold"); | 290 error("more predefined indirect entries than table can hold"); |
| 309 } | 291 } |
| 310 break; | 292 break; |
| 311 } | 293 } |
| 312 case WasmSection::Code::StartFunction: { | 294 case WasmSection::Code::StartFunction: { |
| 313 // Declares a start function for a module. | 295 // Declares a start function for a module. |
| 314 CheckForFunctions(module, section); | 296 CheckForFunctions(module, section); |
| 315 if (module->start_function_index >= 0) { | 297 if (module->start_function_index >= 0) { |
| 316 error("start function already declared"); | 298 error("start function already declared"); |
| 317 break; | 299 break; |
| 318 } | 300 } |
| 319 WasmFunction* func; | 301 WasmFunction* func; |
| 320 const byte* pos = pc_; | 302 const byte* pos = pc_; |
| 321 module->start_function_index = consume_func_index(module, &func); | 303 module->start_function_index = consume_func_index(module, &func); |
| 322 if (func && func->sig->parameter_count() > 0) { | 304 if (func && func->sig->parameter_count() > 0) { |
| 323 error(pos, "invalid start function: non-zero parameter count"); | 305 error(pos, "invalid start function: non-zero parameter count"); |
| 324 break; | 306 break; |
| 325 } | 307 } |
| 326 break; | 308 break; |
| 327 } | 309 } |
| 328 case WasmSection::Code::ImportTable: { | 310 case WasmSection::Code::ImportTable: { |
| 329 int length; | 311 uint32_t import_table_count = consume_u32v("import table count"); |
| 330 uint32_t import_table_count = | |
| 331 consume_u32v(&length, "import table count"); | |
| 332 module->import_table.reserve(SafeReserve(import_table_count)); | 312 module->import_table.reserve(SafeReserve(import_table_count)); |
| 333 // Decode import table. | 313 // Decode import table. |
| 334 for (uint32_t i = 0; i < import_table_count; ++i) { | 314 for (uint32_t i = 0; i < import_table_count; ++i) { |
| 335 if (failed()) break; | 315 if (failed()) break; |
| 336 TRACE("DecodeImportTable[%d] module+%d\n", i, | 316 TRACE("DecodeImportTable[%d] module+%d\n", i, |
| 337 static_cast<int>(pc_ - start_)); | 317 static_cast<int>(pc_ - start_)); |
| 338 | 318 |
| 339 module->import_table.push_back({nullptr, // sig | 319 module->import_table.push_back({nullptr, // sig |
| 340 0, // sig_index | 320 0, // sig_index |
| 341 0, // module_name_offset | 321 0, // module_name_offset |
| (...skipping 10 matching lines...) Expand all Loading... |
| 352 error(pos, "import module name cannot be NULL"); | 332 error(pos, "import module name cannot be NULL"); |
| 353 } | 333 } |
| 354 import->function_name_offset = | 334 import->function_name_offset = |
| 355 consume_string(&import->function_name_length, true); | 335 consume_string(&import->function_name_length, true); |
| 356 } | 336 } |
| 357 break; | 337 break; |
| 358 } | 338 } |
| 359 case WasmSection::Code::ExportTable: { | 339 case WasmSection::Code::ExportTable: { |
| 360 // Declares an export table. | 340 // Declares an export table. |
| 361 CheckForFunctions(module, section); | 341 CheckForFunctions(module, section); |
| 362 int length; | 342 uint32_t export_table_count = consume_u32v("export table count"); |
| 363 uint32_t export_table_count = | |
| 364 consume_u32v(&length, "export table count"); | |
| 365 module->export_table.reserve(SafeReserve(export_table_count)); | 343 module->export_table.reserve(SafeReserve(export_table_count)); |
| 366 // Decode export table. | 344 // Decode export table. |
| 367 for (uint32_t i = 0; i < export_table_count; ++i) { | 345 for (uint32_t i = 0; i < export_table_count; ++i) { |
| 368 if (failed()) break; | 346 if (failed()) break; |
| 369 TRACE("DecodeExportTable[%d] module+%d\n", i, | 347 TRACE("DecodeExportTable[%d] module+%d\n", i, |
| 370 static_cast<int>(pc_ - start_)); | 348 static_cast<int>(pc_ - start_)); |
| 371 | 349 |
| 372 module->export_table.push_back({0, // func_index | 350 module->export_table.push_back({0, // func_index |
| 373 0, // name_offset | 351 0, // name_offset |
| 374 0}); // name_length | 352 0}); // name_length |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 | 488 |
| 511 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { | 489 bool IsWithinLimit(uint32_t limit, uint32_t offset, uint32_t size) { |
| 512 if (offset > limit) return false; | 490 if (offset > limit) return false; |
| 513 if ((offset + size) < offset) return false; // overflow | 491 if ((offset + size) < offset) return false; // overflow |
| 514 return (offset + size) <= limit; | 492 return (offset + size) <= limit; |
| 515 } | 493 } |
| 516 | 494 |
| 517 // Decodes a single data segment entry inside a module starting at {pc_}. | 495 // Decodes a single data segment entry inside a module starting at {pc_}. |
| 518 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { | 496 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
| 519 const byte* start = pc_; | 497 const byte* start = pc_; |
| 520 int length; | 498 segment->dest_addr = consume_u32v("destination"); |
| 521 segment->dest_addr = consume_u32v(&length, "destination"); | 499 segment->source_size = consume_u32v("source size"); |
| 522 segment->source_size = consume_u32v(&length, "source size"); | |
| 523 segment->source_offset = static_cast<uint32_t>(pc_ - start_); | 500 segment->source_offset = static_cast<uint32_t>(pc_ - start_); |
| 524 segment->init = true; | 501 segment->init = true; |
| 525 | 502 |
| 526 // Validate the data is in the module. | 503 // Validate the data is in the module. |
| 527 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); | 504 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); |
| 528 if (!IsWithinLimit(module_limit, segment->source_offset, | 505 if (!IsWithinLimit(module_limit, segment->source_offset, |
| 529 segment->source_size)) { | 506 segment->source_size)) { |
| 530 error(start, "segment out of bounds of module"); | 507 error(start, "segment out of bounds of module"); |
| 531 } | 508 } |
| 532 | 509 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 uint32_t offset = consume_u32(name ? name : "offset"); | 571 uint32_t offset = consume_u32(name ? name : "offset"); |
| 595 if (offset > static_cast<uint32_t>(limit_ - start_)) { | 572 if (offset > static_cast<uint32_t>(limit_ - start_)) { |
| 596 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); | 573 error(pc_ - sizeof(uint32_t), "offset out of bounds of module"); |
| 597 } | 574 } |
| 598 return offset; | 575 return offset; |
| 599 } | 576 } |
| 600 | 577 |
| 601 // Reads a length-prefixed string, checking that it is within bounds. Returns | 578 // Reads a length-prefixed string, checking that it is within bounds. Returns |
| 602 // the offset of the string, and the length as an out parameter. | 579 // the offset of the string, and the length as an out parameter. |
| 603 uint32_t consume_string(uint32_t* length, bool validate_utf8) { | 580 uint32_t consume_string(uint32_t* length, bool validate_utf8) { |
| 604 int varint_length; | 581 *length = consume_u32v("string length"); |
| 605 *length = consume_u32v(&varint_length, "string length"); | |
| 606 uint32_t offset = pc_offset(); | 582 uint32_t offset = pc_offset(); |
| 607 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); | 583 TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length); |
| 608 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { | 584 if (validate_utf8 && !unibrow::Utf8::Validate(pc_, *length)) { |
| 609 error(pc_, "no valid UTF-8 string"); | 585 error(pc_, "no valid UTF-8 string"); |
| 610 } | 586 } |
| 611 consume_bytes(*length); | 587 consume_bytes(*length); |
| 612 return offset; | 588 return offset; |
| 613 } | 589 } |
| 614 | 590 |
| 615 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { | 591 uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { |
| 616 const byte* pos = pc_; | 592 const byte* pos = pc_; |
| 617 int length; | 593 uint32_t sig_index = consume_u32v("signature index"); |
| 618 uint32_t sig_index = consume_u32v(&length, "signature index"); | |
| 619 if (sig_index >= module->signatures.size()) { | 594 if (sig_index >= module->signatures.size()) { |
| 620 error(pos, pos, "signature index %u out of bounds (%d signatures)", | 595 error(pos, pos, "signature index %u out of bounds (%d signatures)", |
| 621 sig_index, static_cast<int>(module->signatures.size())); | 596 sig_index, static_cast<int>(module->signatures.size())); |
| 622 *sig = nullptr; | 597 *sig = nullptr; |
| 623 return 0; | 598 return 0; |
| 624 } | 599 } |
| 625 *sig = module->signatures[sig_index]; | 600 *sig = module->signatures[sig_index]; |
| 626 return sig_index; | 601 return sig_index; |
| 627 } | 602 } |
| 628 | 603 |
| 629 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { | 604 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { |
| 630 const byte* pos = pc_; | 605 const byte* pos = pc_; |
| 631 int length; | 606 uint32_t func_index = consume_u32v("function index"); |
| 632 uint32_t func_index = consume_u32v(&length, "function index"); | |
| 633 if (func_index >= module->functions.size()) { | 607 if (func_index >= module->functions.size()) { |
| 634 error(pos, pos, "function index %u out of bounds (%d functions)", | 608 error(pos, pos, "function index %u out of bounds (%d functions)", |
| 635 func_index, static_cast<int>(module->functions.size())); | 609 func_index, static_cast<int>(module->functions.size())); |
| 636 *func = nullptr; | 610 *func = nullptr; |
| 637 return 0; | 611 return 0; |
| 638 } | 612 } |
| 639 *func = &module->functions[func_index]; | 613 *func = &module->functions[func_index]; |
| 640 return func_index; | 614 return func_index; |
| 641 } | 615 } |
| 642 | 616 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 | 670 |
| 697 // Parses a type entry, which is currently limited to functions only. | 671 // Parses a type entry, which is currently limited to functions only. |
| 698 FunctionSig* consume_sig() { | 672 FunctionSig* consume_sig() { |
| 699 const byte* pos = pc_; | 673 const byte* pos = pc_; |
| 700 byte form = consume_u8("type form"); | 674 byte form = consume_u8("type form"); |
| 701 if (form != kWasmFunctionTypeForm) { | 675 if (form != kWasmFunctionTypeForm) { |
| 702 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", | 676 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
| 703 kWasmFunctionTypeForm, form); | 677 kWasmFunctionTypeForm, form); |
| 704 return nullptr; | 678 return nullptr; |
| 705 } | 679 } |
| 706 int length; | |
| 707 // parse parameter types | 680 // parse parameter types |
| 708 uint32_t param_count = consume_u32v(&length, "param count"); | 681 uint32_t param_count = consume_u32v("param count"); |
| 709 std::vector<LocalType> params; | 682 std::vector<LocalType> params; |
| 710 for (uint32_t i = 0; i < param_count; ++i) { | 683 for (uint32_t i = 0; i < param_count; ++i) { |
| 711 LocalType param = consume_local_type(); | 684 LocalType param = consume_local_type(); |
| 712 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 685 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
| 713 params.push_back(param); | 686 params.push_back(param); |
| 714 } | 687 } |
| 715 | 688 |
| 716 // parse return types | 689 // parse return types |
| 717 const byte* pt = pc_; | 690 const byte* pt = pc_; |
| 718 uint32_t return_count = consume_u32v(&length, "return count"); | 691 uint32_t return_count = consume_u32v("return count"); |
| 719 if (return_count > kMaxReturnCount) { | 692 if (return_count > kMaxReturnCount) { |
| 720 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, | 693 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, |
| 721 kMaxReturnCount); | 694 kMaxReturnCount); |
| 722 return nullptr; | 695 return nullptr; |
| 723 } | 696 } |
| 724 std::vector<LocalType> returns; | 697 std::vector<LocalType> returns; |
| 725 for (uint32_t i = 0; i < return_count; ++i) { | 698 for (uint32_t i = 0; i < return_count; ++i) { |
| 726 LocalType ret = consume_local_type(); | 699 LocalType ret = consume_local_type(); |
| 727 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); | 700 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); |
| 728 returns.push_back(ret); | 701 returns.push_back(ret); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 Decoder decoder(module_start, module_end); | 743 Decoder decoder(module_start, module_end); |
| 771 | 744 |
| 772 uint32_t magic_word = decoder.consume_u32("wasm magic"); | 745 uint32_t magic_word = decoder.consume_u32("wasm magic"); |
| 773 if (magic_word != kWasmMagic) decoder.error("wrong magic word"); | 746 if (magic_word != kWasmMagic) decoder.error("wrong magic word"); |
| 774 | 747 |
| 775 uint32_t magic_version = decoder.consume_u32("wasm version"); | 748 uint32_t magic_version = decoder.consume_u32("wasm version"); |
| 776 if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); | 749 if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); |
| 777 | 750 |
| 778 while (decoder.more() && decoder.ok()) { | 751 while (decoder.more() && decoder.ok()) { |
| 779 // Read the section name. | 752 // Read the section name. |
| 780 int string_leb_length = 0; | 753 uint32_t string_length = decoder.consume_u32v("section name length"); |
| 781 uint32_t string_length = | |
| 782 decoder.consume_u32v(&string_leb_length, "section name length"); | |
| 783 const byte* section_name_start = decoder.pc(); | 754 const byte* section_name_start = decoder.pc(); |
| 784 decoder.consume_bytes(string_length); | 755 decoder.consume_bytes(string_length); |
| 785 if (decoder.failed()) break; | 756 if (decoder.failed()) break; |
| 786 | 757 |
| 787 WasmSection::Code section = | 758 WasmSection::Code section = |
| 788 WasmSection::lookup(section_name_start, string_length); | 759 WasmSection::lookup(section_name_start, string_length); |
| 789 | 760 |
| 790 // Read and check the section size. | 761 // Read and check the section size. |
| 791 int section_leb_length = 0; | 762 uint32_t section_length = decoder.consume_u32v("section length"); |
| 792 uint32_t section_length = | |
| 793 decoder.consume_u32v(§ion_leb_length, "section length"); | |
| 794 | 763 |
| 795 const byte* section_start = decoder.pc(); | 764 const byte* section_start = decoder.pc(); |
| 796 decoder.consume_bytes(section_length); | 765 decoder.consume_bytes(section_length); |
| 797 if (section == code && decoder.ok()) { | 766 if (section == code && decoder.ok()) { |
| 798 return Vector<const uint8_t>(section_start, section_length); | 767 return Vector<const uint8_t>(section_start, section_length); |
| 799 } | 768 } |
| 800 } | 769 } |
| 801 | 770 |
| 802 return Vector<const uint8_t>(); | 771 return Vector<const uint8_t>(); |
| 803 } | 772 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 return decoder.DecodeSingleFunction(module_env, function); | 817 return decoder.DecodeSingleFunction(module_env, function); |
| 849 } | 818 } |
| 850 | 819 |
| 851 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, | 820 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, |
| 852 const byte* module_end) { | 821 const byte* module_end) { |
| 853 Vector<const byte> code_section = | 822 Vector<const byte> code_section = |
| 854 FindSection(module_start, module_end, WasmSection::Code::FunctionBodies); | 823 FindSection(module_start, module_end, WasmSection::Code::FunctionBodies); |
| 855 Decoder decoder(code_section.start(), code_section.end()); | 824 Decoder decoder(code_section.start(), code_section.end()); |
| 856 if (!code_section.start()) decoder.error("no code section"); | 825 if (!code_section.start()) decoder.error("no code section"); |
| 857 | 826 |
| 858 int length; | 827 uint32_t functions_count = decoder.consume_u32v("functions count"); |
| 859 uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); | |
| 860 FunctionOffsets table; | 828 FunctionOffsets table; |
| 861 // Take care of invalid input here. | 829 // Take care of invalid input here. |
| 862 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) | 830 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) |
| 863 table.reserve(functions_count); | 831 table.reserve(functions_count); |
| 864 int section_offset = static_cast<int>(code_section.start() - module_start); | 832 int section_offset = static_cast<int>(code_section.start() - module_start); |
| 865 DCHECK_LE(0, section_offset); | 833 DCHECK_LE(0, section_offset); |
| 866 for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { | 834 for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { |
| 867 uint32_t size = decoder.consume_u32v(&length, "body size"); | 835 uint32_t size = decoder.consume_u32v("body size"); |
| 868 int offset = static_cast<int>(section_offset + decoder.pc_offset()); | 836 int offset = static_cast<int>(section_offset + decoder.pc_offset()); |
| 869 table.push_back(std::make_pair(offset, static_cast<int>(size))); | 837 table.push_back(std::make_pair(offset, static_cast<int>(size))); |
| 870 DCHECK(table.back().first >= 0 && table.back().second >= 0); | 838 DCHECK(table.back().first >= 0 && table.back().second >= 0); |
| 871 decoder.consume_bytes(size); | 839 decoder.consume_bytes(size); |
| 872 } | 840 } |
| 873 if (decoder.more()) decoder.error("unexpected additional bytes"); | 841 if (decoder.more()) decoder.error("unexpected additional bytes"); |
| 874 | 842 |
| 875 return decoder.toResult(std::move(table)); | 843 return decoder.toResult(std::move(table)); |
| 876 } | 844 } |
| 877 | 845 |
| 878 } // namespace wasm | 846 } // namespace wasm |
| 879 } // namespace internal | 847 } // namespace internal |
| 880 } // namespace v8 | 848 } // namespace v8 |
| OLD | NEW |