[wasm] Remove the use of private symbols for branding.

Instead, rely on the underlying instance types for WebAssembly.* types.

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

Review-Url: https://codereview.chromium.org/2971093003
Cr-Commit-Position: refs/heads/master@{#46478}
This commit is contained in:
titzer 2017-07-07 05:56:24 -07:00 committed by Commit Bot
parent dfdcaf4316
commit 0114863957
4 changed files with 31 additions and 115 deletions

View File

@ -366,13 +366,9 @@ enum ContextLookupFlags {
V(NATIVE_FUNCTION_MAP_INDEX, Map, native_function_map) \
V(WASM_FUNCTION_MAP_INDEX, Map, wasm_function_map) \
V(WASM_INSTANCE_CONSTRUCTOR_INDEX, JSFunction, wasm_instance_constructor) \
V(WASM_INSTANCE_SYM_INDEX, Symbol, wasm_instance_sym) \
V(WASM_MEMORY_CONSTRUCTOR_INDEX, JSFunction, wasm_memory_constructor) \
V(WASM_MEMORY_SYM_INDEX, Symbol, wasm_memory_sym) \
V(WASM_MODULE_CONSTRUCTOR_INDEX, JSFunction, wasm_module_constructor) \
V(WASM_MODULE_SYM_INDEX, Symbol, wasm_module_sym) \
V(WASM_TABLE_CONSTRUCTOR_INDEX, JSFunction, wasm_table_constructor) \
V(WASM_TABLE_SYM_INDEX, Symbol, wasm_table_sym) \
V(TYPED_ARRAY_FUN_INDEX, JSFunction, typed_array_function) \
V(TYPED_ARRAY_PROTOTYPE_INDEX, JSObject, typed_array_prototype) \
V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun) \

View File

@ -1318,7 +1318,7 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table,
break;
}
case kExternalTable: {
if (!WasmJs::IsWasmTableObject(isolate_, value)) {
if (!value->IsWasmTableObject()) {
ReportLinkError("table import requires a WebAssembly.Table", index,
module_name, import_name);
return -1;
@ -1390,13 +1390,12 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table,
// Validation should have failed if more than one memory object was
// provided.
DCHECK(!instance->has_memory_object());
if (!WasmJs::IsWasmMemoryObject(isolate_, value)) {
if (!value->IsWasmMemoryObject()) {
ReportLinkError("memory import must be a WebAssembly.Memory object",
index, module_name, import_name);
return -1;
}
auto memory = Handle<WasmMemoryObject>::cast(value);
DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory));
instance->set_memory_object(*memory);
memory_ = Handle<JSArrayBuffer>(memory->array_buffer(), isolate_);
uint32_t imported_cur_pages = static_cast<uint32_t>(

View File

@ -69,20 +69,6 @@ class ScheduledErrorThrower : public ErrorThrower {
}
};
// TODO(titzer): move brand check to the respective types, and don't throw
// in it, rather, use a provided ErrorThrower, or let caller handle it.
static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
if (!value->IsJSObject()) return false;
i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
return has_brand.FromMaybe(false);
}
static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym,
ErrorThrower* thrower, const char* msg) {
return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false);
}
i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
return isolate->factory()->NewStringFromAsciiChecked(str);
}
@ -92,17 +78,14 @@ Local<String> v8_str(Isolate* isolate, const char* str) {
i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
v8::Isolate* isolate = args.GetIsolate();
if (args.Length() < 1) {
thrower->TypeError("Argument 0 must be a WebAssembly.Module");
return {};
}
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args[0]),
i::handle(i_context->wasm_module_sym()), thrower,
"Argument 0 must be a WebAssembly.Module")) {
i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
if (!arg0->IsWasmModuleObject()) {
thrower->TypeError("Argument 0 must be a WebAssembly.Module");
return {};
}
@ -438,7 +421,6 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
Local<Promise> module_promise = resolver->GetPromise();
@ -466,7 +448,7 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
FunctionCallback instantiator = nullptr;
if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) {
if (first_arg->IsWasmModuleObject()) {
module_promise = resolver->GetPromise();
if (!resolver->Resolve(context, first_arg_value).IsJust()) return;
instantiator = WebAssemblyInstantiateImplCallback;
@ -612,21 +594,29 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(Utils::ToLocal(memory_obj));
}
#define NAME_OF_WasmMemoryObject "WebAssembly.Memory"
#define NAME_OF_WasmModuleObject "WebAssembly.Module"
#define NAME_OF_WasmInstanceObject "WebAssembly.Instance"
#define NAME_OF_WasmTableObject "WebAssembly.Table"
#define EXTRACT_THIS(var, WasmType) \
i::Handle<i::WasmType> var; \
{ \
i::Handle<i::Object> this_arg = Utils::OpenHandle(*args.This()); \
if (!this_arg->Is##WasmType()) { \
thrower.TypeError("Receiver is not a " NAME_OF_##WasmType); \
return; \
} \
var = i::Handle<i::WasmType>::cast(this_arg); \
}
void WebAssemblyTableGetLength(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) {
return;
}
auto receiver =
i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
EXTRACT_THIS(receiver, WasmTableObject);
args.GetReturnValue().Set(
v8::Number::New(isolate, receiver->current_length()));
}
@ -638,15 +628,8 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) {
return;
}
EXTRACT_THIS(receiver, WasmTableObject);
auto receiver =
i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate);
int old_size = old_array->length();
int64_t new_size64 = 0;
@ -691,15 +674,7 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) {
return;
}
auto receiver =
i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
EXTRACT_THIS(receiver, WasmTableObject);
i::Handle<i::FixedArray> array(receiver->functions(), i_isolate);
int i = 0;
if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
@ -720,21 +695,13 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) {
return;
}
EXTRACT_THIS(receiver, WasmTableObject);
if (args.Length() < 2) {
thrower.TypeError("Argument 1 must be null or a function");
return;
}
// {This} parameter.
auto receiver =
i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
// Parameter 0.
int32_t index;
if (!args[0]->Int32Value(context).To(&index)) return;
@ -762,19 +729,13 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
"Receiver is not a WebAssembly.Memory")) {
return;
}
EXTRACT_THIS(receiver, WasmMemoryObject);
int64_t delta_size = 0;
if (args.Length() < 1 || !args[0]->IntegerValue(context).To(&delta_size)) {
thrower.TypeError("Argument 0 required, must be numeric value of pages");
return;
}
i::Handle<i::WasmMemoryObject> receiver =
i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
int64_t max_size64 = receiver->maximum_pages();
if (max_size64 < 0 ||
max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_mem_pages)) {
@ -808,15 +769,8 @@ void WebAssemblyMemoryGetBuffer(
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
"Receiver is not a WebAssembly.Memory")) {
return;
}
i::Handle<i::WasmMemoryObject> receiver =
i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
EXTRACT_THIS(receiver, WasmMemoryObject);
i::Handle<i::Object> buffer(receiver->array_buffer(), i_isolate);
DCHECK(buffer->IsJSArrayBuffer());
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
@ -890,21 +844,7 @@ void WasmJs::Install(Isolate* isolate) {
context->set_wasm_function_map(*map);
// Install symbols.
Factory* factory = isolate->factory();
// Create private symbols.
Handle<Symbol> module_sym = factory->NewPrivateSymbol();
context->set_wasm_module_sym(*module_sym);
Handle<Symbol> instance_sym = factory->NewPrivateSymbol();
context->set_wasm_instance_sym(*instance_sym);
Handle<Symbol> table_sym = factory->NewPrivateSymbol();
context->set_wasm_table_sym(*table_sym);
Handle<Symbol> memory_sym = factory->NewPrivateSymbol();
context->set_wasm_memory_sym(*memory_sym);
// Install the JS API.
@ -1017,15 +957,5 @@ void WasmJs::Install(Isolate* isolate) {
JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(),
runtime_error, attributes);
}
bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) {
i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
return HasBrand(value, symbol);
}
bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
return HasBrand(value, symbol);
}
} // namespace internal
} // namespace v8

View File

@ -162,8 +162,6 @@ Handle<WasmModuleObject> WasmModuleObject::New(
isolate->native_context()->wasm_module_constructor());
auto module_object = Handle<WasmModuleObject>::cast(
isolate->factory()->NewJSObject(module_cons));
Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
Object::SetProperty(module_object, module_sym, module_object, STRICT).Check();
module_object->set_compiled_module(*compiled_module);
Handle<WeakCell> link_to_module =
isolate->factory()->NewWeakCell(module_object);
@ -190,8 +188,6 @@ Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial,
Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0);
table_obj->set_dispatch_tables(*dispatch_tables);
Handle<Symbol> table_sym(isolate->native_context()->wasm_table_sym());
Object::SetProperty(table_obj, table_sym, table_obj, STRICT).Check();
return Handle<WasmTableObject>::cast(table_obj);
}
@ -327,8 +323,6 @@ Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate,
}
memory_obj->set_array_buffer(*buffer);
memory_obj->set_maximum_pages(maximum);
Handle<Symbol> memory_sym(isolate->native_context()->wasm_memory_sym());
Object::SetProperty(memory_obj, memory_sym, memory_obj, STRICT).Check();
return Handle<WasmMemoryObject>::cast(memory_obj);
}
@ -436,9 +430,6 @@ Handle<WasmInstanceObject> WasmInstanceObject::New(
Handle<JSObject> instance_object =
isolate->factory()->NewJSObject(instance_cons, TENURED);
Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym());
Object::SetProperty(instance_object, instance_sym, instance_object, STRICT)
.Check();
Handle<WasmInstanceObject> instance(
reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate);