Commit 72c3732f authored by titzer's avatar titzer Committed by Commit bot

[wasm] Use more precise types for some WASM objects.

R=clemensh@chromium.org,mtrofin@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2510673002
Cr-Commit-Position: refs/heads/master@{#41043}
parent 124e77f0
......@@ -736,15 +736,18 @@ RUNTIME_FUNCTION(Runtime_SpeciesProtector) {
return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact());
}
#define CONVERT_ARG_HANDLE_CHECKED_2(Type, name, index) \
CHECK(Type::Is##Type(args[index])); \
Handle<Type> name = args.at<Type>(index);
// Take a compiled wasm module, serialize it and copy the buffer into an array
// buffer, which is then returned.
RUNTIME_FUNCTION(Runtime_SerializeWasmModule) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0);
CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0);
Handle<FixedArray> orig =
handle(FixedArray::cast(module_obj->GetInternalField(0)));
Handle<WasmCompiledModule> orig = handle(module_obj->get_compiled_module());
std::unique_ptr<ScriptData> data =
WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig);
void* buff = isolate->array_buffer_allocator()->Allocate(data->length());
......@@ -794,7 +797,7 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
HandleScope shs(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0);
CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Smi, instance_count, 1);
wasm::testing::ValidateInstancesChain(isolate, module_obj,
instance_count->value());
......@@ -804,7 +807,7 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0);
CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0);
wasm::testing::ValidateModuleState(isolate, module_obj);
return isolate->heap()->ToBoolean(true);
}
......@@ -812,8 +815,8 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) {
RUNTIME_FUNCTION(Runtime_ValidateWasmOrphanedInstance) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0);
wasm::testing::ValidateOrphanedInstance(isolate, instance_obj);
CONVERT_ARG_HANDLE_CHECKED_2(WasmInstanceObject, instance, 0);
wasm::testing::ValidateOrphanedInstance(isolate, instance);
return isolate->heap()->ToBoolean(true);
}
......
......@@ -14,6 +14,7 @@
#include "src/objects-inl.h"
#include "src/v8memory.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"
namespace v8 {
namespace internal {
......@@ -22,7 +23,7 @@ RUNTIME_FUNCTION(Runtime_WasmMemorySize) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
Handle<JSObject> module_instance;
Handle<WasmInstanceObject> instance;
{
// Get the module JSObject
DisallowHeapAllocation no_allocation;
......@@ -31,19 +32,19 @@ RUNTIME_FUNCTION(Runtime_WasmMemorySize) {
Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset);
Code* code =
isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
Object* owning_instance = wasm::GetOwningWasmInstance(code);
WasmInstanceObject* owning_instance = wasm::GetOwningWasmInstance(code);
CHECK_NOT_NULL(owning_instance);
module_instance = handle(JSObject::cast(owning_instance), isolate);
instance = handle(owning_instance, isolate);
}
return *isolate->factory()->NewNumberFromInt(
wasm::GetInstanceMemorySize(isolate, module_instance));
wasm::GetInstanceMemorySize(isolate, instance));
}
RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_UINT32_ARG_CHECKED(delta_pages, 0);
Handle<JSObject> module_instance;
Handle<WasmInstanceObject> instance;
{
// Get the module JSObject
DisallowHeapAllocation no_allocation;
......@@ -52,12 +53,12 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset);
Code* code =
isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
Object* owning_instance = wasm::GetOwningWasmInstance(code);
WasmInstanceObject* owning_instance = wasm::GetOwningWasmInstance(code);
CHECK_NOT_NULL(owning_instance);
module_instance = handle(JSObject::cast(owning_instance), isolate);
instance = handle(owning_instance, isolate);
}
return *isolate->factory()->NewNumberFromInt(
wasm::GrowInstanceMemory(isolate, module_instance, delta_pages));
wasm::GrowInstanceMemory(isolate, instance, delta_pages));
}
RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) {
......
......@@ -535,8 +535,8 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
i::Handle<i::Object> instance_object(
receiver->GetInternalField(kWasmMemoryInstanceObject), i_isolate);
i::Handle<i::JSObject> instance(
i::Handle<i::JSObject>::cast(instance_object));
i::Handle<i::WasmInstanceObject> instance(
i::Handle<i::WasmInstanceObject>::cast(instance_object));
// TODO(gdeepti) Implement growing memory when shared by different
// instances.
......
......@@ -666,7 +666,7 @@ std::ostream& wasm::operator<<(std::ostream& os, const WasmFunctionName& pair) {
return os;
}
Object* wasm::GetOwningWasmInstance(Code* code) {
WasmInstanceObject* wasm::GetOwningWasmInstance(Code* code) {
DCHECK(code->kind() == Code::WASM_FUNCTION);
DisallowHeapAllocation no_gc;
FixedArray* deopt_data = code->deoptimization_data();
......@@ -675,7 +675,8 @@ Object* wasm::GetOwningWasmInstance(Code* code) {
Object* weak_link = deopt_data->get(0);
if (!weak_link->IsWeakCell()) return nullptr;
WeakCell* cell = WeakCell::cast(weak_link);
return cell->value();
if (!cell->value()) return nullptr;
return WasmInstanceObject::cast(cell->value());
}
int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
......@@ -958,8 +959,8 @@ class WasmInstanceBuilder {
memory_(memory) {}
// Build an instance, in all of its glory.
MaybeHandle<JSObject> Build() {
MaybeHandle<JSObject> nothing;
MaybeHandle<WasmInstanceObject> Build() {
MaybeHandle<WasmInstanceObject> nothing;
HistogramTimerScope wasm_instantiate_module_time_scope(
isolate_->counters()->wasm_instantiate_module_time());
Factory* factory = isolate_->factory();
......@@ -1835,11 +1836,9 @@ class WasmInstanceBuilder {
// Instantiates a WASM module, creating a WebAssembly.Instance from a
// WebAssembly.Module.
MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
ErrorThrower* thrower,
Handle<JSObject> wasm_module,
Handle<JSReceiver> ffi,
Handle<JSArrayBuffer> memory) {
MaybeHandle<WasmInstanceObject> WasmModule::Instantiate(
Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module,
Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) {
WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
return builder.Build();
}
......@@ -2002,24 +2001,23 @@ bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
return result.ok();
}
MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(Isolate* isolate,
Handle<JSObject> object) {
auto instance = Handle<WasmInstanceObject>::cast(object);
MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
Isolate* isolate, Handle<WasmInstanceObject> instance) {
if (instance->has_memory_buffer()) {
return Handle<JSArrayBuffer>(instance->get_memory_buffer(), isolate);
}
return MaybeHandle<JSArrayBuffer>();
}
void SetInstanceMemory(Handle<JSObject> object, JSArrayBuffer* buffer) {
void SetInstanceMemory(Handle<WasmInstanceObject> instance,
JSArrayBuffer* buffer) {
DisallowHeapAllocation no_gc;
auto instance = Handle<WasmInstanceObject>::cast(object);
instance->set_memory_buffer(buffer);
instance->get_compiled_module()->set_ptr_to_memory(buffer);
}
int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
Handle<JSObject> instance) {
Handle<WasmInstanceObject> instance) {
MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
GetInstanceMemory(isolate, instance);
Handle<JSArrayBuffer> buffer;
......@@ -2047,10 +2045,9 @@ uint32_t GetMaxInstanceMemorySize(Isolate* isolate,
return WasmModule::kV8MaxPages;
}
int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> object,
int32_t wasm::GrowInstanceMemory(Isolate* isolate,
Handle<WasmInstanceObject> instance,
uint32_t pages) {
if (!IsWasmInstance(*object)) return -1;
auto instance = Handle<WasmInstanceObject>::cast(object);
if (pages == 0) return GetInstanceMemorySize(isolate, instance);
uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
......@@ -2100,22 +2097,20 @@ int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> object,
}
void testing::ValidateInstancesChain(Isolate* isolate,
Handle<JSObject> wasm_module,
Handle<WasmModuleObject> module_obj,
int instance_count) {
CHECK_GE(instance_count, 0);
DisallowHeapAllocation no_gc;
WasmCompiledModule* compiled_module =
WasmCompiledModule::cast(wasm_module->GetInternalField(0));
WasmCompiledModule* compiled_module = module_obj->get_compiled_module();
CHECK_EQ(JSObject::cast(compiled_module->ptr_to_weak_wasm_module()->value()),
*wasm_module);
*module_obj);
Object* prev = nullptr;
int found_instances = compiled_module->has_weak_owning_instance() ? 1 : 0;
WasmCompiledModule* current_instance = compiled_module;
while (current_instance->has_weak_next_instance()) {
CHECK((prev == nullptr && !current_instance->has_weak_prev_instance()) ||
current_instance->ptr_to_weak_prev_instance()->value() == prev);
CHECK_EQ(current_instance->ptr_to_weak_wasm_module()->value(),
*wasm_module);
CHECK_EQ(current_instance->ptr_to_weak_wasm_module()->value(), *module_obj);
CHECK(IsWasmInstance(
current_instance->ptr_to_weak_owning_instance()->value()));
prev = current_instance;
......@@ -2128,21 +2123,19 @@ void testing::ValidateInstancesChain(Isolate* isolate,
}
void testing::ValidateModuleState(Isolate* isolate,
Handle<JSObject> wasm_module) {
Handle<WasmModuleObject> module_obj) {
DisallowHeapAllocation no_gc;
WasmCompiledModule* compiled_module =
WasmCompiledModule::cast(wasm_module->GetInternalField(0));
WasmCompiledModule* compiled_module = module_obj->get_compiled_module();
CHECK(compiled_module->has_weak_wasm_module());
CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *wasm_module);
CHECK_EQ(compiled_module->ptr_to_weak_wasm_module()->value(), *module_obj);
CHECK(!compiled_module->has_weak_prev_instance());
CHECK(!compiled_module->has_weak_next_instance());
CHECK(!compiled_module->has_weak_owning_instance());
}
void testing::ValidateOrphanedInstance(Isolate* isolate,
Handle<JSObject> object) {
Handle<WasmInstanceObject> instance) {
DisallowHeapAllocation no_gc;
WasmInstanceObject* instance = WasmInstanceObject::cast(*object);
WasmCompiledModule* compiled_module = instance->get_compiled_module();
CHECK(compiled_module->has_weak_wasm_module());
CHECK(compiled_module->ptr_to_weak_wasm_module()->cleared());
......
......@@ -22,6 +22,7 @@ namespace internal {
class WasmCompiledModule;
class WasmDebugInfo;
class WasmModuleObject;
class WasmInstanceObject;
namespace compiler {
class CallDescriptor;
......@@ -255,11 +256,9 @@ struct V8_EXPORT_PRIVATE WasmModule {
}
// Creates a new instantiation of the module in the given isolate.
static MaybeHandle<JSObject> Instantiate(Isolate* isolate,
ErrorThrower* thrower,
Handle<JSObject> wasm_module,
Handle<JSReceiver> ffi,
Handle<JSArrayBuffer> memory);
static MaybeHandle<WasmInstanceObject> Instantiate(
Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module,
Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory);
MaybeHandle<WasmCompiledModule> CompileFunctions(
Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper,
......@@ -370,13 +369,6 @@ Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm);
// Return the number of functions in the given wasm object.
int GetNumberOfFunctions(Handle<JSObject> wasm);
// Create and export JSFunction
Handle<JSFunction> WrapExportCodeAsJSFunction(Isolate* isolate,
Handle<Code> export_code,
Handle<String> name,
FunctionSig* sig, int func_index,
Handle<JSObject> instance);
// Check whether the given object represents a WebAssembly.Instance instance.
// This checks the number and type of internal fields, so it's not 100 percent
// secure. If it turns out that we need more complete checks, we could add a
......@@ -422,25 +414,28 @@ bool GetPositionInfo(Handle<WasmCompiledModule> compiled_module,
// Assumed to be called with a code object associated to a wasm module instance.
// Intended to be called from runtime functions.
// Returns nullptr on failing to get owning instance.
Object* GetOwningWasmInstance(Code* code);
WasmInstanceObject* GetOwningWasmInstance(Code* code);
MaybeHandle<JSArrayBuffer> GetInstanceMemory(Isolate* isolate,
Handle<JSObject> instance);
MaybeHandle<JSArrayBuffer> GetInstanceMemory(
Isolate* isolate, Handle<WasmInstanceObject> instance);
int32_t GetInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance);
int32_t GetInstanceMemorySize(Isolate* isolate,
Handle<WasmInstanceObject> instance);
int32_t GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance,
uint32_t pages);
int32_t GrowInstanceMemory(Isolate* isolate,
Handle<WasmInstanceObject> instance, uint32_t pages);
void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables,
int index, Handle<JSFunction> js_function);
namespace testing {
void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> wasm_module,
void ValidateInstancesChain(Isolate* isolate,
Handle<WasmModuleObject> module_obj,
int instance_count);
void ValidateModuleState(Isolate* isolate, Handle<JSObject> wasm_module);
void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance);
void ValidateModuleState(Isolate* isolate, Handle<WasmModuleObject> module_obj);
void ValidateOrphanedInstance(Isolate* isolate,
Handle<WasmInstanceObject> instance);
} // namespace testing
} // namespace wasm
......
......@@ -97,6 +97,14 @@ WasmModuleObject* WasmModuleObject::cast(Object* object) {
return reinterpret_cast<WasmModuleObject*>(object);
}
bool WasmModuleObject::IsWasmModuleObject(Object* object) {
return object->IsJSObject() &&
JSObject::cast(object)->GetInternalFieldCount() == kFieldCount;
}
DEFINE_GETTER(WasmModuleObject, compiled_module, kCompiledModule,
WasmCompiledModule)
Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial,
uint32_t maximum,
Handle<FixedArray>* js_functions) {
......
......@@ -39,7 +39,7 @@ class WasmModuleObject : public JSObject {
DECLARE_CASTS(WasmModuleObject);
WasmCompiledModule* compiled_module();
WasmCompiledModule* get_compiled_module();
wasm::WasmModule* module();
int num_functions();
bool is_asm_js();
......
......@@ -536,7 +536,7 @@ TEST(TestInterruptLoop) {
HandleScope scope(isolate);
testing::SetupIsolateForWasmModule(isolate);
ErrorThrower thrower(isolate, "Test");
const Handle<JSObject> instance =
const Handle<WasmInstanceObject> instance =
testing::CompileInstantiateWasmModuleForTesting(
isolate, &thrower, buffer.begin(), buffer.end(),
ModuleOrigin::kWasmOrigin);
......
......@@ -45,16 +45,15 @@ const WasmModule* DecodeWasmModuleForTesting(
return decoding_result.val;
}
const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
ErrorThrower* thrower,
const WasmModule* module) {
const Handle<WasmInstanceObject> InstantiateModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const WasmModule* module) {
CHECK(module != nullptr);
if (module->import_table.size() > 0) {
thrower->CompileError("Not supported: module has imports.");
}
if (thrower->error()) return Handle<JSObject>::null();
if (thrower->error()) return Handle<WasmInstanceObject>::null();
// Although we decoded the module for some pre-validation, run the bytes
// again through the normal pipeline.
......@@ -64,19 +63,19 @@ const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
ModuleOrigin::kWasmOrigin, Handle<Script>::null(), nullptr, nullptr);
if (module_object.is_null()) {
thrower->CompileError("Module pre-validation failed.");
return Handle<JSObject>::null();
return Handle<WasmInstanceObject>::null();
}
MaybeHandle<JSObject> maybe_instance = WasmModule::Instantiate(
MaybeHandle<WasmInstanceObject> maybe_instance = WasmModule::Instantiate(
isolate, thrower, module_object.ToHandleChecked(),
Handle<JSReceiver>::null(), Handle<JSArrayBuffer>::null());
Handle<JSObject> instance;
Handle<WasmInstanceObject> instance;
if (!maybe_instance.ToHandle(&instance)) {
return Handle<JSObject>::null();
return Handle<WasmInstanceObject>::null();
}
return instance;
}
const Handle<JSObject> CompileInstantiateWasmModuleForTesting(
const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
const byte* module_end, ModuleOrigin origin) {
std::unique_ptr<const WasmModule> module(DecodeWasmModuleForTesting(
......@@ -84,7 +83,7 @@ const Handle<JSObject> CompileInstantiateWasmModuleForTesting(
if (module == nullptr) {
thrower->CompileError("Wasm module decoding failed");
return Handle<JSObject>::null();
return Handle<WasmInstanceObject>::null();
}
return InstantiateModuleForTesting(isolate, thrower, module.get());
}
......
......@@ -10,6 +10,7 @@
#include "src/objects.h"
#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"
#include "src/wasm/wasm-result.h"
#include "src/zone/zone.h"
......@@ -24,9 +25,8 @@ const WasmModule* DecodeWasmModuleForTesting(
const byte* module_end, ModuleOrigin origin, bool verify_functions = false);
// Instantiates a module without any imports and exports.
const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
ErrorThrower* thrower,
const WasmModule* module);
const Handle<WasmInstanceObject> InstantiateModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const WasmModule* module);
int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
ErrorThrower* thrower, const char* name,
......@@ -46,7 +46,7 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
WasmVal* args, bool* may_produced_nan);
// Compiles WasmModule bytes and return an instance of the compiled module.
const Handle<JSObject> CompileInstantiateWasmModuleForTesting(
const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
const byte* module_end, ModuleOrigin origin);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment