| 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/property-descriptor.h" | 7 #include "src/property-descriptor.h" |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/simulator.h" | 10 #include "src/simulator.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 std::ostream& operator<<(std::ostream& os, const WasmModule& module) { | 77 std::ostream& operator<<(std::ostream& os, const WasmModule& module) { |
| 78 os << "WASM module with "; | 78 os << "WASM module with "; |
| 79 os << (module.min_mem_pages * module.kPageSize) << " min mem"; | 79 os << (module.min_mem_pages * module.kPageSize) << " min mem"; |
| 80 os << (module.max_mem_pages * module.kPageSize) << " max mem"; | 80 os << (module.max_mem_pages * module.kPageSize) << " max mem"; |
| 81 os << module.functions.size() << " functions"; | 81 os << module.functions.size() << " functions"; |
| 82 os << module.functions.size() << " globals"; | 82 os << module.functions.size() << " globals"; |
| 83 os << module.functions.size() << " data segments"; | 83 os << module.functions.size() << " data segments"; |
| 84 return os; | 84 return os; |
| 85 } | 85 } |
| 86 | 86 |
| 87 | |
| 88 std::ostream& operator<<(std::ostream& os, const WasmFunction& function) { | 87 std::ostream& operator<<(std::ostream& os, const WasmFunction& function) { |
| 89 os << "WASM function with signature " << *function.sig; | 88 os << "WASM function with signature " << *function.sig; |
| 90 | 89 |
| 91 os << " locals: "; | 90 os << " locals: "; |
| 92 if (function.local_i32_count) os << function.local_i32_count << " i32s "; | 91 if (function.local_i32_count) os << function.local_i32_count << " i32s "; |
| 93 if (function.local_i64_count) os << function.local_i64_count << " i64s "; | 92 if (function.local_i64_count) os << function.local_i64_count << " i64s "; |
| 94 if (function.local_f32_count) os << function.local_f32_count << " f32s "; | 93 if (function.local_f32_count) os << function.local_f32_count << " f32s "; |
| 95 if (function.local_f64_count) os << function.local_f64_count << " f64s "; | 94 if (function.local_f64_count) os << function.local_f64_count << " f64s "; |
| 96 | 95 |
| 97 os << " code bytes: " | 96 os << " code bytes: " |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 if (globals.size() == 0) return 0; | 213 if (globals.size() == 0) return 0; |
| 215 for (WasmGlobal& global : globals) { | 214 for (WasmGlobal& global : globals) { |
| 216 byte size = WasmOpcodes::MemSize(global.type); | 215 byte size = WasmOpcodes::MemSize(global.type); |
| 217 offset = (offset + size - 1) & ~(size - 1); // align | 216 offset = (offset + size - 1) & ~(size - 1); // align |
| 218 global.offset = offset; | 217 global.offset = offset; |
| 219 offset += size; | 218 offset += size; |
| 220 } | 219 } |
| 221 return offset; | 220 return offset; |
| 222 } | 221 } |
| 223 | 222 |
| 224 | |
| 225 void LoadDataSegments(WasmModule* module, byte* mem_addr, size_t mem_size) { | 223 void LoadDataSegments(WasmModule* module, byte* mem_addr, size_t mem_size) { |
| 226 for (const WasmDataSegment& segment : module->data_segments) { | 224 for (const WasmDataSegment& segment : module->data_segments) { |
| 227 if (!segment.init) continue; | 225 if (!segment.init) continue; |
| 228 if (!segment.source_size) continue; | 226 if (!segment.source_size) continue; |
| 229 CHECK_LT(segment.dest_addr, mem_size); | 227 CHECK_LT(segment.dest_addr, mem_size); |
| 230 CHECK_LE(segment.source_size, mem_size); | 228 CHECK_LE(segment.source_size, mem_size); |
| 231 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); | 229 CHECK_LE(segment.dest_addr + segment.source_size, mem_size); |
| 232 byte* addr = mem_addr + segment.dest_addr; | 230 byte* addr = mem_addr + segment.dest_addr; |
| 233 memcpy(addr, module->module_start + segment.source_offset, | 231 memcpy(addr, module->module_start + segment.source_offset, |
| 234 segment.source_size); | 232 segment.source_size); |
| 235 } | 233 } |
| 236 } | 234 } |
| 237 | 235 |
| 238 | |
| 239 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, WasmModule* module) { | 236 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, WasmModule* module) { |
| 240 if (module->function_table.size() == 0) { | 237 if (module->function_table.size() == 0) { |
| 241 return Handle<FixedArray>::null(); | 238 return Handle<FixedArray>::null(); |
| 242 } | 239 } |
| 243 int table_size = static_cast<int>(module->function_table.size()); | 240 int table_size = static_cast<int>(module->function_table.size()); |
| 244 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); | 241 Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); |
| 245 for (int i = 0; i < table_size; i++) { | 242 for (int i = 0; i < table_size; i++) { |
| 246 WasmFunction* function = &module->functions[module->function_table[i]]; | 243 WasmFunction* function = &module->functions[module->function_table[i]]; |
| 247 fixed->set(i, Smi::FromInt(function->sig_index)); | 244 fixed->set(i, Smi::FromInt(function->sig_index)); |
| 248 } | 245 } |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 MaybeHandle<Object> retval = | 670 MaybeHandle<Object> retval = |
| 674 Execution::Call(isolate, jsfunc, undefined, 0, nullptr); | 671 Execution::Call(isolate, jsfunc, undefined, 0, nullptr); |
| 675 | 672 |
| 676 if (retval.is_null()) { | 673 if (retval.is_null()) { |
| 677 thrower.Error("WASM.instantiateModule(): start function failed"); | 674 thrower.Error("WASM.instantiateModule(): start function failed"); |
| 678 } | 675 } |
| 679 } | 676 } |
| 680 return instance.js_object; | 677 return instance.js_object; |
| 681 } | 678 } |
| 682 | 679 |
| 683 | |
| 684 Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) { | 680 Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) { |
| 685 DCHECK(IsValidFunction(index)); | 681 DCHECK(IsValidFunction(index)); |
| 686 if (linker) return linker->GetFunctionCode(index); | 682 if (linker) return linker->GetFunctionCode(index); |
| 687 return instance ? instance->function_code[index] : Handle<Code>::null(); | 683 return instance ? instance->function_code[index] : Handle<Code>::null(); |
| 688 } | 684 } |
| 689 | 685 |
| 690 Handle<Code> ModuleEnv::GetImportCode(uint32_t index) { | 686 Handle<Code> ModuleEnv::GetImportCode(uint32_t index) { |
| 691 DCHECK(IsValidImport(index)); | 687 DCHECK(IsValidImport(index)); |
| 692 return instance ? instance->import_code[index] : Handle<Code>::null(); | 688 return instance ? instance->import_code[index] : Handle<Code>::null(); |
| 693 } | 689 } |
| 694 | 690 |
| 695 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, | 691 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, |
| 696 uint32_t index) { | 692 uint32_t index) { |
| 697 DCHECK(IsValidFunction(index)); | 693 DCHECK(IsValidFunction(index)); |
| 698 // Always make a direct call to whatever is in the table at that location. | 694 // Always make a direct call to whatever is in the table at that location. |
| 699 // A wrapper will be generated for FFI calls. | 695 // A wrapper will be generated for FFI calls. |
| 700 WasmFunction* function = &module->functions[index]; | 696 WasmFunction* function = &module->functions[index]; |
| 701 return GetWasmCallDescriptor(zone, function->sig); | 697 return GetWasmCallDescriptor(zone, function->sig); |
| 702 } | 698 } |
| 703 | 699 |
| 704 | |
| 705 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, | 700 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, |
| 706 const byte* module_end, bool asm_js) { | 701 const byte* module_end, bool asm_js) { |
| 707 HandleScope scope(isolate); | 702 HandleScope scope(isolate); |
| 708 Zone zone(isolate->allocator()); | 703 Zone zone(isolate->allocator()); |
| 709 // Decode the module, but don't verify function bodies, since we'll | 704 // Decode the module, but don't verify function bodies, since we'll |
| 710 // be compiling them anyway. | 705 // be compiling them anyway. |
| 711 ModuleResult result = DecodeWasmModule(isolate, &zone, module_start, | 706 ModuleResult result = DecodeWasmModule(isolate, &zone, module_start, |
| 712 module_end, false, kWasmOrigin); | 707 module_end, false, kWasmOrigin); |
| 713 if (result.failed()) { | 708 if (result.failed()) { |
| 714 if (result.val) { | 709 if (result.val) { |
| 715 delete result.val; | 710 delete result.val; |
| 716 } | 711 } |
| 717 // Module verification failed. throw. | 712 // Module verification failed. throw. |
| 718 std::ostringstream str; | 713 std::ostringstream str; |
| 719 str << "WASM.compileRun() failed: " << result; | 714 str << "WASM.compileRun() failed: " << result; |
| 720 isolate->Throw( | 715 isolate->Throw( |
| 721 *isolate->factory()->NewStringFromAsciiChecked(str.str().c_str())); | 716 *isolate->factory()->NewStringFromAsciiChecked(str.str().c_str())); |
| 722 return -1; | 717 return -1; |
| 723 } | 718 } |
| 724 | 719 |
| 725 int32_t retval = CompileAndRunWasmModule(isolate, result.val); | 720 int32_t retval = CompileAndRunWasmModule(isolate, result.val); |
| 726 delete result.val; | 721 delete result.val; |
| 727 return retval; | 722 return retval; |
| 728 } | 723 } |
| 729 | 724 |
| 730 | |
| 731 int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) { | 725 int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) { |
| 732 ErrorThrower thrower(isolate, "CompileAndRunWasmModule"); | 726 ErrorThrower thrower(isolate, "CompileAndRunWasmModule"); |
| 733 WasmModuleInstance instance(module); | 727 WasmModuleInstance instance(module); |
| 734 | 728 |
| 735 // Allocate and initialize the linear memory. | 729 // Allocate and initialize the linear memory. |
| 736 if (!AllocateMemory(&thrower, isolate, &instance)) { | 730 if (!AllocateMemory(&thrower, isolate, &instance)) { |
| 737 return -1; | 731 return -1; |
| 738 } | 732 } |
| 739 LoadDataSegments(module, instance.mem_start, instance.mem_size); | 733 LoadDataSegments(module, instance.mem_start, instance.mem_size); |
| 740 | 734 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 wasm->GetInternalField(kWasmFunctionNamesArray), wasm->GetIsolate()); | 809 wasm->GetInternalField(kWasmFunctionNamesArray), wasm->GetIsolate()); |
| 816 if (func_names_arr_obj->IsUndefined()) | 810 if (func_names_arr_obj->IsUndefined()) |
| 817 return func_names_arr_obj; // Return undefined. | 811 return func_names_arr_obj; // Return undefined. |
| 818 return GetWasmFunctionNameFromTable( | 812 return GetWasmFunctionNameFromTable( |
| 819 Handle<ByteArray>::cast(func_names_arr_obj), func_index); | 813 Handle<ByteArray>::cast(func_names_arr_obj), func_index); |
| 820 } | 814 } |
| 821 | 815 |
| 822 } // namespace wasm | 816 } // namespace wasm |
| 823 } // namespace internal | 817 } // namespace internal |
| 824 } // namespace v8 | 818 } // namespace v8 |
| OLD | NEW |