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 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_bytes = consume_u32v(&length, "section size"); | |
|
titzer
2016/03/09 13:19:37
section_size
*_bytes sounds like it might refer t
JF
2016/03/09 18:51:52
Done.
| |
| 84 | |
| 85 uint32_t section_string_bytes; | |
|
titzer
2016/03/09 13:19:37
section_string_size
JF
2016/03/09 18:51:52
Done.
| |
| 86 WasmSection::Code section = consume_section_name(§ion_string_bytes); | |
| 87 if (section_string_bytes > section_bytes) { | |
| 88 error(pos, pos, | |
| 89 "section string of size %u longer than total section bytes %u", | |
| 90 section_string_bytes, section_bytes); | |
| 91 break; | |
| 92 } | |
| 93 | |
| 94 if (section == WasmSection::Code::Max) { | |
| 83 // Skip unknown section. | 95 // Skip unknown section. |
| 84 int length; | 96 consume_bytes(section_bytes - section_string_bytes); |
| 85 uint32_t section_bytes = consume_u32v(&length, "section size"); | |
| 86 consume_bytes(section_bytes); | |
| 87 continue; | 97 continue; |
| 88 } | 98 } |
| 89 | 99 |
| 90 // Each section should appear at most once. | 100 // Each section should appear at most once. |
| 91 auto section = static_cast<WasmSectionDeclCode>(section_u8); | |
| 92 CheckForPreviousSection(sections, section, false); | 101 CheckForPreviousSection(sections, section, false); |
| 93 sections[section] = true; | 102 sections[(size_t)section] = true; |
| 94 | 103 |
| 95 switch (section) { | 104 switch (section) { |
| 96 case kDeclEnd: | 105 case WasmSection::Code::End: |
| 97 // Terminate section decoding. | 106 // Terminate section decoding. |
| 98 limit_ = pc_; | 107 limit_ = pc_; |
| 99 break; | 108 break; |
| 100 case kDeclMemory: | 109 case WasmSection::Code::Memory: |
| 101 int length; | 110 int length; |
| 102 module->min_mem_pages = consume_u32v(&length, "min memory"); | 111 module->min_mem_pages = consume_u32v(&length, "min memory"); |
| 103 module->max_mem_pages = consume_u32v(&length, "max memory"); | 112 module->max_mem_pages = consume_u32v(&length, "max memory"); |
| 104 module->mem_export = consume_u8("export memory") != 0; | 113 module->mem_export = consume_u8("export memory") != 0; |
| 105 break; | 114 break; |
| 106 case kDeclSignatures: { | 115 case WasmSection::Code::Signatures: { |
| 107 int length; | 116 int length; |
| 108 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 117 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
| 109 module->signatures.reserve(SafeReserve(signatures_count)); | 118 module->signatures.reserve(SafeReserve(signatures_count)); |
| 110 // Decode signatures. | 119 // Decode signatures. |
| 111 for (uint32_t i = 0; i < signatures_count; i++) { | 120 for (uint32_t i = 0; i < signatures_count; i++) { |
| 112 if (failed()) break; | 121 if (failed()) break; |
| 113 TRACE("DecodeSignature[%d] module+%d\n", i, | 122 TRACE("DecodeSignature[%d] module+%d\n", i, |
| 114 static_cast<int>(pc_ - start_)); | 123 static_cast<int>(pc_ - start_)); |
| 115 FunctionSig* s = consume_sig(); // read function sig. | 124 FunctionSig* s = consume_sig(); // read function sig. |
| 116 module->signatures.push_back(s); | 125 module->signatures.push_back(s); |
| 117 } | 126 } |
| 118 break; | 127 break; |
| 119 } | 128 } |
| 120 case kDeclFunctions: { | 129 case WasmSection::Code::Functions: { |
| 121 // Functions require a signature table first. | 130 // Functions require a signature table first. |
| 122 CheckForPreviousSection(sections, kDeclSignatures, true); | 131 CheckForPreviousSection(sections, WasmSection::Code::Signatures, true) ; |
| 123 int length; | 132 int length; |
| 124 uint32_t functions_count = consume_u32v(&length, "functions count"); | 133 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 125 module->functions.reserve(SafeReserve(functions_count)); | 134 module->functions.reserve(SafeReserve(functions_count)); |
| 126 // Set up module environment for verification. | 135 // Set up module environment for verification. |
| 127 ModuleEnv menv; | 136 ModuleEnv menv; |
| 128 menv.module = module; | 137 menv.module = module; |
| 129 menv.instance = nullptr; | 138 menv.instance = nullptr; |
| 130 menv.origin = origin_; | 139 menv.origin = origin_; |
| 131 // Decode functions. | 140 // Decode functions. |
| 132 for (uint32_t i = 0; i < functions_count; i++) { | 141 for (uint32_t i = 0; i < functions_count; i++) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 145 WasmFunction* function = &module->functions[i]; | 154 WasmFunction* function = &module->functions[i]; |
| 146 if (!function->external) { | 155 if (!function->external) { |
| 147 VerifyFunctionBody(i, &menv, function); | 156 VerifyFunctionBody(i, &menv, function); |
| 148 if (result_.failed()) | 157 if (result_.failed()) |
| 149 error(result_.error_pc, result_.error_msg.get()); | 158 error(result_.error_pc, result_.error_msg.get()); |
| 150 } | 159 } |
| 151 } | 160 } |
| 152 } | 161 } |
| 153 break; | 162 break; |
| 154 } | 163 } |
| 155 case kDeclGlobals: { | 164 case WasmSection::Code::Globals: { |
| 156 int length; | 165 int length; |
| 157 uint32_t globals_count = consume_u32v(&length, "globals count"); | 166 uint32_t globals_count = consume_u32v(&length, "globals count"); |
| 158 module->globals.reserve(SafeReserve(globals_count)); | 167 module->globals.reserve(SafeReserve(globals_count)); |
| 159 // Decode globals. | 168 // Decode globals. |
| 160 for (uint32_t i = 0; i < globals_count; i++) { | 169 for (uint32_t i = 0; i < globals_count; i++) { |
| 161 if (failed()) break; | 170 if (failed()) break; |
| 162 TRACE("DecodeGlobal[%d] module+%d\n", i, | 171 TRACE("DecodeGlobal[%d] module+%d\n", i, |
| 163 static_cast<int>(pc_ - start_)); | 172 static_cast<int>(pc_ - start_)); |
| 164 module->globals.push_back({0, MachineType::Int32(), 0, false}); | 173 module->globals.push_back({0, MachineType::Int32(), 0, false}); |
| 165 WasmGlobal* global = &module->globals.back(); | 174 WasmGlobal* global = &module->globals.back(); |
| 166 DecodeGlobalInModule(global); | 175 DecodeGlobalInModule(global); |
| 167 } | 176 } |
| 168 break; | 177 break; |
| 169 } | 178 } |
| 170 case kDeclDataSegments: { | 179 case WasmSection::Code::DataSegments: { |
| 171 int length; | 180 int length; |
| 172 uint32_t data_segments_count = | 181 uint32_t data_segments_count = |
| 173 consume_u32v(&length, "data segments count"); | 182 consume_u32v(&length, "data segments count"); |
| 174 module->data_segments.reserve(SafeReserve(data_segments_count)); | 183 module->data_segments.reserve(SafeReserve(data_segments_count)); |
| 175 // Decode data segments. | 184 // Decode data segments. |
| 176 for (uint32_t i = 0; i < data_segments_count; i++) { | 185 for (uint32_t i = 0; i < data_segments_count; i++) { |
| 177 if (failed()) break; | 186 if (failed()) break; |
| 178 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 187 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
| 179 static_cast<int>(pc_ - start_)); | 188 static_cast<int>(pc_ - start_)); |
| 180 module->data_segments.push_back({0, 0, 0}); | 189 module->data_segments.push_back({0, 0, 0}); |
| 181 WasmDataSegment* segment = &module->data_segments.back(); | 190 WasmDataSegment* segment = &module->data_segments.back(); |
| 182 DecodeDataSegmentInModule(module, segment); | 191 DecodeDataSegmentInModule(module, segment); |
| 183 } | 192 } |
| 184 break; | 193 break; |
| 185 } | 194 } |
| 186 case kDeclFunctionTable: { | 195 case WasmSection::Code::FunctionTable: { |
| 187 // An indirect function table requires functions first. | 196 // An indirect function table requires functions first. |
| 188 CheckForPreviousSection(sections, kDeclFunctions, true); | 197 CheckForPreviousSection(sections, WasmSection::Code::Functions, true); |
| 189 int length; | 198 int length; |
| 190 uint32_t function_table_count = | 199 uint32_t function_table_count = |
| 191 consume_u32v(&length, "function table count"); | 200 consume_u32v(&length, "function table count"); |
| 192 module->function_table.reserve(SafeReserve(function_table_count)); | 201 module->function_table.reserve(SafeReserve(function_table_count)); |
| 193 // Decode function table. | 202 // Decode function table. |
| 194 for (uint32_t i = 0; i < function_table_count; i++) { | 203 for (uint32_t i = 0; i < function_table_count; i++) { |
| 195 if (failed()) break; | 204 if (failed()) break; |
| 196 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 205 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
| 197 static_cast<int>(pc_ - start_)); | 206 static_cast<int>(pc_ - start_)); |
| 198 uint16_t index = consume_u16(); | 207 uint16_t index = consume_u16(); |
| 199 if (index >= module->functions.size()) { | 208 if (index >= module->functions.size()) { |
| 200 error(pc_ - 2, "invalid function index"); | 209 error(pc_ - 2, "invalid function index"); |
| 201 break; | 210 break; |
| 202 } | 211 } |
| 203 module->function_table.push_back(index); | 212 module->function_table.push_back(index); |
| 204 } | 213 } |
| 205 break; | 214 break; |
| 206 } | 215 } |
| 207 case kDeclStartFunction: { | 216 case WasmSection::Code::StartFunction: { |
| 208 // Declares a start function for a module. | 217 // Declares a start function for a module. |
| 209 CheckForPreviousSection(sections, kDeclFunctions, true); | 218 CheckForPreviousSection(sections, WasmSection::Code::Functions, true); |
| 210 if (module->start_function_index >= 0) { | 219 if (module->start_function_index >= 0) { |
| 211 error("start function already declared"); | 220 error("start function already declared"); |
| 212 break; | 221 break; |
| 213 } | 222 } |
| 214 int length; | 223 int length; |
| 215 const byte* before = pc_; | 224 const byte* before = pc_; |
| 216 uint32_t index = consume_u32v(&length, "start function index"); | 225 uint32_t index = consume_u32v(&length, "start function index"); |
| 217 if (index >= module->functions.size()) { | 226 if (index >= module->functions.size()) { |
| 218 error(before, "invalid start function index"); | 227 error(before, "invalid start function index"); |
| 219 break; | 228 break; |
| 220 } | 229 } |
| 221 module->start_function_index = static_cast<int>(index); | 230 module->start_function_index = static_cast<int>(index); |
| 222 FunctionSig* sig = | 231 FunctionSig* sig = |
| 223 module->signatures[module->functions[index].sig_index]; | 232 module->signatures[module->functions[index].sig_index]; |
| 224 if (sig->parameter_count() > 0) { | 233 if (sig->parameter_count() > 0) { |
| 225 error(before, "invalid start function: non-zero parameter count"); | 234 error(before, "invalid start function: non-zero parameter count"); |
| 226 break; | 235 break; |
| 227 } | 236 } |
| 228 break; | 237 break; |
| 229 } | 238 } |
| 230 case kDeclImportTable: { | 239 case WasmSection::Code::ImportTable: { |
| 231 // Declares an import table. | 240 // Declares an import table. |
| 232 CheckForPreviousSection(sections, kDeclSignatures, true); | 241 CheckForPreviousSection(sections, WasmSection::Code::Signatures, true) ; |
| 233 int length; | 242 int length; |
| 234 uint32_t import_table_count = | 243 uint32_t import_table_count = |
| 235 consume_u32v(&length, "import table count"); | 244 consume_u32v(&length, "import table count"); |
| 236 module->import_table.reserve(SafeReserve(import_table_count)); | 245 module->import_table.reserve(SafeReserve(import_table_count)); |
| 237 // Decode import table. | 246 // Decode import table. |
| 238 for (uint32_t i = 0; i < import_table_count; i++) { | 247 for (uint32_t i = 0; i < import_table_count; i++) { |
| 239 if (failed()) break; | 248 if (failed()) break; |
| 240 TRACE("DecodeImportTable[%d] module+%d\n", i, | 249 TRACE("DecodeImportTable[%d] module+%d\n", i, |
| 241 static_cast<int>(pc_ - start_)); | 250 static_cast<int>(pc_ - start_)); |
| 242 | 251 |
| 243 module->import_table.push_back({nullptr, 0, 0}); | 252 module->import_table.push_back({nullptr, 0, 0}); |
| 244 WasmImport* import = &module->import_table.back(); | 253 WasmImport* import = &module->import_table.back(); |
| 245 | 254 |
| 246 const byte* sigpos = pc_; | 255 const byte* sigpos = pc_; |
| 247 import->sig_index = consume_u16("signature index"); | 256 import->sig_index = consume_u16("signature index"); |
| 248 | 257 |
| 249 if (import->sig_index >= module->signatures.size()) { | 258 if (import->sig_index >= module->signatures.size()) { |
| 250 error(sigpos, "invalid signature index"); | 259 error(sigpos, "invalid signature index"); |
| 251 } else { | 260 } else { |
| 252 import->sig = module->signatures[import->sig_index]; | 261 import->sig = module->signatures[import->sig_index]; |
| 253 } | 262 } |
| 254 import->module_name_offset = consume_string("import module name"); | 263 import->module_name_offset = consume_string("import module name"); |
| 255 import->function_name_offset = | 264 import->function_name_offset = |
| 256 consume_string("import function name"); | 265 consume_string("import function name"); |
| 257 } | 266 } |
| 258 break; | 267 break; |
| 259 } | 268 } |
| 260 case kDeclExportTable: { | 269 case WasmSection::Code::ExportTable: { |
| 261 // Declares an export table. | 270 // Declares an export table. |
| 262 CheckForPreviousSection(sections, kDeclFunctions, true); | 271 CheckForPreviousSection(sections, WasmSection::Code::Functions, true); |
| 263 int length; | 272 int length; |
| 264 uint32_t export_table_count = | 273 uint32_t export_table_count = |
| 265 consume_u32v(&length, "export table count"); | 274 consume_u32v(&length, "export table count"); |
| 266 module->export_table.reserve(SafeReserve(export_table_count)); | 275 module->export_table.reserve(SafeReserve(export_table_count)); |
| 267 // Decode export table. | 276 // Decode export table. |
| 268 for (uint32_t i = 0; i < export_table_count; i++) { | 277 for (uint32_t i = 0; i < export_table_count; i++) { |
| 269 if (failed()) break; | 278 if (failed()) break; |
| 270 TRACE("DecodeExportTable[%d] module+%d\n", i, | 279 TRACE("DecodeExportTable[%d] module+%d\n", i, |
| 271 static_cast<int>(pc_ - start_)); | 280 static_cast<int>(pc_ - start_)); |
| 272 | 281 |
| 273 module->export_table.push_back({0, 0}); | 282 module->export_table.push_back({0, 0}); |
| 274 WasmExport* exp = &module->export_table.back(); | 283 WasmExport* exp = &module->export_table.back(); |
| 275 | 284 |
| 276 const byte* sigpos = pc_; | 285 const byte* sigpos = pc_; |
| 277 exp->func_index = consume_u16("function index"); | 286 exp->func_index = consume_u16("function index"); |
| 278 if (exp->func_index >= module->functions.size()) { | 287 if (exp->func_index >= module->functions.size()) { |
| 279 error(sigpos, sigpos, | 288 error(sigpos, sigpos, |
| 280 "function index %u out of bounds (%d functions)", | 289 "function index %u out of bounds (%d functions)", |
| 281 exp->func_index, | 290 exp->func_index, |
| 282 static_cast<int>(module->functions.size())); | 291 static_cast<int>(module->functions.size())); |
| 283 } | 292 } |
| 284 exp->name_offset = consume_string("export name"); | 293 exp->name_offset = consume_string("export name"); |
| 285 } | 294 } |
| 286 break; | 295 break; |
| 287 } | 296 } |
| 288 case kMaxModuleSectionCode: | 297 case WasmSection::Code::Max: |
| 289 UNREACHABLE(); // Already skipped unknown sections. | 298 UNREACHABLE(); // Already skipped unknown sections. |
| 290 } | 299 } |
| 291 } | 300 } |
| 292 | 301 |
| 293 return toResult(module); | 302 return toResult(module); |
| 294 } | 303 } |
| 295 | 304 |
| 296 uint32_t SafeReserve(uint32_t count) { | 305 uint32_t SafeReserve(uint32_t count) { |
| 297 // Avoid OOM by only reserving up to a certain size. | 306 // Avoid OOM by only reserving up to a certain size. |
| 298 const uint32_t kMaxReserve = 20000; | 307 const uint32_t kMaxReserve = 20000; |
| 299 return count < kMaxReserve ? count : kMaxReserve; | 308 return count < kMaxReserve ? count : kMaxReserve; |
| 300 } | 309 } |
| 301 | 310 |
| 302 void CheckForPreviousSection(bool* sections, WasmSectionDeclCode section, | 311 void CheckForPreviousSection(bool* sections, WasmSection::Code section, |
| 303 bool present) { | 312 bool present) { |
| 304 if (section >= kMaxModuleSectionCode) return; | 313 if (section >= WasmSection::Code::Max) return; |
| 305 if (sections[section] == present) return; | 314 if (sections[(size_t)section] == present) return; |
| 306 const char* name = ""; | |
| 307 switch (section) { | |
| 308 case kDeclMemory: | |
| 309 name = "memory"; | |
| 310 break; | |
| 311 case kDeclSignatures: | |
| 312 name = "signatures"; | |
| 313 break; | |
| 314 case kDeclFunctions: | |
| 315 name = "function declaration"; | |
| 316 break; | |
| 317 case kDeclGlobals: | |
| 318 name = "global variable"; | |
| 319 break; | |
| 320 case kDeclDataSegments: | |
| 321 name = "data segment"; | |
| 322 break; | |
| 323 case kDeclFunctionTable: | |
| 324 name = "function table"; | |
| 325 break; | |
| 326 default: | |
| 327 name = ""; | |
| 328 break; | |
| 329 } | |
| 330 if (present) { | 315 if (present) { |
| 331 error(pc_ - 1, nullptr, "required %s section missing", name); | 316 error(pc_ - 1, nullptr, "required %s section missing", |
| 317 WasmSection::getName(section)); | |
| 332 } else { | 318 } else { |
| 333 error(pc_ - 1, nullptr, "%s section already present", name); | 319 error(pc_ - 1, nullptr, "%s section already present", |
| 320 WasmSection::getName(section)); | |
| 334 } | 321 } |
| 335 } | 322 } |
| 336 | 323 |
| 337 // Decodes a single anonymous function starting at {start_}. | 324 // Decodes a single anonymous function starting at {start_}. |
| 338 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, | 325 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
| 339 WasmFunction* function) { | 326 WasmFunction* function) { |
| 340 pc_ = start_; | 327 pc_ = start_; |
| 341 function->sig = consume_sig(); // read signature | 328 function->sig = consume_sig(); // read signature |
| 342 function->name_offset = 0; // ---- name | 329 function->name_offset = 0; // ---- name |
| 343 function->code_start_offset = off(pc_); // ---- code start | 330 function->code_start_offset = off(pc_); // ---- code start |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 501 return offset; | 488 return offset; |
| 502 } | 489 } |
| 503 | 490 |
| 504 // Reads a single 32-bit unsigned integer interpreted as an offset into the | 491 // Reads a single 32-bit unsigned integer interpreted as an offset into the |
| 505 // data and validating the string there and advances. | 492 // data and validating the string there and advances. |
| 506 uint32_t consume_string(const char* name = nullptr) { | 493 uint32_t consume_string(const char* name = nullptr) { |
| 507 // TODO(titzer): validate string | 494 // TODO(titzer): validate string |
| 508 return consume_offset(name ? name : "string"); | 495 return consume_offset(name ? name : "string"); |
| 509 } | 496 } |
| 510 | 497 |
| 498 // Reads a section name. | |
| 499 WasmSection::Code consume_section_name(uint32_t* string_bytes) { | |
| 500 int length; | |
| 501 *string_bytes = consume_u32v(&length, "name length"); | |
| 502 const byte* start = pc_; | |
| 503 consume_bytes(*string_bytes); | |
| 504 if (failed()) { | |
| 505 TRACE("Section name of length %u couldn't be read\n", *string_bytes); | |
| 506 return WasmSection::Code::Max; | |
| 507 } | |
| 508 for (WasmSection::Code i = WasmSection::begin(); i != WasmSection::end(); | |
| 509 i = WasmSection::next(i)) { | |
| 510 if (WasmSection::getNameLength(i) == *string_bytes && | |
|
titzer
2016/03/09 13:19:37
Can you drop in a TODO here? It's a linear search.
JF
2016/03/09 18:51:52
Done.
| |
| 511 0 == memcmp(WasmSection::getName(i), start, *string_bytes)) { | |
| 512 return i; | |
| 513 } | |
| 514 } | |
| 515 TRACE("Unknown section: '%*s'\n", *string_bytes, start); | |
| 516 return WasmSection::Code::Max; | |
| 517 } | |
| 518 | |
| 511 // Reads a single 8-bit integer, interpreting it as a local type. | 519 // Reads a single 8-bit integer, interpreting it as a local type. |
| 512 LocalType consume_local_type() { | 520 LocalType consume_local_type() { |
| 513 byte val = consume_u8("local type"); | 521 byte val = consume_u8("local type"); |
| 514 LocalTypeCode t = static_cast<LocalTypeCode>(val); | 522 LocalTypeCode t = static_cast<LocalTypeCode>(val); |
| 515 switch (t) { | 523 switch (t) { |
| 516 case kLocalVoid: | 524 case kLocalVoid: |
| 517 return kAstStmt; | 525 return kAstStmt; |
| 518 case kLocalI32: | 526 case kLocalI32: |
| 519 return kAstI32; | 527 return kAstI32; |
| 520 case kLocalI64: | 528 case kLocalI64: |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 if (function_start > function_end) return FunctionError("start > end"); | 639 if (function_start > function_end) return FunctionError("start > end"); |
| 632 if (size > kMaxFunctionSize) | 640 if (size > kMaxFunctionSize) |
| 633 return FunctionError("size > maximum function size"); | 641 return FunctionError("size > maximum function size"); |
| 634 WasmFunction* function = new WasmFunction(); | 642 WasmFunction* function = new WasmFunction(); |
| 635 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 643 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
| 636 return decoder.DecodeSingleFunction(module_env, function); | 644 return decoder.DecodeSingleFunction(module_env, function); |
| 637 } | 645 } |
| 638 } // namespace wasm | 646 } // namespace wasm |
| 639 } // namespace internal | 647 } // namespace internal |
| 640 } // namespace v8 | 648 } // namespace v8 |
| OLD | NEW |