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 <memory> | 5 #include <memory> |
6 | 6 |
7 #include "src/base/atomic-utils.h" | 7 #include "src/base/atomic-utils.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 | 9 |
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/property-descriptor.h" | 12 #include "src/property-descriptor.h" |
13 #include "src/simulator.h" | 13 #include "src/simulator.h" |
14 #include "src/snapshot/snapshot.h" | 14 #include "src/snapshot/snapshot.h" |
15 #include "src/v8.h" | 15 #include "src/v8.h" |
16 | 16 |
17 #include "src/wasm/ast-decoder.h" | 17 #include "src/wasm/ast-decoder.h" |
18 #include "src/wasm/module-decoder.h" | 18 #include "src/wasm/module-decoder.h" |
19 #include "src/wasm/wasm-debug.h" | 19 #include "src/wasm/wasm-debug.h" |
20 #include "src/wasm/wasm-function-name-table.h" | 20 #include "src/wasm/wasm-function-name-table.h" |
21 #include "src/wasm/wasm-interpreter.h" | |
21 #include "src/wasm/wasm-module.h" | 22 #include "src/wasm/wasm-module.h" |
22 #include "src/wasm/wasm-result.h" | 23 #include "src/wasm/wasm-result.h" |
23 | 24 |
24 #include "src/compiler/wasm-compiler.h" | 25 #include "src/compiler/wasm-compiler.h" |
25 | 26 |
26 namespace v8 { | 27 namespace v8 { |
27 namespace internal { | 28 namespace internal { |
28 namespace wasm { | 29 namespace wasm { |
29 | 30 |
30 enum JSFunctionExportInternalField { | 31 enum JSFunctionExportInternalField { |
(...skipping 1637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1668 MaybeHandle<FixedArray> compiled_module = | 1669 MaybeHandle<FixedArray> compiled_module = |
1669 decoded_module->CompileFunctions(isolate, thrower); | 1670 decoded_module->CompileFunctions(isolate, thrower); |
1670 if (compiled_module.is_null()) return nothing; | 1671 if (compiled_module.is_null()) return nothing; |
1671 | 1672 |
1672 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(), | 1673 return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(), |
1673 origin); | 1674 origin); |
1674 } | 1675 } |
1675 | 1676 |
1676 namespace testing { | 1677 namespace testing { |
1677 | 1678 |
1678 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, | 1679 const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, Zone* zone, |
1679 const byte* module_end, bool asm_js) { | 1680 ErrorThrower& thrower, |
1680 HandleScope scope(isolate); | 1681 const byte* module_start, |
1681 Zone zone(isolate->allocator()); | 1682 const byte* module_end, |
1682 ErrorThrower thrower(isolate, "CompileAndRunWasmModule"); | 1683 ModuleOrigin origin) { |
1683 | |
1684 // Decode the module, but don't verify function bodies, since we'll | 1684 // Decode the module, but don't verify function bodies, since we'll |
1685 // be compiling them anyway. | 1685 // be compiling them anyway. |
1686 ModuleResult decoding_result = | 1686 ModuleResult decoding_result = |
1687 DecodeWasmModule(isolate, &zone, module_start, module_end, false, | 1687 DecodeWasmModule(isolate, zone, module_start, module_end, false, origin); |
1688 asm_js ? kAsmJsOrigin : kWasmOrigin); | |
1689 | 1688 |
1690 std::unique_ptr<const WasmModule> module(decoding_result.val); | 1689 std::unique_ptr<const WasmModule> module(decoding_result.val); |
1691 if (decoding_result.failed()) { | 1690 if (decoding_result.failed()) { |
1692 // Module verification failed. throw. | 1691 // Module verification failed. throw. |
1693 thrower.Error("WASM.compileRun() failed: %s", | 1692 thrower.Error("WASM.compileRun() failed: %s", |
1694 decoding_result.error_msg.get()); | 1693 decoding_result.error_msg.get()); |
1695 return -1; | 1694 return nullptr; |
1696 } | 1695 } |
1697 | 1696 |
1697 if (thrower.error()) return nullptr; | |
1698 return module.release(); | |
1699 } | |
1700 | |
1701 const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate, | |
1702 ErrorThrower& thrower, | |
1703 const WasmModule* module) { | |
1704 CHECK(module != nullptr); | |
1705 | |
1698 if (module->import_table.size() > 0) { | 1706 if (module->import_table.size() > 0) { |
1699 thrower.Error("Not supported: module has imports."); | 1707 thrower.Error("Not supported: module has imports."); |
1700 } | 1708 } |
1701 if (module->export_table.size() == 0) { | 1709 if (module->export_table.size() == 0) { |
1702 thrower.Error("Not supported: module has no exports."); | 1710 thrower.Error("Not supported: module has no exports."); |
1703 } | 1711 } |
1704 | 1712 |
1713 if (thrower.error()) return Handle<JSObject>::null(); | |
1714 | |
1715 MaybeHandle<FixedArray> compiled_module = | |
1716 module->CompileFunctions(isolate, &thrower); | |
1717 | |
1718 if (compiled_module.is_null()) return Handle<JSObject>::null(); | |
1719 return WasmModule::Instantiate(isolate, compiled_module.ToHandleChecked(), | |
1720 Handle<JSReceiver>::null(), | |
1721 Handle<JSArrayBuffer>::null()) | |
1722 .ToHandleChecked(); | |
1723 } | |
1724 | |
1725 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, | |
titzer
2016/09/09 08:58:59
I'm wondering if it's time to move this into the t
ahaas
2016/09/09 11:57:36
I created new files for this testing code in test/
| |
1726 const byte* module_end, bool asm_js) { | |
1727 HandleScope scope(isolate); | |
1728 Zone zone(isolate->allocator()); | |
1729 | |
1730 ErrorThrower thrower(isolate, "CompileAndRunWasmModule"); | |
1731 std::unique_ptr<const WasmModule> module(DecodeWasmModuleForTesting( | |
1732 isolate, &zone, thrower, module_start, module_end, | |
1733 asm_js ? kAsmJsOrigin : kWasmOrigin)); | |
1734 | |
1735 if (module == nullptr) { | |
1736 return -1; | |
1737 } | |
1738 Handle<JSObject> instance = | |
1739 InstantiateModuleForTesting(isolate, thrower, module.get()); | |
1740 if (instance.is_null()) { | |
1741 return -1; | |
1742 } | |
1743 return CallWasmFunctionForTesting(isolate, instance, thrower, | |
1744 asm_js ? "caller" : "main", 0, nullptr, | |
1745 asm_js); | |
1746 } | |
1747 | |
1748 int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower& thrower, | |
1749 const WasmModule* module, int function_index, | |
1750 WasmVal* args) { | |
1751 CHECK(module != nullptr); | |
1752 | |
1753 Zone zone(isolate->allocator()); | |
1754 v8::internal::HandleScope scope(isolate); | |
1755 | |
1756 if (module->import_table.size() > 0) { | |
1757 thrower.Error("Not supported: module has imports."); | |
1758 } | |
1759 if (module->export_table.size() == 0) { | |
1760 thrower.Error("Not supported: module has no exports."); | |
1761 } | |
1762 | |
1705 if (thrower.error()) return -1; | 1763 if (thrower.error()) return -1; |
1706 MaybeHandle<FixedArray> compiled_module = | |
1707 module->CompileFunctions(isolate, &thrower); | |
1708 | 1764 |
1709 if (compiled_module.is_null()) return -1; | 1765 WasmModuleInstance instance(module); |
1710 Handle<JSObject> instance = | 1766 instance.context = isolate->native_context(); |
1711 WasmModule::Instantiate(isolate, compiled_module.ToHandleChecked(), | 1767 instance.mem_size = GetMinModuleMemSize(module); |
1712 Handle<JSReceiver>::null(), | 1768 instance.mem_start = nullptr; |
1713 Handle<JSArrayBuffer>::null()) | 1769 instance.globals_start = nullptr; |
1714 .ToHandleChecked(); | |
1715 | 1770 |
1716 return CallFunction(isolate, instance, &thrower, asm_js ? "caller" : "main", | 1771 ModuleEnv module_env; |
1717 0, nullptr, asm_js); | 1772 module_env.module = module; |
1773 module_env.instance = &instance; | |
1774 module_env.origin = module->origin; | |
1775 | |
1776 const WasmFunction* function = &(module->functions[function_index]); | |
1777 | |
1778 FunctionBody body = {&module_env, function->sig, module->module_start, | |
1779 module->module_start + function->code_start_offset, | |
1780 module->module_start + function->code_end_offset}; | |
1781 DecodeResult result = VerifyWasmCode(isolate->allocator(), body); | |
1782 if (result.failed()) { | |
1783 thrower.Error("Function did not verify"); | |
1784 return -1; | |
1785 } | |
1786 | |
1787 WasmInterpreter interpreter(&instance, isolate->allocator()); | |
1788 | |
1789 WasmInterpreter::Thread* thread = interpreter.GetThread(0); | |
1790 thread->Reset(); | |
1791 thread->PushFrame(function, args); | |
1792 if (thread->Run() == WasmInterpreter::FINISHED) { | |
1793 WasmVal val = thread->GetReturnValue(); | |
1794 return val.to<int32_t>(); | |
1795 } else if (thread->state() == WasmInterpreter::TRAPPED) { | |
1796 return 0xdeadbeef; | |
1797 } else { | |
1798 thrower.Error("Interpreter did not finish execution within its step bound"); | |
1799 return -1; | |
1800 } | |
1718 } | 1801 } |
1719 | 1802 |
1720 int32_t CallFunction(Isolate* isolate, Handle<JSObject> instance, | 1803 int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance, |
1721 ErrorThrower* thrower, const char* name, int argc, | 1804 ErrorThrower& thrower, const char* name, |
1722 Handle<Object> argv[], bool asm_js) { | 1805 int argc, Handle<Object> argv[], |
1806 bool asm_js) { | |
1723 Handle<JSObject> exports_object; | 1807 Handle<JSObject> exports_object; |
1724 if (asm_js) { | 1808 if (asm_js) { |
1725 exports_object = instance; | 1809 exports_object = instance; |
1726 } else { | 1810 } else { |
1727 Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports"); | 1811 Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports"); |
1728 exports_object = Handle<JSObject>::cast( | 1812 exports_object = Handle<JSObject>::cast( |
1729 JSObject::GetProperty(instance, exports).ToHandleChecked()); | 1813 JSObject::GetProperty(instance, exports).ToHandleChecked()); |
1730 } | 1814 } |
1731 Handle<Name> main_name = isolate->factory()->NewStringFromAsciiChecked(name); | 1815 Handle<Name> main_name = isolate->factory()->NewStringFromAsciiChecked(name); |
1732 PropertyDescriptor desc; | 1816 PropertyDescriptor desc; |
1733 Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor( | 1817 Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor( |
1734 isolate, exports_object, main_name, &desc); | 1818 isolate, exports_object, main_name, &desc); |
1735 if (!property_found.FromMaybe(false)) return -1; | 1819 if (!property_found.FromMaybe(false)) return -1; |
1736 | 1820 |
1737 Handle<JSFunction> main_export = Handle<JSFunction>::cast(desc.value()); | 1821 Handle<JSFunction> main_export = Handle<JSFunction>::cast(desc.value()); |
1738 | 1822 |
1739 // Call the JS function. | 1823 // Call the JS function. |
1740 Handle<Object> undefined = isolate->factory()->undefined_value(); | 1824 Handle<Object> undefined = isolate->factory()->undefined_value(); |
1741 MaybeHandle<Object> retval = | 1825 MaybeHandle<Object> retval = |
1742 Execution::Call(isolate, main_export, undefined, argc, argv); | 1826 Execution::Call(isolate, main_export, undefined, argc, argv); |
1743 | 1827 |
1744 // The result should be a number. | 1828 // The result should be a number. |
1745 if (retval.is_null()) { | 1829 if (retval.is_null()) { |
1746 thrower->Error("WASM.compileRun() failed: Invocation was null"); | 1830 thrower.Error("WASM.compileRun() failed: Invocation was null"); |
1747 return -1; | 1831 return -1; |
1748 } | 1832 } |
1749 Handle<Object> result = retval.ToHandleChecked(); | 1833 Handle<Object> result = retval.ToHandleChecked(); |
1750 if (result->IsSmi()) { | 1834 if (result->IsSmi()) { |
1751 return Smi::cast(*result)->value(); | 1835 return Smi::cast(*result)->value(); |
1752 } | 1836 } |
1753 if (result->IsHeapNumber()) { | 1837 if (result->IsHeapNumber()) { |
1754 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 1838 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
1755 } | 1839 } |
1756 thrower->Error("WASM.compileRun() failed: Return value should be number"); | 1840 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
1757 return -1; | 1841 return -1; |
1758 } | 1842 } |
1759 | 1843 |
1760 } // namespace testing | 1844 } // namespace testing |
1761 } // namespace wasm | 1845 } // namespace wasm |
1762 } // namespace internal | 1846 } // namespace internal |
1763 } // namespace v8 | 1847 } // namespace v8 |
OLD | NEW |