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 |