| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { | 44 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { |
| 45 pc_ = start_; | 45 pc_ = start_; |
| 46 module->module_start = start_; | 46 module->module_start = start_; |
| 47 module->module_end = limit_; | 47 module->module_end = limit_; |
| 48 module->min_mem_pages = 0; | 48 module->min_mem_pages = 0; |
| 49 module->max_mem_pages = 0; | 49 module->max_mem_pages = 0; |
| 50 module->mem_export = false; | 50 module->mem_export = false; |
| 51 module->mem_external = false; | 51 module->mem_external = false; |
| 52 module->origin = origin_; | 52 module->origin = origin_; |
| 53 | 53 |
| 54 bool sections[kMaxModuleSectionCode] = {false}; | 54 bool sections[(size_t)WasmSection::Code::Max] = {false}; |
| 55 | 55 |
| 56 const byte* pos = pc_; | 56 const byte* pos = pc_; |
| 57 uint32_t magic_word = consume_u32("wasm magic"); | 57 uint32_t magic_word = consume_u32("wasm magic"); |
| 58 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff | 58 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff |
| 59 if (magic_word != kWasmMagic) { | 59 if (magic_word != kWasmMagic) { |
| 60 error(pos, pos, | 60 error(pos, pos, |
| 61 "expected magic word %02x %02x %02x %02x, " | 61 "expected magic word %02x %02x %02x %02x, " |
| 62 "found %02x %02x %02x %02x", | 62 "found %02x %02x %02x %02x", |
| 63 BYTES(kWasmMagic), BYTES(magic_word)); | 63 BYTES(kWasmMagic), BYTES(magic_word)); |
| 64 return toResult(module); | 64 return toResult(module); |
| 65 } | 65 } |
| 66 | 66 |
| 67 pos = pc_; | 67 pos = pc_; |
| 68 uint32_t magic_version = consume_u32("wasm version"); | 68 uint32_t magic_version = consume_u32("wasm version"); |
| 69 if (magic_version != kWasmVersion) { | 69 if (magic_version != kWasmVersion) { |
| 70 error(pos, pos, | 70 error(pos, pos, |
| 71 "expected version %02x %02x %02x %02x, " | 71 "expected version %02x %02x %02x %02x, " |
| 72 "found %02x %02x %02x %02x", | 72 "found %02x %02x %02x %02x", |
| 73 BYTES(kWasmVersion), BYTES(magic_version)); | 73 BYTES(kWasmVersion), BYTES(magic_version)); |
| 74 return toResult(module); | 74 return toResult(module); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Decode the module sections. | 77 // Decode the module sections. |
| 78 while (pc_ < limit_) { | 78 while (pc_ < limit_) { |
| 79 TRACE("DecodeSection\n"); | 79 TRACE("DecodeSection\n"); |
| 80 uint8_t section_u8 = consume_u8("section"); | 80 pos = pc_; |
| 81 | 81 |
| 82 if (section_u8 >= kMaxModuleSectionCode) { | 82 int length; |
| 83 uint32_t section_length = consume_u32v(&length, "section size"); |
| 84 |
| 85 int section_string_leb_length; |
| 86 uint32_t section_string_length; |
| 87 WasmSection::Code section = consume_section_name( |
| 88 §ion_string_leb_length, §ion_string_length); |
| 89 uint32_t string_and_leb_length = |
| 90 section_string_leb_length + section_string_length; |
| 91 if (string_and_leb_length > section_length) { |
| 92 error(pos, pos, |
| 93 "section string of size %u longer than total section bytes %u", |
| 94 string_and_leb_length, section_length); |
| 95 break; |
| 96 } |
| 97 |
| 98 if (section == WasmSection::Code::Max) { |
| 83 // Skip unknown section. | 99 // Skip unknown section. |
| 84 int length; | 100 uint32_t skip = section_length - string_and_leb_length; |
| 85 uint32_t section_bytes = consume_u32v(&length, "section size"); | 101 TRACE("skipping %u bytes from unknown section\n", skip); |
| 86 consume_bytes(section_bytes); | 102 consume_bytes(skip); |
| 87 continue; | 103 continue; |
| 88 } | 104 } |
| 89 | 105 |
| 90 // Each section should appear at most once. | 106 // Each section should appear at most once. |
| 91 auto section = static_cast<WasmSectionDeclCode>(section_u8); | |
| 92 CheckForPreviousSection(sections, section, false); | 107 CheckForPreviousSection(sections, section, false); |
| 93 sections[section] = true; | 108 sections[(size_t)section] = true; |
| 94 | 109 |
| 95 switch (section) { | 110 switch (section) { |
| 96 case kDeclEnd: | 111 case WasmSection::Code::End: |
| 97 // Terminate section decoding. | 112 // Terminate section decoding. |
| 98 limit_ = pc_; | 113 limit_ = pc_; |
| 99 break; | 114 break; |
| 100 case kDeclMemory: | 115 case WasmSection::Code::Memory: |
| 101 int length; | 116 int length; |
| 102 module->min_mem_pages = consume_u32v(&length, "min memory"); | 117 module->min_mem_pages = consume_u32v(&length, "min memory"); |
| 103 module->max_mem_pages = consume_u32v(&length, "max memory"); | 118 module->max_mem_pages = consume_u32v(&length, "max memory"); |
| 104 module->mem_export = consume_u8("export memory") != 0; | 119 module->mem_export = consume_u8("export memory") != 0; |
| 105 break; | 120 break; |
| 106 case kDeclSignatures: { | 121 case WasmSection::Code::Signatures: { |
| 107 int length; | 122 int length; |
| 108 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 123 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
| 109 module->signatures.reserve(SafeReserve(signatures_count)); | 124 module->signatures.reserve(SafeReserve(signatures_count)); |
| 110 // Decode signatures. | 125 // Decode signatures. |
| 111 for (uint32_t i = 0; i < signatures_count; i++) { | 126 for (uint32_t i = 0; i < signatures_count; i++) { |
| 112 if (failed()) break; | 127 if (failed()) break; |
| 113 TRACE("DecodeSignature[%d] module+%d\n", i, | 128 TRACE("DecodeSignature[%d] module+%d\n", i, |
| 114 static_cast<int>(pc_ - start_)); | 129 static_cast<int>(pc_ - start_)); |
| 115 FunctionSig* s = consume_sig(); // read function sig. | 130 FunctionSig* s = consume_sig(); // read function sig. |
| 116 module->signatures.push_back(s); | 131 module->signatures.push_back(s); |
| 117 } | 132 } |
| 118 break; | 133 break; |
| 119 } | 134 } |
| 120 case kDeclFunctionSignatures: { | 135 case WasmSection::Code::FunctionSignatures: { |
| 121 // Functions require a signature table first. | 136 // Functions require a signature table first. |
| 122 CheckForPreviousSection(sections, kDeclSignatures, true); | 137 CheckForPreviousSection(sections, WasmSection::Code::Signatures, |
| 138 true); |
| 123 int length; | 139 int length; |
| 124 uint32_t functions_count = consume_u32v(&length, "functions count"); | 140 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 125 module->functions.reserve(SafeReserve(functions_count)); | 141 module->functions.reserve(SafeReserve(functions_count)); |
| 126 for (uint32_t i = 0; i < functions_count; i++) { | 142 for (uint32_t i = 0; i < functions_count; i++) { |
| 127 module->functions.push_back( | 143 module->functions.push_back( |
| 128 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); | 144 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); |
| 129 WasmFunction* function = &module->functions.back(); | 145 WasmFunction* function = &module->functions.back(); |
| 130 function->sig_index = consume_sig_index(module, &function->sig); | 146 function->sig_index = consume_sig_index(module, &function->sig); |
| 131 } | 147 } |
| 132 break; | 148 break; |
| 133 } | 149 } |
| 134 case kDeclFunctionBodies: { | 150 case WasmSection::Code::FunctionBodies: { |
| 135 // Function bodies should follow signatures. | 151 // Function bodies should follow signatures. |
| 136 CheckForPreviousSection(sections, kDeclFunctionSignatures, true); | 152 CheckForPreviousSection(sections, |
| 153 WasmSection::Code::FunctionSignatures, true); |
| 137 int length; | 154 int length; |
| 138 const byte* pos = pc_; | 155 const byte* pos = pc_; |
| 139 uint32_t functions_count = consume_u32v(&length, "functions count"); | 156 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 140 if (functions_count != module->functions.size()) { | 157 if (functions_count != module->functions.size()) { |
| 141 error(pos, pos, "function body count %u mismatch (%u expected)", | 158 error(pos, pos, "function body count %u mismatch (%u expected)", |
| 142 functions_count, | 159 functions_count, |
| 143 static_cast<uint32_t>(module->functions.size())); | 160 static_cast<uint32_t>(module->functions.size())); |
| 144 break; | 161 break; |
| 145 } | 162 } |
| 146 for (uint32_t i = 0; i < functions_count; i++) { | 163 for (uint32_t i = 0; i < functions_count; i++) { |
| 147 WasmFunction* function = &module->functions[i]; | 164 WasmFunction* function = &module->functions[i]; |
| 148 int length; | 165 int length; |
| 149 uint32_t size = consume_u32v(&length, "body size"); | 166 uint32_t size = consume_u32v(&length, "body size"); |
| 150 function->code_start_offset = pc_offset(); | 167 function->code_start_offset = pc_offset(); |
| 151 function->code_end_offset = pc_offset() + size; | 168 function->code_end_offset = pc_offset() + size; |
| 152 | 169 |
| 153 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 170 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
| 154 size); | 171 size); |
| 155 pc_ += size; | 172 pc_ += size; |
| 156 if (pc_ > limit_) { | 173 if (pc_ > limit_) { |
| 157 error(pc_, "function body extends beyond end of file"); | 174 error(pc_, "function body extends beyond end of file"); |
| 158 } | 175 } |
| 159 } | 176 } |
| 160 break; | 177 break; |
| 161 } | 178 } |
| 162 case kDeclFunctions: { | 179 case WasmSection::Code::Functions: { |
| 163 // Functions require a signature table first. | 180 // Functions require a signature table first. |
| 164 CheckForPreviousSection(sections, kDeclSignatures, true); | 181 CheckForPreviousSection(sections, WasmSection::Code::Signatures, |
| 182 true); |
| 165 int length; | 183 int length; |
| 166 uint32_t functions_count = consume_u32v(&length, "functions count"); | 184 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 167 module->functions.reserve(SafeReserve(functions_count)); | 185 module->functions.reserve(SafeReserve(functions_count)); |
| 168 // Set up module environment for verification. | 186 // Set up module environment for verification. |
| 169 ModuleEnv menv; | 187 ModuleEnv menv; |
| 170 menv.module = module; | 188 menv.module = module; |
| 171 menv.instance = nullptr; | 189 menv.instance = nullptr; |
| 172 menv.origin = origin_; | 190 menv.origin = origin_; |
| 173 // Decode functions. | 191 // Decode functions. |
| 174 for (uint32_t i = 0; i < functions_count; i++) { | 192 for (uint32_t i = 0; i < functions_count; i++) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 187 WasmFunction* function = &module->functions[i]; | 205 WasmFunction* function = &module->functions[i]; |
| 188 if (!function->external) { | 206 if (!function->external) { |
| 189 VerifyFunctionBody(i, &menv, function); | 207 VerifyFunctionBody(i, &menv, function); |
| 190 if (result_.failed()) | 208 if (result_.failed()) |
| 191 error(result_.error_pc, result_.error_msg.get()); | 209 error(result_.error_pc, result_.error_msg.get()); |
| 192 } | 210 } |
| 193 } | 211 } |
| 194 } | 212 } |
| 195 break; | 213 break; |
| 196 } | 214 } |
| 197 case kDeclNames: { | 215 case WasmSection::Code::Names: { |
| 198 // Names correspond to functions. | 216 // Names correspond to functions. |
| 199 CheckForPreviousSection(sections, kDeclFunctionSignatures, true); | 217 CheckForPreviousSection(sections, |
| 218 WasmSection::Code::FunctionSignatures, true); |
| 200 int length; | 219 int length; |
| 201 const byte* pos = pc_; | 220 const byte* pos = pc_; |
| 202 uint32_t functions_count = consume_u32v(&length, "functions count"); | 221 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 203 if (functions_count != module->functions.size()) { | 222 if (functions_count != module->functions.size()) { |
| 204 error(pos, pos, "function name count %u mismatch (%u expected)", | 223 error(pos, pos, "function name count %u mismatch (%u expected)", |
| 205 functions_count, | 224 functions_count, |
| 206 static_cast<uint32_t>(module->functions.size())); | 225 static_cast<uint32_t>(module->functions.size())); |
| 207 break; | 226 break; |
| 208 } | 227 } |
| 209 | 228 |
| 210 for (uint32_t i = 0; i < functions_count; i++) { | 229 for (uint32_t i = 0; i < functions_count; i++) { |
| 211 WasmFunction* function = &module->functions[i]; | 230 WasmFunction* function = &module->functions[i]; |
| 212 function->name_offset = | 231 function->name_offset = |
| 213 consume_string(&function->name_length, "function name"); | 232 consume_string(&function->name_length, "function name"); |
| 214 | 233 |
| 215 uint32_t local_names_count = | 234 uint32_t local_names_count = |
| 216 consume_u32v(&length, "local names count"); | 235 consume_u32v(&length, "local names count"); |
| 217 for (uint32_t j = 0; j < local_names_count; j++) { | 236 for (uint32_t j = 0; j < local_names_count; j++) { |
| 218 uint32_t unused = 0; | 237 uint32_t unused = 0; |
| 219 uint32_t offset = consume_string(&unused, "local name"); | 238 uint32_t offset = consume_string(&unused, "local name"); |
| 220 USE(unused); | 239 USE(unused); |
| 221 USE(offset); | 240 USE(offset); |
| 222 } | 241 } |
| 223 } | 242 } |
| 224 break; | 243 break; |
| 225 } | 244 } |
| 226 case kDeclGlobals: { | 245 case WasmSection::Code::Globals: { |
| 227 int length; | 246 int length; |
| 228 uint32_t globals_count = consume_u32v(&length, "globals count"); | 247 uint32_t globals_count = consume_u32v(&length, "globals count"); |
| 229 module->globals.reserve(SafeReserve(globals_count)); | 248 module->globals.reserve(SafeReserve(globals_count)); |
| 230 // Decode globals. | 249 // Decode globals. |
| 231 for (uint32_t i = 0; i < globals_count; i++) { | 250 for (uint32_t i = 0; i < globals_count; i++) { |
| 232 if (failed()) break; | 251 if (failed()) break; |
| 233 TRACE("DecodeGlobal[%d] module+%d\n", i, | 252 TRACE("DecodeGlobal[%d] module+%d\n", i, |
| 234 static_cast<int>(pc_ - start_)); | 253 static_cast<int>(pc_ - start_)); |
| 235 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); | 254 module->globals.push_back({0, 0, MachineType::Int32(), 0, false}); |
| 236 WasmGlobal* global = &module->globals.back(); | 255 WasmGlobal* global = &module->globals.back(); |
| 237 DecodeGlobalInModule(global); | 256 DecodeGlobalInModule(global); |
| 238 } | 257 } |
| 239 break; | 258 break; |
| 240 } | 259 } |
| 241 case kDeclDataSegments: { | 260 case WasmSection::Code::DataSegments: { |
| 242 int length; | 261 int length; |
| 243 uint32_t data_segments_count = | 262 uint32_t data_segments_count = |
| 244 consume_u32v(&length, "data segments count"); | 263 consume_u32v(&length, "data segments count"); |
| 245 module->data_segments.reserve(SafeReserve(data_segments_count)); | 264 module->data_segments.reserve(SafeReserve(data_segments_count)); |
| 246 // Decode data segments. | 265 // Decode data segments. |
| 247 for (uint32_t i = 0; i < data_segments_count; i++) { | 266 for (uint32_t i = 0; i < data_segments_count; i++) { |
| 248 if (failed()) break; | 267 if (failed()) break; |
| 249 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 268 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
| 250 static_cast<int>(pc_ - start_)); | 269 static_cast<int>(pc_ - start_)); |
| 251 module->data_segments.push_back({0, 0, 0}); | 270 module->data_segments.push_back({0, 0, 0}); |
| 252 WasmDataSegment* segment = &module->data_segments.back(); | 271 WasmDataSegment* segment = &module->data_segments.back(); |
| 253 DecodeDataSegmentInModule(module, segment); | 272 DecodeDataSegmentInModule(module, segment); |
| 254 } | 273 } |
| 255 break; | 274 break; |
| 256 } | 275 } |
| 257 case kDeclFunctionTable: { | 276 case WasmSection::Code::FunctionTable: { |
| 258 // An indirect function table requires functions first. | 277 // An indirect function table requires functions first. |
| 259 CheckForFunctions(module, section); | 278 CheckForFunctions(module, section); |
| 260 int length; | 279 int length; |
| 261 uint32_t function_table_count = | 280 uint32_t function_table_count = |
| 262 consume_u32v(&length, "function table count"); | 281 consume_u32v(&length, "function table count"); |
| 263 module->function_table.reserve(SafeReserve(function_table_count)); | 282 module->function_table.reserve(SafeReserve(function_table_count)); |
| 264 // Decode function table. | 283 // Decode function table. |
| 265 for (uint32_t i = 0; i < function_table_count; i++) { | 284 for (uint32_t i = 0; i < function_table_count; i++) { |
| 266 if (failed()) break; | 285 if (failed()) break; |
| 267 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 286 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
| 268 static_cast<int>(pc_ - start_)); | 287 static_cast<int>(pc_ - start_)); |
| 269 uint16_t index = consume_u32v(&length); | 288 uint16_t index = consume_u32v(&length); |
| 270 if (index >= module->functions.size()) { | 289 if (index >= module->functions.size()) { |
| 271 error(pc_ - 2, "invalid function index"); | 290 error(pc_ - 2, "invalid function index"); |
| 272 break; | 291 break; |
| 273 } | 292 } |
| 274 module->function_table.push_back(index); | 293 module->function_table.push_back(index); |
| 275 } | 294 } |
| 276 break; | 295 break; |
| 277 } | 296 } |
| 278 case kDeclStartFunction: { | 297 case WasmSection::Code::StartFunction: { |
| 279 // Declares a start function for a module. | 298 // Declares a start function for a module. |
| 280 CheckForFunctions(module, section); | 299 CheckForFunctions(module, section); |
| 281 if (module->start_function_index >= 0) { | 300 if (module->start_function_index >= 0) { |
| 282 error("start function already declared"); | 301 error("start function already declared"); |
| 283 break; | 302 break; |
| 284 } | 303 } |
| 285 WasmFunction* func; | 304 WasmFunction* func; |
| 286 const byte* pos = pc_; | 305 const byte* pos = pc_; |
| 287 module->start_function_index = consume_func_index(module, &func); | 306 module->start_function_index = consume_func_index(module, &func); |
| 288 if (func && func->sig->parameter_count() > 0) { | 307 if (func && func->sig->parameter_count() > 0) { |
| 289 error(pos, "invalid start function: non-zero parameter count"); | 308 error(pos, "invalid start function: non-zero parameter count"); |
| 290 break; | 309 break; |
| 291 } | 310 } |
| 292 break; | 311 break; |
| 293 } | 312 } |
| 294 case kDeclImportTable: { | 313 case WasmSection::Code::ImportTable: { |
| 295 // Declares an import table. | 314 // Declares an import table. |
| 296 CheckForPreviousSection(sections, kDeclSignatures, true); | 315 CheckForPreviousSection(sections, WasmSection::Code::Signatures, |
| 316 true); |
| 297 int length; | 317 int length; |
| 298 uint32_t import_table_count = | 318 uint32_t import_table_count = |
| 299 consume_u32v(&length, "import table count"); | 319 consume_u32v(&length, "import table count"); |
| 300 module->import_table.reserve(SafeReserve(import_table_count)); | 320 module->import_table.reserve(SafeReserve(import_table_count)); |
| 301 // Decode import table. | 321 // Decode import table. |
| 302 for (uint32_t i = 0; i < import_table_count; i++) { | 322 for (uint32_t i = 0; i < import_table_count; i++) { |
| 303 if (failed()) break; | 323 if (failed()) break; |
| 304 TRACE("DecodeImportTable[%d] module+%d\n", i, | 324 TRACE("DecodeImportTable[%d] module+%d\n", i, |
| 305 static_cast<int>(pc_ - start_)); | 325 static_cast<int>(pc_ - start_)); |
| 306 | 326 |
| 307 module->import_table.push_back({nullptr, 0, 0}); | 327 module->import_table.push_back({nullptr, 0, 0}); |
| 308 WasmImport* import = &module->import_table.back(); | 328 WasmImport* import = &module->import_table.back(); |
| 309 | 329 |
| 310 import->sig_index = consume_sig_index(module, &import->sig); | 330 import->sig_index = consume_sig_index(module, &import->sig); |
| 311 const byte* pos = pc_; | 331 const byte* pos = pc_; |
| 312 import->module_name_offset = consume_string( | 332 import->module_name_offset = consume_string( |
| 313 &import->module_name_length, "import module name"); | 333 &import->module_name_length, "import module name"); |
| 314 if (import->module_name_length == 0) { | 334 if (import->module_name_length == 0) { |
| 315 error(pos, "import module name cannot be NULL"); | 335 error(pos, "import module name cannot be NULL"); |
| 316 } | 336 } |
| 317 import->function_name_offset = consume_string( | 337 import->function_name_offset = consume_string( |
| 318 &import->function_name_length, "import function name"); | 338 &import->function_name_length, "import function name"); |
| 319 } | 339 } |
| 320 break; | 340 break; |
| 321 } | 341 } |
| 322 case kDeclExportTable: { | 342 case WasmSection::Code::ExportTable: { |
| 323 // Declares an export table. | 343 // Declares an export table. |
| 324 CheckForFunctions(module, section); | 344 CheckForFunctions(module, section); |
| 325 int length; | 345 int length; |
| 326 uint32_t export_table_count = | 346 uint32_t export_table_count = |
| 327 consume_u32v(&length, "export table count"); | 347 consume_u32v(&length, "export table count"); |
| 328 module->export_table.reserve(SafeReserve(export_table_count)); | 348 module->export_table.reserve(SafeReserve(export_table_count)); |
| 329 // Decode export table. | 349 // Decode export table. |
| 330 for (uint32_t i = 0; i < export_table_count; i++) { | 350 for (uint32_t i = 0; i < export_table_count; i++) { |
| 331 if (failed()) break; | 351 if (failed()) break; |
| 332 TRACE("DecodeExportTable[%d] module+%d\n", i, | 352 TRACE("DecodeExportTable[%d] module+%d\n", i, |
| 333 static_cast<int>(pc_ - start_)); | 353 static_cast<int>(pc_ - start_)); |
| 334 | 354 |
| 335 module->export_table.push_back({0, 0}); | 355 module->export_table.push_back({0, 0}); |
| 336 WasmExport* exp = &module->export_table.back(); | 356 WasmExport* exp = &module->export_table.back(); |
| 337 | 357 |
| 338 WasmFunction* func; | 358 WasmFunction* func; |
| 339 exp->func_index = consume_func_index(module, &func); | 359 exp->func_index = consume_func_index(module, &func); |
| 340 exp->name_offset = consume_string(&exp->name_length, "export name"); | 360 exp->name_offset = consume_string(&exp->name_length, "export name"); |
| 341 } | 361 } |
| 342 break; | 362 break; |
| 343 } | 363 } |
| 344 case kMaxModuleSectionCode: | 364 case WasmSection::Code::Max: |
| 345 UNREACHABLE(); // Already skipped unknown sections. | 365 UNREACHABLE(); // Already skipped unknown sections. |
| 346 } | 366 } |
| 347 } | 367 } |
| 348 | 368 |
| 349 return toResult(module); | 369 return toResult(module); |
| 350 } | 370 } |
| 351 | 371 |
| 352 uint32_t SafeReserve(uint32_t count) { | 372 uint32_t SafeReserve(uint32_t count) { |
| 353 // Avoid OOM by only reserving up to a certain size. | 373 // Avoid OOM by only reserving up to a certain size. |
| 354 const uint32_t kMaxReserve = 20000; | 374 const uint32_t kMaxReserve = 20000; |
| 355 return count < kMaxReserve ? count : kMaxReserve; | 375 return count < kMaxReserve ? count : kMaxReserve; |
| 356 } | 376 } |
| 357 | 377 |
| 358 const char* SectionName(WasmSectionDeclCode section) { | 378 void CheckForFunctions(WasmModule* module, WasmSection::Code section) { |
| 359 switch (section) { | 379 if (module->functions.size() == 0) { |
| 360 case kDeclMemory: | 380 error(pc_ - 1, nullptr, "functions must appear before section %s", |
| 361 return "memory"; | 381 WasmSection::getName(section)); |
| 362 case kDeclSignatures: | |
| 363 return "signatures"; | |
| 364 case kDeclFunctions: | |
| 365 return "function declaration"; | |
| 366 case kDeclGlobals: | |
| 367 return "global variable"; | |
| 368 case kDeclDataSegments: | |
| 369 return "data segment"; | |
| 370 case kDeclFunctionTable: | |
| 371 return "function table"; | |
| 372 default: | |
| 373 return ""; | |
| 374 } | 382 } |
| 375 } | 383 } |
| 376 | 384 |
| 377 void CheckForFunctions(WasmModule* module, WasmSectionDeclCode section) { | 385 void CheckForPreviousSection(bool* sections, WasmSection::Code section, |
| 378 if (module->functions.size() == 0) { | 386 bool present) { |
| 379 error(pc_ - 1, nullptr, "functions must appear before section %s", | 387 if (section >= WasmSection::Code::Max) return; |
| 380 SectionName(section)); | 388 if (sections[(size_t)section] == present) return; |
| 389 if (present) { |
| 390 error(pc_ - 1, nullptr, "required %s section missing", |
| 391 WasmSection::getName(section)); |
| 392 } else { |
| 393 error(pc_ - 1, nullptr, "%s section already present", |
| 394 WasmSection::getName(section)); |
| 381 } | 395 } |
| 382 } | 396 } |
| 383 | 397 |
| 384 void CheckForPreviousSection(bool* sections, WasmSectionDeclCode section, | |
| 385 bool present) { | |
| 386 if (section >= kMaxModuleSectionCode) return; | |
| 387 if (sections[section] == present) return; | |
| 388 const char* name = SectionName(section); | |
| 389 if (present) { | |
| 390 error(pc_ - 1, nullptr, "required %s section missing", name); | |
| 391 } else { | |
| 392 error(pc_ - 1, nullptr, "%s section already present", name); | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 // Decodes a single anonymous function starting at {start_}. | 398 // Decodes a single anonymous function starting at {start_}. |
| 397 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, | 399 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
| 398 WasmFunction* function) { | 400 WasmFunction* function) { |
| 399 pc_ = start_; | 401 pc_ = start_; |
| 400 function->sig = consume_sig(); // read signature | 402 function->sig = consume_sig(); // read signature |
| 401 function->name_offset = 0; // ---- name | 403 function->name_offset = 0; // ---- name |
| 402 function->name_length = 0; // ---- name length | 404 function->name_length = 0; // ---- name length |
| 403 function->code_start_offset = off(pc_); // ---- code start | 405 function->code_start_offset = off(pc_); // ---- code start |
| 404 function->code_end_offset = off(limit_); // ---- code end | 406 function->code_end_offset = off(limit_); // ---- code end |
| 405 function->exported = false; // ---- exported | 407 function->exported = false; // ---- exported |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 if (func_index >= module->functions.size()) { | 601 if (func_index >= module->functions.size()) { |
| 600 error(pos, pos, "function index %u out of bounds (%d functions)", | 602 error(pos, pos, "function index %u out of bounds (%d functions)", |
| 601 func_index, static_cast<int>(module->functions.size())); | 603 func_index, static_cast<int>(module->functions.size())); |
| 602 *func = nullptr; | 604 *func = nullptr; |
| 603 return 0; | 605 return 0; |
| 604 } | 606 } |
| 605 *func = &module->functions[func_index]; | 607 *func = &module->functions[func_index]; |
| 606 return func_index; | 608 return func_index; |
| 607 } | 609 } |
| 608 | 610 |
| 611 // Reads a section name. |
| 612 WasmSection::Code consume_section_name(int* string_leb_length, |
| 613 uint32_t* string_length) { |
| 614 *string_length = consume_u32v(string_leb_length, "name length"); |
| 615 const byte* start = pc_; |
| 616 consume_bytes(*string_length); |
| 617 if (failed()) { |
| 618 TRACE("Section name of length %u couldn't be read\n", *string_length); |
| 619 return WasmSection::Code::Max; |
| 620 } |
| 621 // TODO Linear search, it may be better to do a common-prefix search. |
| 622 for (WasmSection::Code i = WasmSection::begin(); i != WasmSection::end(); |
| 623 i = WasmSection::next(i)) { |
| 624 if (WasmSection::getNameLength(i) == *string_length && |
| 625 0 == memcmp(WasmSection::getName(i), start, *string_length)) { |
| 626 return i; |
| 627 } |
| 628 } |
| 629 TRACE("Unknown section: '"); |
| 630 for (uint32_t i = 0; i != *string_length; ++i) TRACE("%c", *(start + i)); |
| 631 TRACE("'\n"); |
| 632 return WasmSection::Code::Max; |
| 633 } |
| 634 |
| 609 // Reads a single 8-bit integer, interpreting it as a local type. | 635 // Reads a single 8-bit integer, interpreting it as a local type. |
| 610 LocalType consume_local_type() { | 636 LocalType consume_local_type() { |
| 611 byte val = consume_u8("local type"); | 637 byte val = consume_u8("local type"); |
| 612 LocalTypeCode t = static_cast<LocalTypeCode>(val); | 638 LocalTypeCode t = static_cast<LocalTypeCode>(val); |
| 613 switch (t) { | 639 switch (t) { |
| 614 case kLocalVoid: | 640 case kLocalVoid: |
| 615 return kAstStmt; | 641 return kAstStmt; |
| 616 case kLocalI32: | 642 case kLocalI32: |
| 617 return kAstI32; | 643 return kAstI32; |
| 618 case kLocalI64: | 644 case kLocalI64: |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 if (function_start > function_end) return FunctionError("start > end"); | 756 if (function_start > function_end) return FunctionError("start > end"); |
| 731 if (size > kMaxFunctionSize) | 757 if (size > kMaxFunctionSize) |
| 732 return FunctionError("size > maximum function size"); | 758 return FunctionError("size > maximum function size"); |
| 733 WasmFunction* function = new WasmFunction(); | 759 WasmFunction* function = new WasmFunction(); |
| 734 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 760 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
| 735 return decoder.DecodeSingleFunction(module_env, function); | 761 return decoder.DecodeSingleFunction(module_env, function); |
| 736 } | 762 } |
| 737 } // namespace wasm | 763 } // namespace wasm |
| 738 } // namespace internal | 764 } // namespace internal |
| 739 } // namespace v8 | 765 } // namespace v8 |
| OLD | NEW |