| 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/flags.h" | 9 #include "src/flags.h" |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| 11 #include "src/objects.h" | 11 #include "src/objects.h" |
| 12 #include "src/v8.h" | 12 #include "src/v8.h" |
| 13 | 13 |
| 14 #include "src/wasm/decoder.h" | 14 #include "src/wasm/decoder.h" |
| 15 #include "src/wasm/wasm-limits.h" |
| 15 | 16 |
| 16 namespace v8 { | 17 namespace v8 { |
| 17 namespace internal { | 18 namespace internal { |
| 18 namespace wasm { | 19 namespace wasm { |
| 19 | 20 |
| 20 #if DEBUG | 21 #if DEBUG |
| 21 #define TRACE(...) \ | 22 #define TRACE(...) \ |
| 22 do { \ | 23 do { \ |
| 23 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 24 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
| 24 } while (false) | 25 } while (false) |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 } | 306 } |
| 306 case kExternalTable: { | 307 case kExternalTable: { |
| 307 // ===== Imported table ========================================== | 308 // ===== Imported table ========================================== |
| 308 import->index = | 309 import->index = |
| 309 static_cast<uint32_t>(module->function_tables.size()); | 310 static_cast<uint32_t>(module->function_tables.size()); |
| 310 module->function_tables.push_back({0, 0, false, | 311 module->function_tables.push_back({0, 0, false, |
| 311 std::vector<int32_t>(), true, | 312 std::vector<int32_t>(), true, |
| 312 false, SignatureMap()}); | 313 false, SignatureMap()}); |
| 313 expect_u8("element type", kWasmAnyFunctionTypeForm); | 314 expect_u8("element type", kWasmAnyFunctionTypeForm); |
| 314 WasmIndirectFunctionTable* table = &module->function_tables.back(); | 315 WasmIndirectFunctionTable* table = &module->function_tables.back(); |
| 315 consume_resizable_limits( | 316 consume_resizable_limits("element count", "elements", |
| 316 "element count", "elements", WasmModule::kV8MaxTableSize, | 317 kV8MaxWasmTableSize, &table->min_size, |
| 317 &table->min_size, &table->has_max, WasmModule::kV8MaxTableSize, | 318 &table->has_max, kV8MaxWasmTableSize, |
| 318 &table->max_size); | 319 &table->max_size); |
| 319 break; | 320 break; |
| 320 } | 321 } |
| 321 case kExternalMemory: { | 322 case kExternalMemory: { |
| 322 // ===== Imported memory ========================================= | 323 // ===== Imported memory ========================================= |
| 323 bool has_max = false; | 324 bool has_max = false; |
| 324 consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages, | 325 consume_resizable_limits("memory", "pages", kV8MaxWasmMemoryPages, |
| 325 &module->min_mem_pages, &has_max, | 326 &module->min_mem_pages, &has_max, |
| 326 WasmModule::kSpecMaxPages, | 327 kSpecMaxWasmMemoryPages, |
| 327 &module->max_mem_pages); | 328 &module->max_mem_pages); |
| 328 module->has_memory = true; | 329 module->has_memory = true; |
| 329 break; | 330 break; |
| 330 } | 331 } |
| 331 case kExternalGlobal: { | 332 case kExternalGlobal: { |
| 332 // ===== Imported global ========================================= | 333 // ===== Imported global ========================================= |
| 333 import->index = static_cast<uint32_t>(module->globals.size()); | 334 import->index = static_cast<uint32_t>(module->globals.size()); |
| 334 module->globals.push_back( | 335 module->globals.push_back( |
| 335 {kAstStmt, false, WasmInitExpr(), 0, true, false}); | 336 {kAstStmt, false, WasmInitExpr(), 0, true, false}); |
| 336 WasmGlobal* global = &module->globals.back(); | 337 WasmGlobal* global = &module->globals.back(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 error(pos, pos, "invalid table count %d, maximum 1", table_count); | 381 error(pos, pos, "invalid table count %d, maximum 1", table_count); |
| 381 } | 382 } |
| 382 if (module->function_tables.size() < 1) { | 383 if (module->function_tables.size() < 1) { |
| 383 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), | 384 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), |
| 384 false, false, SignatureMap()}); | 385 false, false, SignatureMap()}); |
| 385 } | 386 } |
| 386 | 387 |
| 387 for (uint32_t i = 0; ok() && i < table_count; i++) { | 388 for (uint32_t i = 0; ok() && i < table_count; i++) { |
| 388 WasmIndirectFunctionTable* table = &module->function_tables.back(); | 389 WasmIndirectFunctionTable* table = &module->function_tables.back(); |
| 389 expect_u8("table type", kWasmAnyFunctionTypeForm); | 390 expect_u8("table type", kWasmAnyFunctionTypeForm); |
| 390 consume_resizable_limits("table elements", "elements", | 391 consume_resizable_limits( |
| 391 WasmModule::kV8MaxTableSize, &table->min_size, | 392 "table elements", "elements", kV8MaxWasmTableSize, &table->min_size, |
| 392 &table->has_max, WasmModule::kV8MaxTableSize, | 393 &table->has_max, kV8MaxWasmTableSize, &table->max_size); |
| 393 &table->max_size); | |
| 394 } | 394 } |
| 395 section_iter.advance(); | 395 section_iter.advance(); |
| 396 } | 396 } |
| 397 | 397 |
| 398 // ===== Memory section ================================================== | 398 // ===== Memory section ================================================== |
| 399 if (section_iter.section_code() == kMemorySectionCode) { | 399 if (section_iter.section_code() == kMemorySectionCode) { |
| 400 const byte* pos = pc_; | 400 const byte* pos = pc_; |
| 401 uint32_t memory_count = consume_u32v("memory count"); | 401 uint32_t memory_count = consume_u32v("memory count"); |
| 402 // Require at most one memory for now. | 402 // Require at most one memory for now. |
| 403 if (memory_count > 1) { | 403 if (memory_count > 1) { |
| 404 error(pos, pos, "invalid memory count %d, maximum 1", memory_count); | 404 error(pos, pos, "invalid memory count %d, maximum 1", memory_count); |
| 405 } | 405 } |
| 406 | 406 |
| 407 for (uint32_t i = 0; ok() && i < memory_count; i++) { | 407 for (uint32_t i = 0; ok() && i < memory_count; i++) { |
| 408 bool has_max = false; | 408 bool has_max = false; |
| 409 consume_resizable_limits( | 409 consume_resizable_limits( |
| 410 "memory", "pages", WasmModule::kV8MaxPages, &module->min_mem_pages, | 410 "memory", "pages", kV8MaxWasmMemoryPages, &module->min_mem_pages, |
| 411 &has_max, WasmModule::kSpecMaxPages, &module->max_mem_pages); | 411 &has_max, kSpecMaxWasmMemoryPages, &module->max_mem_pages); |
| 412 } | 412 } |
| 413 module->has_memory = true; | 413 module->has_memory = true; |
| 414 section_iter.advance(); | 414 section_iter.advance(); |
| 415 } | 415 } |
| 416 | 416 |
| 417 // ===== Global section ================================================== | 417 // ===== Global section ================================================== |
| 418 if (section_iter.section_code() == kGlobalSectionCode) { | 418 if (section_iter.section_code() == kGlobalSectionCode) { |
| 419 uint32_t globals_count = consume_u32v("globals count"); | 419 uint32_t globals_count = consume_u32v("globals count"); |
| 420 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); | 420 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); |
| 421 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count, | 421 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count, |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 | 1102 |
| 1103 } // namespace | 1103 } // namespace |
| 1104 | 1104 |
| 1105 ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, | 1105 ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, |
| 1106 const byte* module_end, bool verify_functions, | 1106 const byte* module_end, bool verify_functions, |
| 1107 ModuleOrigin origin) { | 1107 ModuleOrigin origin) { |
| 1108 HistogramTimerScope wasm_decode_module_time_scope( | 1108 HistogramTimerScope wasm_decode_module_time_scope( |
| 1109 isolate->counters()->wasm_decode_module_time()); | 1109 isolate->counters()->wasm_decode_module_time()); |
| 1110 size_t size = module_end - module_start; | 1110 size_t size = module_end - module_start; |
| 1111 if (module_start > module_end) return ModuleError("start > end"); | 1111 if (module_start > module_end) return ModuleError("start > end"); |
| 1112 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size"); | 1112 if (size >= kV8MaxWasmModuleSize) |
| 1113 return ModuleError("size > maximum module size"); |
| 1113 // TODO(bradnelson): Improve histogram handling of size_t. | 1114 // TODO(bradnelson): Improve histogram handling of size_t. |
| 1114 isolate->counters()->wasm_module_size_bytes()->AddSample( | 1115 isolate->counters()->wasm_module_size_bytes()->AddSample( |
| 1115 static_cast<int>(size)); | 1116 static_cast<int>(size)); |
| 1116 // Signatures are stored in zone memory, which have the same lifetime | 1117 // Signatures are stored in zone memory, which have the same lifetime |
| 1117 // as the {module}. | 1118 // as the {module}. |
| 1118 Zone* zone = new Zone(isolate->allocator(), ZONE_NAME); | 1119 Zone* zone = new Zone(isolate->allocator(), ZONE_NAME); |
| 1119 ModuleDecoder decoder(zone, module_start, module_end, origin); | 1120 ModuleDecoder decoder(zone, module_start, module_end, origin); |
| 1120 ModuleResult result = decoder.DecodeModule(verify_functions); | 1121 ModuleResult result = decoder.DecodeModule(verify_functions); |
| 1121 // TODO(bradnelson): Improve histogram handling of size_t. | 1122 // TODO(bradnelson): Improve histogram handling of size_t. |
| 1122 // TODO(titzer): this isn't accurate, since it doesn't count the data | 1123 // TODO(titzer): this isn't accurate, since it doesn't count the data |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1141 } | 1142 } |
| 1142 | 1143 |
| 1143 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, | 1144 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, |
| 1144 ModuleBytesEnv* module_env, | 1145 ModuleBytesEnv* module_env, |
| 1145 const byte* function_start, | 1146 const byte* function_start, |
| 1146 const byte* function_end) { | 1147 const byte* function_end) { |
| 1147 HistogramTimerScope wasm_decode_function_time_scope( | 1148 HistogramTimerScope wasm_decode_function_time_scope( |
| 1148 isolate->counters()->wasm_decode_function_time()); | 1149 isolate->counters()->wasm_decode_function_time()); |
| 1149 size_t size = function_end - function_start; | 1150 size_t size = function_end - function_start; |
| 1150 if (function_start > function_end) return FunctionError("start > end"); | 1151 if (function_start > function_end) return FunctionError("start > end"); |
| 1151 if (size > kMaxFunctionSize) | 1152 if (size > kV8MaxWasmFunctionSize) |
| 1152 return FunctionError("size > maximum function size"); | 1153 return FunctionError("size > maximum function size"); |
| 1153 isolate->counters()->wasm_function_size_bytes()->AddSample( | 1154 isolate->counters()->wasm_function_size_bytes()->AddSample( |
| 1154 static_cast<int>(size)); | 1155 static_cast<int>(size)); |
| 1155 WasmFunction* function = new WasmFunction(); | 1156 WasmFunction* function = new WasmFunction(); |
| 1156 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 1157 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
| 1157 return decoder.DecodeSingleFunction(module_env, function); | 1158 return decoder.DecodeSingleFunction(module_env, function); |
| 1158 } | 1159 } |
| 1159 | 1160 |
| 1160 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, | 1161 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, |
| 1161 const byte* module_end) { | 1162 const byte* module_end) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 table.push_back(std::move(func_asm_offsets)); | 1227 table.push_back(std::move(func_asm_offsets)); |
| 1227 } | 1228 } |
| 1228 if (decoder.more()) decoder.error("unexpected additional bytes"); | 1229 if (decoder.more()) decoder.error("unexpected additional bytes"); |
| 1229 | 1230 |
| 1230 return decoder.toResult(std::move(table)); | 1231 return decoder.toResult(std::move(table)); |
| 1231 } | 1232 } |
| 1232 | 1233 |
| 1233 } // namespace wasm | 1234 } // namespace wasm |
| 1234 } // namespace internal | 1235 } // namespace internal |
| 1235 } // namespace v8 | 1236 } // namespace v8 |
| OLD | NEW |