Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(678)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2091533002: [wasm] Consolidate CompileAndRunWasmModule (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/base/atomic-utils.h" 5 #include "src/base/atomic-utils.h"
6 #include "src/macro-assembler.h" 6 #include "src/macro-assembler.h"
7 #include "src/objects.h" 7 #include "src/objects.h"
8 #include "src/property-descriptor.h" 8 #include "src/property-descriptor.h"
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 959
960 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, 960 compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone,
961 uint32_t index) { 961 uint32_t index) {
962 DCHECK(IsValidFunction(index)); 962 DCHECK(IsValidFunction(index));
963 // Always make a direct call to whatever is in the table at that location. 963 // Always make a direct call to whatever is in the table at that location.
964 // A wrapper will be generated for FFI calls. 964 // A wrapper will be generated for FFI calls.
965 const WasmFunction* function = &module->functions[index]; 965 const WasmFunction* function = &module->functions[index];
966 return GetWasmCallDescriptor(zone, function->sig); 966 return GetWasmCallDescriptor(zone, function->sig);
967 } 967 }
968 968
969 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
970 const byte* module_end, bool asm_js) {
971 HandleScope scope(isolate);
972 Zone zone(isolate->allocator());
973 // Decode the module, but don't verify function bodies, since we'll
974 // be compiling them anyway.
975 ModuleResult result =
976 DecodeWasmModule(isolate, &zone, module_start, module_end, false,
977 asm_js ? kAsmJsOrigin : kWasmOrigin);
978 if (result.failed()) {
979 if (result.val) {
980 delete result.val;
981 }
982 // Module verification failed. throw.
983 std::ostringstream str;
984 str << "WASM.compileRun() failed: " << result;
985 isolate->Throw(
986 *isolate->factory()->NewStringFromAsciiChecked(str.str().c_str()));
987 return -1;
988 }
989
990 int32_t retval = CompileAndRunWasmModule(isolate, result.val);
991 delete result.val;
992 return retval;
993 }
994
995 int32_t CompileAndRunWasmModule(Isolate* isolate, const WasmModule* module) {
996 ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
997 WasmModuleInstance instance(module);
998 Handle<FixedArray> code_table = module->CompileFunctions(isolate);
999
1000 if (code_table.is_null()) return -1;
1001
1002 for (uint32_t i = 0; i < module->functions.size(); ++i) {
1003 Handle<Code> code = Handle<Code>(Code::cast(code_table->get(i)));
1004 instance.function_code[i] = code;
1005 }
1006
1007 // Allocate and initialize the linear memory.
1008 if (!AllocateMemory(&thrower, isolate, &instance)) {
1009 return -1;
1010 }
1011 LoadDataSegments(module, instance.mem_start, instance.mem_size);
1012
1013 // Allocate the globals area if necessary.
1014 if (!AllocateGlobals(&thrower, isolate, &instance)) {
1015 return -1;
1016 }
1017
1018 ModuleEnv module_env;
1019 module_env.module = module;
1020 module_env.instance = &instance;
1021 module_env.origin = module->origin;
1022 InitializePlaceholders(isolate->factory(), &module_env.placeholders,
1023 module->functions.size());
1024 if (module->export_table.size() == 0) {
1025 thrower.Error("WASM.compileRun() failed: no exported functions");
1026 return -2;
1027 }
1028
1029 // Compile all functions.
1030 for (const WasmFunction& func : module->functions) {
1031 // Compile the function and install it in the linker.
1032 Handle<Code> code = compiler::WasmCompilationUnit::CompileWasmFunction(
1033 &thrower, isolate, &module_env, &func);
1034 if (!code.is_null()) instance.function_code[func.func_index] = code;
1035 if (thrower.error()) return -1;
1036 }
1037
1038 LinkModuleFunctions(isolate, instance.function_code);
1039
1040 // Wrap the main code so it can be called as a JS function.
1041 uint32_t main_index = module->export_table.back().func_index;
1042 Handle<Code> main_code = instance.function_code[main_index];
1043 Handle<String> name = isolate->factory()->NewStringFromStaticChars("main");
1044 Handle<JSObject> module_object = Handle<JSObject>(0, isolate);
1045 Handle<JSFunction> jsfunc = compiler::CompileJSToWasmWrapper(
1046 isolate, &module_env, name, main_code, module_object, main_index);
1047
1048 // Call the JS function.
1049 Handle<Object> undefined = isolate->factory()->undefined_value();
1050 MaybeHandle<Object> retval =
1051 Execution::Call(isolate, jsfunc, undefined, 0, nullptr);
1052
1053 // The result should be a number.
1054 if (retval.is_null()) {
1055 thrower.Error("WASM.compileRun() failed: Invocation was null");
1056 return -1;
1057 }
1058 Handle<Object> result = retval.ToHandleChecked();
1059 if (result->IsSmi()) {
1060 return Smi::cast(*result)->value();
1061 }
1062 if (result->IsHeapNumber()) {
1063 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1064 }
1065 thrower.Error("WASM.compileRun() failed: Return value should be number");
1066 return -1;
1067 }
1068
1069 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm, 969 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm,
1070 uint32_t func_index) { 970 uint32_t func_index) {
1071 if (!wasm->IsUndefined(isolate)) { 971 if (!wasm->IsUndefined(isolate)) {
1072 Handle<ByteArray> func_names_arr_obj( 972 Handle<ByteArray> func_names_arr_obj(
1073 ByteArray::cast(Handle<JSObject>::cast(wasm)->GetInternalField( 973 ByteArray::cast(Handle<JSObject>::cast(wasm)->GetInternalField(
1074 kWasmFunctionNamesArray)), 974 kWasmFunctionNamesArray)),
1075 isolate); 975 isolate);
1076 // TODO(clemens): Extract this from the module bytes; skip whole function 976 // TODO(clemens): Extract this from the module bytes; skip whole function
1077 // name table. 977 // name table.
1078 Handle<Object> name; 978 Handle<Object> name;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 } 1019 }
1120 1020
1121 WasmDebugInfo* GetDebugInfo(JSObject* wasm) { 1021 WasmDebugInfo* GetDebugInfo(JSObject* wasm) {
1122 Object* info = wasm->GetInternalField(kWasmDebugInfo); 1022 Object* info = wasm->GetInternalField(kWasmDebugInfo);
1123 if (!info->IsUndefined(wasm->GetIsolate())) return WasmDebugInfo::cast(info); 1023 if (!info->IsUndefined(wasm->GetIsolate())) return WasmDebugInfo::cast(info);
1124 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(handle(wasm)); 1024 Handle<WasmDebugInfo> new_info = WasmDebugInfo::New(handle(wasm));
1125 wasm->SetInternalField(kWasmDebugInfo, *new_info); 1025 wasm->SetInternalField(kWasmDebugInfo, *new_info);
1126 return *new_info; 1026 return *new_info;
1127 } 1027 }
1128 1028
1029 namespace testing {
1030
1031 int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
1032 const byte* module_end, bool asm_js) {
1033 HandleScope scope(isolate);
1034 Zone zone(isolate->allocator());
1035 ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
1036
1037 // Decode the module, but don't verify function bodies, since we'll
1038 // be compiling them anyway.
1039 ModuleResult decoding_result =
1040 DecodeWasmModule(isolate, &zone, module_start, module_end, false,
1041 asm_js ? kAsmJsOrigin : kWasmOrigin);
1042 if (decoding_result.failed()) {
1043 // Module verification failed. throw.
1044 thrower.Error("WASM.compileRun() failed: %s",
1045 decoding_result.error_msg.get());
ahaas 2016/06/23 13:49:19 Should you not return here?
Mircea Trofin 2016/06/23 15:04:14 Good catch - yes, we should.
1046 }
1047 std::unique_ptr<const WasmModule> module(decoding_result.val);
1048
1049 if (module->import_table.size() > 0) {
1050 thrower.Error("Not supported: module has imports.");
1051 }
1052 if (module->export_table.size() == 0) {
1053 thrower.Error("Not supported: module has no exports.");
1054 }
1055
1056 if (thrower.error()) return -1;
1057
1058 Handle<JSObject> instance =
1059 module
1060 ->Instantiate(isolate, Handle<JSReceiver>::null(),
1061 Handle<JSArrayBuffer>::null())
1062 .ToHandleChecked();
1063
1064 Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports");
1065 Handle<JSObject> exports_object = Handle<JSObject>::cast(
1066 JSObject::GetProperty(instance, exports).ToHandleChecked());
1067 Handle<Name> main_name = isolate->factory()->NewStringFromStaticChars("main");
1068 PropertyDescriptor desc;
1069 Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor(
1070 isolate, exports_object, main_name, &desc);
1071 if (!property_found.FromMaybe(false)) return -1;
1072
1073 Handle<JSFunction> main_export = Handle<JSFunction>::cast(desc.value());
1074
1075 // Call the JS function.
1076 Handle<Object> undefined = isolate->factory()->undefined_value();
1077 MaybeHandle<Object> retval =
1078 Execution::Call(isolate, main_export, undefined, 0, nullptr);
1079
1080 // The result should be a number.
1081 if (retval.is_null()) {
1082 thrower.Error("WASM.compileRun() failed: Invocation was null");
1083 return -1;
1084 }
1085 Handle<Object> result = retval.ToHandleChecked();
1086 if (result->IsSmi()) {
1087 return Smi::cast(*result)->value();
1088 }
1089 if (result->IsHeapNumber()) {
1090 return static_cast<int32_t>(HeapNumber::cast(*result)->value());
1091 }
1092 thrower.Error("WASM.compileRun() failed: Return value should be number");
1093 return -1;
1094 }
1095
1096 } // namespace testing
1129 } // namespace wasm 1097 } // namespace wasm
1130 } // namespace internal 1098 } // namespace internal
1131 } // namespace v8 1099 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-module.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698