[wasm] Introduce instance types for WebAssembly.* objects.
This CL refactors the internal representation of JavaScript-exposed WebAssembly objects to be more like other such objects in V8. By introducing a new instance type for each of the JS-exposed types, we get more robust typechecking without using embedder fields (which were previously used when these objects where instance type JS_API_OBJECT). In addition to the new instance types, the subclasses X of JSObject (WasmInstanceObject, WasmMemoryObject, WasmModuleObject, WasmTableObject) now have appropriate Is##X() methods on Object and are now robust. BUG=v8:6547 CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_chromium_rel_ng Review-Url: https://codereview.chromium.org/2964943002 Cr-Commit-Position: refs/heads/master@{#46475}
This commit is contained in:
parent
c16a39f23e
commit
17001a05c8
12
src/api.cc
12
src/api.cc
@ -7703,10 +7703,10 @@ MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
|
||||
}
|
||||
|
||||
Local<String> WasmCompiledModule::GetWasmWireBytes() {
|
||||
i::Handle<i::JSObject> obj =
|
||||
i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
|
||||
i::Handle<i::WasmModuleObject> obj =
|
||||
i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
|
||||
i::Handle<i::WasmCompiledModule> compiled_part =
|
||||
i::handle(i::WasmCompiledModule::cast(obj->GetEmbedderField(0)));
|
||||
i::handle(i::WasmCompiledModule::cast(obj->compiled_module()));
|
||||
i::Handle<i::String> wire_bytes(compiled_part->module_bytes());
|
||||
return Local<String>::Cast(Utils::ToLocal(wire_bytes));
|
||||
}
|
||||
@ -7742,10 +7742,10 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::FromTransferrableModule(
|
||||
}
|
||||
|
||||
WasmCompiledModule::SerializedModule WasmCompiledModule::Serialize() {
|
||||
i::Handle<i::JSObject> obj =
|
||||
i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
|
||||
i::Handle<i::WasmModuleObject> obj =
|
||||
i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
|
||||
i::Handle<i::WasmCompiledModule> compiled_part =
|
||||
i::handle(i::WasmCompiledModule::cast(obj->GetEmbedderField(0)));
|
||||
i::handle(i::WasmCompiledModule::cast(obj->compiled_module()));
|
||||
|
||||
std::unique_ptr<i::ScriptData> script_data =
|
||||
i::WasmCompiledModuleSerializer::SerializeWasmModule(obj->GetIsolate(),
|
||||
|
@ -267,6 +267,10 @@ Type::bitset BitsetType::Lub(i::Map* map) {
|
||||
case JS_WEAK_SET_TYPE:
|
||||
case JS_PROMISE_CAPABILITY_TYPE:
|
||||
case JS_PROMISE_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_INSTANCE_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
DCHECK(!map->is_callable());
|
||||
DCHECK(!map->is_undetectable());
|
||||
return kOtherObject;
|
||||
|
@ -3983,6 +3983,10 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
|
||||
case PADDING_TYPE_1:
|
||||
case PADDING_TYPE_2:
|
||||
case PADDING_TYPE_3:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_INSTANCE_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
OFStream os(stderr);
|
||||
os << "[couldn't handle instance type " << map->instance_type() << "]"
|
||||
<< std::endl;
|
||||
|
@ -3641,6 +3641,10 @@ AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
|
||||
map->instance_type() == JS_ERROR_TYPE ||
|
||||
map->instance_type() == JS_ARRAY_TYPE ||
|
||||
map->instance_type() == JS_API_OBJECT_TYPE ||
|
||||
map->instance_type() == WASM_INSTANCE_TYPE ||
|
||||
map->instance_type() == WASM_MEMORY_TYPE ||
|
||||
map->instance_type() == WASM_MODULE_TYPE ||
|
||||
map->instance_type() == WASM_TABLE_TYPE ||
|
||||
map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE);
|
||||
|
||||
int object_size = map->instance_size();
|
||||
|
@ -658,6 +658,10 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_MESSAGE_OBJECT_TYPE:
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
case WASM_INSTANCE_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3);
|
||||
case JS_WEAK_MAP_TYPE:
|
||||
case JS_WEAK_SET_TYPE:
|
||||
|
@ -110,6 +110,10 @@ void HeapObject::HeapObjectVerify() {
|
||||
case JS_API_OBJECT_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
|
||||
case WASM_INSTANCE_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
JSObject::cast(this)->JSObjectVerify();
|
||||
break;
|
||||
case JS_ARGUMENTS_TYPE:
|
||||
|
@ -106,6 +106,10 @@ TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
|
||||
TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
|
||||
TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
|
||||
TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE)
|
||||
TYPE_CHECKER(WasmInstanceObject, WASM_INSTANCE_TYPE)
|
||||
TYPE_CHECKER(WasmMemoryObject, WASM_MEMORY_TYPE)
|
||||
TYPE_CHECKER(WasmModuleObject, WASM_MODULE_TYPE)
|
||||
TYPE_CHECKER(WasmTableObject, WASM_TABLE_TYPE)
|
||||
TYPE_CHECKER(Map, MAP_TYPE)
|
||||
TYPE_CHECKER(MutableHeapNumber, MUTABLE_HEAP_NUMBER_TYPE)
|
||||
TYPE_CHECKER(Oddball, ODDBALL_TYPE)
|
||||
@ -1476,79 +1480,12 @@ void WeakCell::clear_next(Object* the_hole_value) {
|
||||
|
||||
bool WeakCell::next_cleared() { return next()->IsTheHole(GetIsolate()); }
|
||||
|
||||
int JSObject::GetHeaderSize() { return GetHeaderSize(map()->instance_type()); }
|
||||
|
||||
|
||||
int JSObject::GetHeaderSize(InstanceType type) {
|
||||
int JSObject::GetHeaderSize() {
|
||||
// Check for the most common kind of JavaScript object before
|
||||
// falling into the generic switch. This speeds up the internal
|
||||
// field operations considerably on average.
|
||||
if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
|
||||
switch (type) {
|
||||
case JS_API_OBJECT_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_GENERATOR_OBJECT_TYPE:
|
||||
return JSGeneratorObject::kSize;
|
||||
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
|
||||
return JSAsyncGeneratorObject::kSize;
|
||||
case JS_GLOBAL_PROXY_TYPE:
|
||||
return JSGlobalProxy::kSize;
|
||||
case JS_GLOBAL_OBJECT_TYPE:
|
||||
return JSGlobalObject::kSize;
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
return JSBoundFunction::kSize;
|
||||
case JS_FUNCTION_TYPE:
|
||||
return JSFunction::kSize;
|
||||
case JS_VALUE_TYPE:
|
||||
return JSValue::kSize;
|
||||
case JS_DATE_TYPE:
|
||||
return JSDate::kSize;
|
||||
case JS_ARRAY_TYPE:
|
||||
return JSArray::kSize;
|
||||
case JS_ARRAY_BUFFER_TYPE:
|
||||
return JSArrayBuffer::kSize;
|
||||
case JS_TYPED_ARRAY_TYPE:
|
||||
return JSTypedArray::kSize;
|
||||
case JS_DATA_VIEW_TYPE:
|
||||
return JSDataView::kSize;
|
||||
case JS_SET_TYPE:
|
||||
return JSSet::kSize;
|
||||
case JS_MAP_TYPE:
|
||||
return JSMap::kSize;
|
||||
case JS_SET_ITERATOR_TYPE:
|
||||
return JSSetIterator::kSize;
|
||||
case JS_MAP_ITERATOR_TYPE:
|
||||
return JSMapIterator::kSize;
|
||||
case JS_WEAK_MAP_TYPE:
|
||||
return JSWeakMap::kSize;
|
||||
case JS_WEAK_SET_TYPE:
|
||||
return JSWeakSet::kSize;
|
||||
case JS_PROMISE_CAPABILITY_TYPE:
|
||||
return JSPromiseCapability::kSize;
|
||||
case JS_PROMISE_TYPE:
|
||||
return JSPromise::kSize;
|
||||
case JS_REGEXP_TYPE:
|
||||
return JSRegExp::kSize;
|
||||
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_MESSAGE_OBJECT_TYPE:
|
||||
return JSMessageObject::kSize;
|
||||
case JS_ARGUMENTS_TYPE:
|
||||
return JSArgumentsObject::kHeaderSize;
|
||||
case JS_ERROR_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_STRING_ITERATOR_TYPE:
|
||||
return JSStringIterator::kSize;
|
||||
case JS_MODULE_NAMESPACE_TYPE:
|
||||
return JSModuleNamespace::kHeaderSize;
|
||||
default:
|
||||
if (type >= FIRST_ARRAY_ITERATOR_TYPE &&
|
||||
type <= LAST_ARRAY_ITERATOR_TYPE) {
|
||||
return JSArrayIterator::kSize;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
InstanceType type = map()->instance_type();
|
||||
return type == JS_OBJECT_TYPE ? JSObject::kHeaderSize : GetHeaderSize(type);
|
||||
}
|
||||
|
||||
inline bool IsSpecialReceiverInstanceType(InstanceType instance_type) {
|
||||
|
@ -153,6 +153,10 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
case JS_ARGUMENTS_TYPE:
|
||||
case JS_ERROR_TYPE:
|
||||
case JS_PROMISE_CAPABILITY_TYPE:
|
||||
case WASM_INSTANCE_TYPE: // TODO(titzer): debug printing for wasm objects
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
JSObject::cast(this)->JSObjectPrint(os);
|
||||
break;
|
||||
case JS_PROMISE_TYPE:
|
||||
|
@ -1290,6 +1290,82 @@ void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
|
||||
isolate->counters()->cow_arrays_converted()->Increment();
|
||||
}
|
||||
|
||||
int JSObject::GetHeaderSize(InstanceType type) {
|
||||
switch (type) {
|
||||
case JS_OBJECT_TYPE:
|
||||
case JS_API_OBJECT_TYPE:
|
||||
case JS_SPECIAL_API_OBJECT_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_GENERATOR_OBJECT_TYPE:
|
||||
return JSGeneratorObject::kSize;
|
||||
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
|
||||
return JSAsyncGeneratorObject::kSize;
|
||||
case JS_GLOBAL_PROXY_TYPE:
|
||||
return JSGlobalProxy::kSize;
|
||||
case JS_GLOBAL_OBJECT_TYPE:
|
||||
return JSGlobalObject::kSize;
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
return JSBoundFunction::kSize;
|
||||
case JS_FUNCTION_TYPE:
|
||||
return JSFunction::kSize;
|
||||
case JS_VALUE_TYPE:
|
||||
return JSValue::kSize;
|
||||
case JS_DATE_TYPE:
|
||||
return JSDate::kSize;
|
||||
case JS_ARRAY_TYPE:
|
||||
return JSArray::kSize;
|
||||
case JS_ARRAY_BUFFER_TYPE:
|
||||
return JSArrayBuffer::kSize;
|
||||
case JS_TYPED_ARRAY_TYPE:
|
||||
return JSTypedArray::kSize;
|
||||
case JS_DATA_VIEW_TYPE:
|
||||
return JSDataView::kSize;
|
||||
case JS_SET_TYPE:
|
||||
return JSSet::kSize;
|
||||
case JS_MAP_TYPE:
|
||||
return JSMap::kSize;
|
||||
case JS_SET_ITERATOR_TYPE:
|
||||
return JSSetIterator::kSize;
|
||||
case JS_MAP_ITERATOR_TYPE:
|
||||
return JSMapIterator::kSize;
|
||||
case JS_WEAK_MAP_TYPE:
|
||||
return JSWeakMap::kSize;
|
||||
case JS_WEAK_SET_TYPE:
|
||||
return JSWeakSet::kSize;
|
||||
case JS_PROMISE_CAPABILITY_TYPE:
|
||||
return JSPromiseCapability::kSize;
|
||||
case JS_PROMISE_TYPE:
|
||||
return JSPromise::kSize;
|
||||
case JS_REGEXP_TYPE:
|
||||
return JSRegExp::kSize;
|
||||
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_MESSAGE_OBJECT_TYPE:
|
||||
return JSMessageObject::kSize;
|
||||
case JS_ARGUMENTS_TYPE:
|
||||
return JSArgumentsObject::kHeaderSize;
|
||||
case JS_ERROR_TYPE:
|
||||
return JSObject::kHeaderSize;
|
||||
case JS_STRING_ITERATOR_TYPE:
|
||||
return JSStringIterator::kSize;
|
||||
case JS_MODULE_NAMESPACE_TYPE:
|
||||
return JSModuleNamespace::kHeaderSize;
|
||||
case WASM_INSTANCE_TYPE:
|
||||
return WasmInstanceObject::kSize;
|
||||
case WASM_MEMORY_TYPE:
|
||||
return WasmMemoryObject::kSize;
|
||||
case WASM_MODULE_TYPE:
|
||||
return WasmModuleObject::kSize;
|
||||
case WASM_TABLE_TYPE:
|
||||
return WasmTableObject::kSize;
|
||||
default:
|
||||
if (type >= FIRST_ARRAY_ITERATOR_TYPE &&
|
||||
type <= LAST_ARRAY_ITERATOR_TYPE) {
|
||||
return JSArrayIterator::kSize;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 9.5.1
|
||||
// static
|
||||
@ -3011,6 +3087,10 @@ VisitorId Map::GetVisitorId(Map* map) {
|
||||
|
||||
case JS_PROMISE_CAPABILITY_TYPE:
|
||||
case JS_PROMISE_TYPE:
|
||||
case WASM_INSTANCE_TYPE:
|
||||
case WASM_MEMORY_TYPE:
|
||||
case WASM_MODULE_TYPE:
|
||||
case WASM_TABLE_TYPE:
|
||||
case JS_BOUND_FUNCTION_TYPE:
|
||||
return has_unboxed_fields ? kVisitJSObject : kVisitJSObjectFast;
|
||||
case JS_API_OBJECT_TYPE:
|
||||
|
@ -73,6 +73,10 @@
|
||||
// - JSDate
|
||||
// - JSMessageObject
|
||||
// - JSModuleNamespace
|
||||
// - WasmInstanceObject
|
||||
// - WasmMemoryObject
|
||||
// - WasmModuleObject
|
||||
// - WasmTableObject
|
||||
// - JSProxy
|
||||
// - FixedArrayBase
|
||||
// - ByteArray
|
||||
@ -99,6 +103,8 @@
|
||||
// - ModuleInfo
|
||||
// - ScriptContextTable
|
||||
// - WeakFixedArray
|
||||
// - WasmSharedModuleData
|
||||
// - WasmCompiledModule
|
||||
// - FixedDoubleArray
|
||||
// - Name
|
||||
// - String
|
||||
@ -445,6 +451,10 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
V(JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE) \
|
||||
\
|
||||
V(WASM_INSTANCE_TYPE) \
|
||||
V(WASM_MEMORY_TYPE) \
|
||||
V(WASM_MODULE_TYPE) \
|
||||
V(WASM_TABLE_TYPE) \
|
||||
V(JS_BOUND_FUNCTION_TYPE) \
|
||||
V(JS_FUNCTION_TYPE)
|
||||
|
||||
@ -798,6 +808,10 @@ enum InstanceType {
|
||||
JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE,
|
||||
|
||||
WASM_INSTANCE_TYPE,
|
||||
WASM_MEMORY_TYPE,
|
||||
WASM_MODULE_TYPE,
|
||||
WASM_TABLE_TYPE,
|
||||
JS_BOUND_FUNCTION_TYPE,
|
||||
JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
|
||||
|
||||
@ -1053,6 +1067,10 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(JSMapIterator) \
|
||||
V(JSMessageObject) \
|
||||
V(JSModuleNamespace) \
|
||||
V(WasmInstanceObject) \
|
||||
V(WasmMemoryObject) \
|
||||
V(WasmModuleObject) \
|
||||
V(WasmTableObject) \
|
||||
V(JSObject) \
|
||||
V(JSPromise) \
|
||||
V(JSPromiseCapability) \
|
||||
@ -2389,7 +2407,7 @@ class JSObject: public JSReceiver {
|
||||
|
||||
// Get the header size for a JSObject. Used to compute the index of
|
||||
// embedder fields as well as the number of embedder fields.
|
||||
static inline int GetHeaderSize(InstanceType instance_type);
|
||||
static int GetHeaderSize(InstanceType instance_type);
|
||||
inline int GetHeaderSize();
|
||||
|
||||
static inline int GetEmbedderFieldCount(const Map* map);
|
||||
|
@ -864,16 +864,12 @@ 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_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
|
||||
|
||||
Handle<WasmCompiledModule> orig(module_obj->compiled_module());
|
||||
std::unique_ptr<ScriptData> data =
|
||||
@ -925,7 +921,7 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
|
||||
RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
|
||||
HandleScope shs(isolate);
|
||||
DCHECK_EQ(2, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Smi, instance_count, 1);
|
||||
wasm::testing::ValidateInstancesChain(isolate, module_obj,
|
||||
instance_count->value());
|
||||
@ -935,7 +931,7 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
|
||||
RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) {
|
||||
HandleScope shs(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0);
|
||||
wasm::testing::ValidateModuleState(isolate, module_obj);
|
||||
return isolate->heap()->ToBoolean(true);
|
||||
}
|
||||
@ -943,7 +939,7 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) {
|
||||
RUNTIME_FUNCTION(Runtime_ValidateWasmOrphanedInstance) {
|
||||
HandleScope shs(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED_2(WasmInstanceObject, instance, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
wasm::testing::ValidateOrphanedInstance(isolate, instance);
|
||||
return isolate->heap()->ToBoolean(true);
|
||||
}
|
||||
@ -968,10 +964,7 @@ RUNTIME_FUNCTION(Runtime_HeapObjectVerify) {
|
||||
RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) {
|
||||
DCHECK_EQ(1, args.length());
|
||||
HandleScope scope(isolate);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0);
|
||||
CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj));
|
||||
Handle<WasmInstanceObject> instance =
|
||||
Handle<WasmInstanceObject>::cast(instance_obj);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
if (!instance->has_debug_info()) return 0;
|
||||
uint64_t num = instance->debug_info()->NumInterpretedCalls();
|
||||
return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num));
|
||||
@ -980,11 +973,8 @@ RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) {
|
||||
RUNTIME_FUNCTION(Runtime_RedirectToWasmInterpreter) {
|
||||
DCHECK_EQ(2, args.length());
|
||||
HandleScope scope(isolate);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
CONVERT_SMI_ARG_CHECKED(function_index, 1);
|
||||
CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj));
|
||||
Handle<WasmInstanceObject> instance =
|
||||
Handle<WasmInstanceObject>::cast(instance_obj);
|
||||
Handle<WasmDebugInfo> debug_info =
|
||||
WasmInstanceObject::GetOrCreateDebugInfo(instance);
|
||||
WasmDebugInfo::RedirectToInterpreter(debug_info,
|
||||
|
@ -180,12 +180,9 @@ RUNTIME_FUNCTION(Runtime_ClearThreadInWasm) {
|
||||
RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) {
|
||||
DCHECK_EQ(3, args.length());
|
||||
HandleScope scope(isolate);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[1]);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 2);
|
||||
CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj));
|
||||
Handle<WasmInstanceObject> instance =
|
||||
Handle<WasmInstanceObject>::cast(instance_obj);
|
||||
|
||||
// The arg buffer is the raw pointer to the caller's stack. It looks like a
|
||||
// Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just
|
||||
|
@ -449,12 +449,7 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
|
||||
case JS_OBJECT_TYPE:
|
||||
case JS_API_OBJECT_TYPE: {
|
||||
Handle<JSObject> js_object = Handle<JSObject>::cast(receiver);
|
||||
Map* map = js_object->map();
|
||||
if (!FLAG_wasm_disable_structured_cloning &&
|
||||
map->GetConstructor() ==
|
||||
isolate_->native_context()->wasm_module_constructor()) {
|
||||
return WriteWasmModule(js_object);
|
||||
} else if (JSObject::GetEmbedderFieldCount(map)) {
|
||||
if (JSObject::GetEmbedderFieldCount(js_object->map())) {
|
||||
return WriteHostObject(js_object);
|
||||
} else {
|
||||
return WriteJSObject(js_object);
|
||||
@ -479,6 +474,11 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
|
||||
case JS_TYPED_ARRAY_TYPE:
|
||||
case JS_DATA_VIEW_TYPE:
|
||||
return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver));
|
||||
case WASM_MODULE_TYPE:
|
||||
if (!FLAG_wasm_disable_structured_cloning) {
|
||||
// Only write WebAssembly modules if not disabled by a flag.
|
||||
return WriteWasmModule(Handle<WasmModuleObject>::cast(receiver));
|
||||
} // fall through to error case
|
||||
default:
|
||||
ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver);
|
||||
return Nothing<bool>();
|
||||
@ -815,11 +815,13 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) {
|
||||
return ThrowIfOutOfMemory();
|
||||
}
|
||||
|
||||
Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) {
|
||||
Maybe<bool> ValueSerializer::WriteWasmModule(Handle<WasmModuleObject> object) {
|
||||
if (delegate_ != nullptr) {
|
||||
// TODO(titzer): introduce a Utils::ToLocal for WasmModuleObject.
|
||||
Maybe<uint32_t> transfer_id = delegate_->GetWasmModuleTransferId(
|
||||
reinterpret_cast<v8::Isolate*>(isolate_),
|
||||
v8::Local<v8::WasmCompiledModule>::Cast(Utils::ToLocal(object)));
|
||||
v8::Local<v8::WasmCompiledModule>::Cast(
|
||||
Utils::ToLocal(Handle<JSObject>::cast(object))));
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate_, Nothing<bool>());
|
||||
uint32_t id = 0;
|
||||
if (transfer_id.To(&id)) {
|
||||
@ -829,8 +831,7 @@ Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) {
|
||||
}
|
||||
}
|
||||
|
||||
Handle<WasmCompiledModule> compiled_part(
|
||||
WasmCompiledModule::cast(object->GetEmbedderField(0)), isolate_);
|
||||
Handle<WasmCompiledModule> compiled_part(object->compiled_module(), isolate_);
|
||||
WasmEncodingTag encoding_tag = WasmEncodingTag::kRawBytes;
|
||||
WriteTag(SerializationTag::kWasmModule);
|
||||
WriteRawBytes(&encoding_tag, sizeof(encoding_tag));
|
||||
|
@ -125,7 +125,8 @@ class ValueSerializer {
|
||||
Maybe<bool> WriteJSArrayBuffer(Handle<JSArrayBuffer> array_buffer)
|
||||
WARN_UNUSED_RESULT;
|
||||
Maybe<bool> WriteJSArrayBufferView(JSArrayBufferView* array_buffer);
|
||||
Maybe<bool> WriteWasmModule(Handle<JSObject> object) WARN_UNUSED_RESULT;
|
||||
Maybe<bool> WriteWasmModule(Handle<WasmModuleObject> object)
|
||||
WARN_UNUSED_RESULT;
|
||||
Maybe<bool> WriteHostObject(Handle<JSObject> object) WARN_UNUSED_RESULT;
|
||||
|
||||
/*
|
||||
|
@ -1022,7 +1022,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
|
||||
//--------------------------------------------------------------------------
|
||||
// Add instance to Memory object
|
||||
//--------------------------------------------------------------------------
|
||||
DCHECK(wasm::IsWasmInstance(*instance));
|
||||
DCHECK(instance->IsWasmInstanceObject());
|
||||
if (instance->has_memory_object()) {
|
||||
instance->memory_object()->AddInstance(isolate_, instance);
|
||||
}
|
||||
@ -1074,7 +1074,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
|
||||
compiled_module_->set_weak_wasm_module(
|
||||
original.ToHandleChecked()->weak_wasm_module());
|
||||
}
|
||||
module_object_->SetEmbedderField(0, *compiled_module_);
|
||||
module_object_->set_compiled_module(*compiled_module_);
|
||||
compiled_module_->set_weak_owning_instance(link_to_owning_instance);
|
||||
GlobalHandles::MakeWeak(
|
||||
global_handle.location(), global_handle.location(),
|
||||
@ -1398,7 +1398,7 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table,
|
||||
auto memory = Handle<WasmMemoryObject>::cast(value);
|
||||
DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory));
|
||||
instance->set_memory_object(*memory);
|
||||
memory_ = Handle<JSArrayBuffer>(memory->buffer(), isolate_);
|
||||
memory_ = Handle<JSArrayBuffer>(memory->array_buffer(), isolate_);
|
||||
uint32_t imported_cur_pages = static_cast<uint32_t>(
|
||||
memory_->byte_length()->Number() / WasmModule::kPageSize);
|
||||
if (imported_cur_pages < module_->min_mem_pages) {
|
||||
@ -1668,7 +1668,6 @@ void InstanceBuilder::ProcessExports(
|
||||
} else {
|
||||
memory_object =
|
||||
Handle<WasmMemoryObject>(instance->memory_object(), isolate_);
|
||||
DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory_object));
|
||||
memory_object->ResetInstancesLink(isolate_);
|
||||
}
|
||||
|
||||
|
@ -539,25 +539,25 @@ class InterpreterHandle {
|
||||
|
||||
InterpreterHandle* GetOrCreateInterpreterHandle(
|
||||
Isolate* isolate, Handle<WasmDebugInfo> debug_info) {
|
||||
Handle<Object> handle(debug_info->get(WasmDebugInfo::kInterpreterHandle),
|
||||
Handle<Object> handle(debug_info->get(WasmDebugInfo::kInterpreterHandleIndex),
|
||||
isolate);
|
||||
if (handle->IsUndefined(isolate)) {
|
||||
InterpreterHandle* cpp_handle = new InterpreterHandle(isolate, *debug_info);
|
||||
handle = Managed<InterpreterHandle>::New(isolate, cpp_handle);
|
||||
debug_info->set(WasmDebugInfo::kInterpreterHandle, *handle);
|
||||
debug_info->set(WasmDebugInfo::kInterpreterHandleIndex, *handle);
|
||||
}
|
||||
|
||||
return Handle<Managed<InterpreterHandle>>::cast(handle)->get();
|
||||
}
|
||||
|
||||
InterpreterHandle* GetInterpreterHandle(WasmDebugInfo* debug_info) {
|
||||
Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandle);
|
||||
Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandleIndex);
|
||||
DCHECK(!handle_obj->IsUndefined(debug_info->GetIsolate()));
|
||||
return Managed<InterpreterHandle>::cast(handle_obj)->get();
|
||||
}
|
||||
|
||||
InterpreterHandle* GetInterpreterHandleOrNull(WasmDebugInfo* debug_info) {
|
||||
Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandle);
|
||||
Object* handle_obj = debug_info->get(WasmDebugInfo::kInterpreterHandleIndex);
|
||||
if (handle_obj->IsUndefined(debug_info->GetIsolate())) return nullptr;
|
||||
return Managed<InterpreterHandle>::cast(handle_obj)->get();
|
||||
}
|
||||
@ -571,13 +571,13 @@ int GetNumFunctions(WasmInstanceObject* instance) {
|
||||
|
||||
Handle<FixedArray> GetOrCreateInterpretedFunctions(
|
||||
Isolate* isolate, Handle<WasmDebugInfo> debug_info) {
|
||||
Handle<Object> obj(debug_info->get(WasmDebugInfo::kInterpretedFunctions),
|
||||
Handle<Object> obj(debug_info->get(WasmDebugInfo::kInterpretedFunctionsIndex),
|
||||
isolate);
|
||||
if (!obj->IsUndefined(isolate)) return Handle<FixedArray>::cast(obj);
|
||||
|
||||
Handle<FixedArray> new_arr = isolate->factory()->NewFixedArray(
|
||||
GetNumFunctions(debug_info->wasm_instance()));
|
||||
debug_info->set(WasmDebugInfo::kInterpretedFunctions, *new_arr);
|
||||
debug_info->set(WasmDebugInfo::kInterpretedFunctionsIndex, *new_arr);
|
||||
return new_arr;
|
||||
}
|
||||
|
||||
@ -622,8 +622,7 @@ Handle<WasmDebugInfo> WasmDebugInfo::New(Handle<WasmInstanceObject> instance) {
|
||||
DCHECK(!instance->has_debug_info());
|
||||
Factory* factory = instance->GetIsolate()->factory();
|
||||
Handle<FixedArray> arr = factory->NewFixedArray(kFieldCount, TENURED);
|
||||
arr->set(kWrapperTracerHeader, Smi::kZero);
|
||||
arr->set(kInstance, *instance);
|
||||
arr->set(kInstanceIndex, *instance);
|
||||
Handle<WasmDebugInfo> debug_info = Handle<WasmDebugInfo>::cast(arr);
|
||||
instance->set_debug_info(*debug_info);
|
||||
return debug_info;
|
||||
@ -636,29 +635,29 @@ WasmInterpreter* WasmDebugInfo::SetupForTesting(
|
||||
InterpreterHandle* cpp_handle =
|
||||
new InterpreterHandle(isolate, *debug_info, instance);
|
||||
Handle<Object> handle = Managed<InterpreterHandle>::New(isolate, cpp_handle);
|
||||
debug_info->set(kInterpreterHandle, *handle);
|
||||
debug_info->set(kInterpreterHandleIndex, *handle);
|
||||
return cpp_handle->interpreter();
|
||||
}
|
||||
|
||||
bool WasmDebugInfo::IsDebugInfo(Object* object) {
|
||||
bool WasmDebugInfo::IsWasmDebugInfo(Object* object) {
|
||||
if (!object->IsFixedArray()) return false;
|
||||
FixedArray* arr = FixedArray::cast(object);
|
||||
if (arr->length() != kFieldCount) return false;
|
||||
if (!IsWasmInstance(arr->get(kInstance))) return false;
|
||||
if (!arr->get(kInstanceIndex)->IsWasmInstanceObject()) return false;
|
||||
Isolate* isolate = arr->GetIsolate();
|
||||
if (!arr->get(kInterpreterHandle)->IsUndefined(isolate) &&
|
||||
!arr->get(kInterpreterHandle)->IsForeign())
|
||||
if (!arr->get(kInterpreterHandleIndex)->IsUndefined(isolate) &&
|
||||
!arr->get(kInterpreterHandleIndex)->IsForeign())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
WasmDebugInfo* WasmDebugInfo::cast(Object* object) {
|
||||
DCHECK(IsDebugInfo(object));
|
||||
DCHECK(IsWasmDebugInfo(object));
|
||||
return reinterpret_cast<WasmDebugInfo*>(object);
|
||||
}
|
||||
|
||||
WasmInstanceObject* WasmDebugInfo::wasm_instance() {
|
||||
return WasmInstanceObject::cast(get(kInstance));
|
||||
return WasmInstanceObject::cast(get(kInstanceIndex));
|
||||
}
|
||||
|
||||
void WasmDebugInfo::SetBreakpoint(Handle<WasmDebugInfo> debug_info,
|
||||
|
@ -90,7 +90,7 @@ struct WasmVal {
|
||||
}
|
||||
};
|
||||
|
||||
#define DECLARE_CAST(field, localtype, ctype) \
|
||||
#define DECLARE_CASTS(field, localtype, ctype) \
|
||||
template <> \
|
||||
inline ctype WasmVal::to_unchecked() const { \
|
||||
return val.field; \
|
||||
@ -100,7 +100,7 @@ struct WasmVal {
|
||||
CHECK_EQ(localtype, type); \
|
||||
return val.field; \
|
||||
}
|
||||
FOREACH_UNION_MEMBER(DECLARE_CAST)
|
||||
FOREACH_UNION_MEMBER(DECLARE_CASTS)
|
||||
#undef DECLARE_CAST
|
||||
|
||||
// Representation of frames within the interpreter.
|
||||
|
@ -69,7 +69,7 @@ class ScheduledErrorThrower : public ErrorThrower {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(wasm): move brand check to the respective types, and don't throw
|
||||
// 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;
|
||||
@ -780,7 +780,7 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_mem_pages)) {
|
||||
max_size64 = i::FLAG_wasm_max_mem_pages;
|
||||
}
|
||||
i::Handle<i::JSArrayBuffer> old_buffer(receiver->buffer());
|
||||
i::Handle<i::JSArrayBuffer> old_buffer(receiver->array_buffer());
|
||||
uint32_t old_size =
|
||||
old_buffer->byte_length()->Number() / i::wasm::kSpecMaxWasmMemoryPages;
|
||||
int64_t new_size64 = old_size + delta_size;
|
||||
@ -817,7 +817,7 @@ void WebAssemblyMemoryGetBuffer(
|
||||
}
|
||||
i::Handle<i::WasmMemoryObject> receiver =
|
||||
i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
|
||||
i::Handle<i::Object> buffer(receiver->buffer(), i_isolate);
|
||||
i::Handle<i::Object> buffer(receiver->array_buffer(), i_isolate);
|
||||
DCHECK(buffer->IsJSArrayBuffer());
|
||||
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
||||
return_value.Set(Utils::ToLocal(buffer));
|
||||
@ -879,12 +879,9 @@ void WasmJs::Install(Isolate* isolate) {
|
||||
int pre_allocated =
|
||||
prev_map->GetInObjectProperties() - prev_map->unused_property_fields();
|
||||
int instance_size = 0;
|
||||
int in_object_properties = 0;
|
||||
int wasm_embedder_fields = embedder_fields + 1 // module instance object
|
||||
+ 1 // function arity
|
||||
+ 1; // function signature
|
||||
JSFunction::CalculateInstanceSizeHelper(instance_type, wasm_embedder_fields,
|
||||
0, &instance_size,
|
||||
int in_object_properties = WasmExportedFunction::kFieldCount;
|
||||
JSFunction::CalculateInstanceSizeHelper(instance_type, embedder_fields,
|
||||
in_object_properties, &instance_size,
|
||||
&in_object_properties);
|
||||
|
||||
int unused_property_fields = in_object_properties - pre_allocated;
|
||||
@ -942,8 +939,8 @@ void WasmJs::Install(Isolate* isolate) {
|
||||
Handle<JSObject> module_proto =
|
||||
factory->NewJSObject(module_constructor, TENURED);
|
||||
i::Handle<i::Map> module_map = isolate->factory()->NewMap(
|
||||
i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
||||
WasmModuleObject::kFieldCount * i::kPointerSize);
|
||||
i::WASM_MODULE_TYPE, i::JSObject::kHeaderSize +
|
||||
WasmModuleObject::kFieldCount * i::kPointerSize);
|
||||
JSFunction::SetInitialMap(module_constructor, module_map, module_proto);
|
||||
InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports,
|
||||
1);
|
||||
@ -963,8 +960,7 @@ void WasmJs::Install(Isolate* isolate) {
|
||||
Handle<JSObject> instance_proto =
|
||||
factory->NewJSObject(instance_constructor, TENURED);
|
||||
i::Handle<i::Map> instance_map = isolate->factory()->NewMap(
|
||||
i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
||||
WasmInstanceObject::kFieldCount * i::kPointerSize);
|
||||
i::WASM_INSTANCE_TYPE, WasmInstanceObject::kSize);
|
||||
JSFunction::SetInitialMap(instance_constructor, instance_map, instance_proto);
|
||||
JSObject::AddProperty(instance_proto,
|
||||
isolate->factory()->constructor_string(),
|
||||
@ -978,9 +974,8 @@ void WasmJs::Install(Isolate* isolate) {
|
||||
context->set_wasm_table_constructor(*table_constructor);
|
||||
Handle<JSObject> table_proto =
|
||||
factory->NewJSObject(table_constructor, TENURED);
|
||||
i::Handle<i::Map> table_map = isolate->factory()->NewMap(
|
||||
i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
||||
WasmTableObject::kFieldCount * i::kPointerSize);
|
||||
i::Handle<i::Map> table_map =
|
||||
isolate->factory()->NewMap(i::WASM_TABLE_TYPE, WasmTableObject::kSize);
|
||||
JSFunction::SetInitialMap(table_constructor, table_map, table_proto);
|
||||
JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(),
|
||||
table_constructor, DONT_ENUM);
|
||||
@ -997,9 +992,8 @@ void WasmJs::Install(Isolate* isolate) {
|
||||
context->set_wasm_memory_constructor(*memory_constructor);
|
||||
Handle<JSObject> memory_proto =
|
||||
factory->NewJSObject(memory_constructor, TENURED);
|
||||
i::Handle<i::Map> memory_map = isolate->factory()->NewMap(
|
||||
i::JS_API_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
||||
WasmMemoryObject::kFieldCount * i::kPointerSize);
|
||||
i::Handle<i::Map> memory_map =
|
||||
isolate->factory()->NewMap(i::WASM_MEMORY_TYPE, WasmMemoryObject::kSize);
|
||||
JSFunction::SetInitialMap(memory_constructor, memory_map, memory_proto);
|
||||
JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(),
|
||||
memory_constructor, DONT_ENUM);
|
||||
|
@ -159,9 +159,9 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
|
||||
// was GC-ed. In that case, there won't be any new instances created,
|
||||
// and we don't need to maintain the links between instances.
|
||||
if (!weak_wasm_module->cleared()) {
|
||||
JSObject* wasm_module = JSObject::cast(weak_wasm_module->value());
|
||||
WasmCompiledModule* current_template =
|
||||
WasmCompiledModule::cast(wasm_module->GetEmbedderField(0));
|
||||
WasmModuleObject* wasm_module =
|
||||
WasmModuleObject::cast(weak_wasm_module->value());
|
||||
WasmCompiledModule* current_template = wasm_module->compiled_module();
|
||||
|
||||
TRACE("chain before {\n");
|
||||
TRACE_CHAIN(current_template);
|
||||
@ -175,10 +175,12 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
|
||||
if (next == nullptr) {
|
||||
WasmCompiledModule::Reset(isolate, compiled_module);
|
||||
} else {
|
||||
DCHECK(next->value()->IsFixedArray());
|
||||
wasm_module->SetEmbedderField(0, next->value());
|
||||
WasmCompiledModule* next_compiled_module =
|
||||
WasmCompiledModule::cast(next->value());
|
||||
WasmModuleObject::cast(wasm_module)
|
||||
->set_compiled_module(next_compiled_module);
|
||||
DCHECK_NULL(prev);
|
||||
WasmCompiledModule::cast(next->value())->reset_weak_prev_instance();
|
||||
next_compiled_module->reset_weak_prev_instance();
|
||||
}
|
||||
} else {
|
||||
DCHECK(!(prev == nullptr && next == nullptr));
|
||||
@ -205,7 +207,7 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
|
||||
}
|
||||
}
|
||||
TRACE("chain after {\n");
|
||||
TRACE_CHAIN(WasmCompiledModule::cast(wasm_module->GetEmbedderField(0)));
|
||||
TRACE_CHAIN(wasm_module->compiled_module());
|
||||
TRACE("}\n");
|
||||
}
|
||||
compiled_module->reset_weak_owning_instance();
|
||||
@ -452,10 +454,6 @@ void wasm::TableSet(ErrorThrower* thrower, Isolate* isolate,
|
||||
array->set(index, *value);
|
||||
}
|
||||
|
||||
bool wasm::IsWasmInstance(Object* object) {
|
||||
return WasmInstanceObject::IsWasmInstanceObject(object);
|
||||
}
|
||||
|
||||
Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
|
||||
WasmCompiledModule* compiled_module =
|
||||
WasmInstanceObject::cast(*instance)->compiled_module();
|
||||
@ -514,8 +512,9 @@ void testing::ValidateInstancesChain(Isolate* isolate,
|
||||
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(), *module_obj);
|
||||
CHECK(IsWasmInstance(
|
||||
current_instance->ptr_to_weak_owning_instance()->value()));
|
||||
CHECK(current_instance->ptr_to_weak_owning_instance()
|
||||
->value()
|
||||
->IsWasmInstanceObject());
|
||||
prev = current_instance;
|
||||
current_instance = WasmCompiledModule::cast(
|
||||
current_instance->ptr_to_weak_next_instance()->value());
|
||||
|
@ -384,13 +384,6 @@ std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
|
||||
// If no debug info exists yet, it is created automatically.
|
||||
Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm);
|
||||
|
||||
// Check whether the given object represents a WebAssembly.Instance instance.
|
||||
// This checks the number and type of embedder fields, so it's not 100 percent
|
||||
// secure. If it turns out that we need more complete checks, we could add a
|
||||
// special marker as embedder field, which will definitely never occur anywhere
|
||||
// else.
|
||||
bool IsWasmInstance(Object* instance);
|
||||
|
||||
// Get the script of the wasm module. If the origin of the module is asm.js, the
|
||||
// returned Script will be a JavaScript Script of Script::TYPE_NORMAL, otherwise
|
||||
// it's of type TYPE_WASM.
|
||||
|
@ -29,46 +29,6 @@
|
||||
using namespace v8::internal;
|
||||
using namespace v8::internal::wasm;
|
||||
|
||||
#define DEFINE_GETTER0(getter, Container, name, field, type) \
|
||||
type* Container::name() { return type::cast(getter(field)); }
|
||||
|
||||
#define DEFINE_ACCESSORS0(getter, setter, Container, name, field, type) \
|
||||
DEFINE_GETTER0(getter, Container, name, field, type) \
|
||||
void Container::set_##name(type* value) { return setter(field, value); }
|
||||
|
||||
#define DEFINE_OPTIONAL_ACCESSORS0(getter, setter, Container, name, field, \
|
||||
type) \
|
||||
DEFINE_ACCESSORS0(getter, setter, Container, name, field, type) \
|
||||
bool Container::has_##name() { \
|
||||
return !getter(field)->IsUndefined(GetIsolate()); \
|
||||
}
|
||||
|
||||
#define DEFINE_OPTIONAL_GETTER0(getter, Container, name, field, type) \
|
||||
DEFINE_GETTER0(getter, Container, name, field, type) \
|
||||
bool Container::has_##name() { \
|
||||
return !getter(field)->IsUndefined(GetIsolate()); \
|
||||
}
|
||||
|
||||
#define DEFINE_GETTER0(getter, Container, name, field, type) \
|
||||
type* Container::name() { return type::cast(getter(field)); }
|
||||
|
||||
#define DEFINE_OBJ_GETTER(Container, name, field, type) \
|
||||
DEFINE_GETTER0(GetEmbedderField, Container, name, field, type)
|
||||
#define DEFINE_OBJ_ACCESSORS(Container, name, field, type) \
|
||||
DEFINE_ACCESSORS0(GetEmbedderField, SetEmbedderField, Container, name, \
|
||||
field, type)
|
||||
#define DEFINE_OPTIONAL_OBJ_ACCESSORS(Container, name, field, type) \
|
||||
DEFINE_OPTIONAL_ACCESSORS0(GetEmbedderField, SetEmbedderField, Container, \
|
||||
name, field, type)
|
||||
#define DEFINE_ARR_GETTER(Container, name, field, type) \
|
||||
DEFINE_GETTER0(get, Container, name, field, type)
|
||||
#define DEFINE_ARR_ACCESSORS(Container, name, field, type) \
|
||||
DEFINE_ACCESSORS0(get, set, Container, name, field, type)
|
||||
#define DEFINE_OPTIONAL_ARR_ACCESSORS(Container, name, field, type) \
|
||||
DEFINE_OPTIONAL_ACCESSORS0(get, set, Container, name, field, type)
|
||||
#define DEFINE_OPTIONAL_ARR_GETTER(Container, name, field, type) \
|
||||
DEFINE_OPTIONAL_GETTER0(get, Container, name, field, type)
|
||||
|
||||
namespace {
|
||||
|
||||
// An iterator that returns first the module itself, then all modules linked via
|
||||
@ -198,63 +158,38 @@ bool IsBreakablePosition(Handle<WasmCompiledModule> compiled_module,
|
||||
|
||||
Handle<WasmModuleObject> WasmModuleObject::New(
|
||||
Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
|
||||
WasmModule* module = compiled_module->module();
|
||||
Handle<JSObject> module_object;
|
||||
if (module->is_wasm()) {
|
||||
Handle<JSFunction> module_cons(
|
||||
isolate->native_context()->wasm_module_constructor());
|
||||
module_object = 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();
|
||||
} else {
|
||||
DCHECK(module->is_asm_js());
|
||||
Handle<Map> map = isolate->factory()->NewMap(
|
||||
JS_OBJECT_TYPE,
|
||||
JSObject::kHeaderSize + WasmModuleObject::kFieldCount * kPointerSize);
|
||||
module_object = isolate->factory()->NewJSObjectFromMap(map, TENURED);
|
||||
}
|
||||
module_object->SetEmbedderField(WasmModuleObject::kCompiledModule,
|
||||
*compiled_module);
|
||||
Handle<JSFunction> module_cons(
|
||||
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);
|
||||
compiled_module->set_weak_wasm_module(link_to_module);
|
||||
return Handle<WasmModuleObject>::cast(module_object);
|
||||
return module_object;
|
||||
}
|
||||
|
||||
WasmModuleObject* WasmModuleObject::cast(Object* object) {
|
||||
DCHECK(object->IsJSObject());
|
||||
// TODO(titzer): brand check for WasmModuleObject.
|
||||
return reinterpret_cast<WasmModuleObject*>(object);
|
||||
}
|
||||
|
||||
bool WasmModuleObject::IsWasmModuleObject(Object* object) {
|
||||
return object->IsJSObject() &&
|
||||
JSObject::cast(object)->GetEmbedderFieldCount() == kFieldCount;
|
||||
}
|
||||
|
||||
DEFINE_OBJ_GETTER(WasmModuleObject, compiled_module, kCompiledModule,
|
||||
WasmCompiledModule)
|
||||
|
||||
Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, uint32_t initial,
|
||||
int64_t maximum,
|
||||
Handle<FixedArray>* js_functions) {
|
||||
Handle<JSFunction> table_ctor(
|
||||
isolate->native_context()->wasm_table_constructor());
|
||||
Handle<JSObject> table_obj = isolate->factory()->NewJSObject(table_ctor);
|
||||
table_obj->SetEmbedderField(kWrapperTracerHeader, Smi::kZero);
|
||||
auto table_obj = Handle<WasmTableObject>::cast(
|
||||
isolate->factory()->NewJSObject(table_ctor));
|
||||
|
||||
*js_functions = isolate->factory()->NewFixedArray(initial);
|
||||
Object* null = isolate->heap()->null_value();
|
||||
for (int i = 0; i < static_cast<int>(initial); ++i) {
|
||||
(*js_functions)->set(i, null);
|
||||
}
|
||||
table_obj->SetEmbedderField(kFunctions, *(*js_functions));
|
||||
Handle<Object> max = isolate->factory()->NewNumber(maximum);
|
||||
table_obj->SetEmbedderField(kMaximum, *max);
|
||||
table_obj->set_functions(**js_functions);
|
||||
DCHECK_EQ(maximum, static_cast<int>(maximum));
|
||||
table_obj->set_maximum_length(static_cast<int>(maximum));
|
||||
|
||||
Handle<FixedArray> dispatch_tables = isolate->factory()->NewFixedArray(0);
|
||||
table_obj->SetEmbedderField(kDispatchTables, *dispatch_tables);
|
||||
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);
|
||||
@ -264,8 +199,7 @@ Handle<FixedArray> WasmTableObject::AddDispatchTable(
|
||||
Isolate* isolate, Handle<WasmTableObject> table_obj,
|
||||
Handle<WasmInstanceObject> instance, int table_index,
|
||||
Handle<FixedArray> function_table, Handle<FixedArray> signature_table) {
|
||||
Handle<FixedArray> dispatch_tables(
|
||||
FixedArray::cast(table_obj->GetEmbedderField(kDispatchTables)), isolate);
|
||||
Handle<FixedArray> dispatch_tables(table_obj->dispatch_tables());
|
||||
DCHECK_EQ(0, dispatch_tables->length() % 4);
|
||||
|
||||
if (instance.is_null()) return dispatch_tables;
|
||||
@ -281,35 +215,13 @@ Handle<FixedArray> WasmTableObject::AddDispatchTable(
|
||||
new_dispatch_tables->set(dispatch_tables->length() + 2, *function_table);
|
||||
new_dispatch_tables->set(dispatch_tables->length() + 3, *signature_table);
|
||||
|
||||
table_obj->SetEmbedderField(WasmTableObject::kDispatchTables,
|
||||
*new_dispatch_tables);
|
||||
table_obj->set_dispatch_tables(*new_dispatch_tables);
|
||||
|
||||
return new_dispatch_tables;
|
||||
}
|
||||
|
||||
DEFINE_OBJ_ACCESSORS(WasmTableObject, functions, kFunctions, FixedArray)
|
||||
|
||||
DEFINE_OBJ_GETTER(WasmTableObject, dispatch_tables, kDispatchTables, FixedArray)
|
||||
|
||||
uint32_t WasmTableObject::current_length() { return functions()->length(); }
|
||||
|
||||
bool WasmTableObject::has_maximum_length() {
|
||||
return GetEmbedderField(kMaximum)->Number() >= 0;
|
||||
}
|
||||
|
||||
int64_t WasmTableObject::maximum_length() {
|
||||
return static_cast<int64_t>(GetEmbedderField(kMaximum)->Number());
|
||||
}
|
||||
|
||||
WasmTableObject* WasmTableObject::cast(Object* object) {
|
||||
DCHECK(object && object->IsJSObject());
|
||||
// TODO(titzer): brand check for WasmTableObject.
|
||||
return reinterpret_cast<WasmTableObject*>(object);
|
||||
}
|
||||
|
||||
void WasmTableObject::grow(Isolate* isolate, uint32_t count) {
|
||||
Handle<FixedArray> dispatch_tables(
|
||||
FixedArray::cast(GetEmbedderField(kDispatchTables)));
|
||||
Handle<FixedArray> dispatch_tables(this->dispatch_tables());
|
||||
DCHECK_EQ(0, dispatch_tables->length() % 4);
|
||||
uint32_t old_size = functions()->length();
|
||||
|
||||
@ -406,46 +318,26 @@ Handle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate,
|
||||
int32_t maximum) {
|
||||
Handle<JSFunction> memory_ctor(
|
||||
isolate->native_context()->wasm_memory_constructor());
|
||||
Handle<JSObject> memory_obj =
|
||||
isolate->factory()->NewJSObject(memory_ctor, TENURED);
|
||||
memory_obj->SetEmbedderField(kWrapperTracerHeader, Smi::kZero);
|
||||
auto memory_obj = Handle<WasmMemoryObject>::cast(
|
||||
isolate->factory()->NewJSObject(memory_ctor, TENURED));
|
||||
if (buffer.is_null()) {
|
||||
const bool enable_guard_regions = EnableGuardRegions();
|
||||
buffer = SetupArrayBuffer(isolate, nullptr, 0, nullptr, 0, false,
|
||||
enable_guard_regions);
|
||||
}
|
||||
memory_obj->SetEmbedderField(kArrayBuffer, *buffer);
|
||||
Handle<Object> max = isolate->factory()->NewNumber(maximum);
|
||||
memory_obj->SetEmbedderField(kMaximum, *max);
|
||||
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);
|
||||
}
|
||||
|
||||
DEFINE_OBJ_ACCESSORS(WasmMemoryObject, buffer, kArrayBuffer, JSArrayBuffer)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmMemoryObject, instances_link, kInstancesLink,
|
||||
WasmInstanceWrapper)
|
||||
|
||||
uint32_t WasmMemoryObject::current_pages() {
|
||||
uint32_t byte_length;
|
||||
CHECK(buffer()->byte_length()->ToUint32(&byte_length));
|
||||
CHECK(array_buffer()->byte_length()->ToUint32(&byte_length));
|
||||
return byte_length / wasm::WasmModule::kPageSize;
|
||||
}
|
||||
|
||||
bool WasmMemoryObject::has_maximum_pages() {
|
||||
return GetEmbedderField(kMaximum)->Number() >= 0;
|
||||
}
|
||||
|
||||
int32_t WasmMemoryObject::maximum_pages() {
|
||||
return static_cast<int32_t>(GetEmbedderField(kMaximum)->Number());
|
||||
}
|
||||
|
||||
WasmMemoryObject* WasmMemoryObject::cast(Object* object) {
|
||||
DCHECK(object && object->IsJSObject());
|
||||
// TODO(titzer): brand check for WasmMemoryObject.
|
||||
return reinterpret_cast<WasmMemoryObject*>(object);
|
||||
}
|
||||
|
||||
void WasmMemoryObject::AddInstance(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance) {
|
||||
Handle<WasmInstanceWrapper> instance_wrapper =
|
||||
@ -460,16 +352,11 @@ void WasmMemoryObject::AddInstance(Isolate* isolate,
|
||||
set_instances_link(*instance_wrapper);
|
||||
}
|
||||
|
||||
void WasmMemoryObject::ResetInstancesLink(Isolate* isolate) {
|
||||
Handle<Object> undefined = isolate->factory()->undefined_value();
|
||||
SetEmbedderField(kInstancesLink, *undefined);
|
||||
}
|
||||
|
||||
// static
|
||||
int32_t WasmMemoryObject::Grow(Isolate* isolate,
|
||||
Handle<WasmMemoryObject> memory_object,
|
||||
uint32_t pages) {
|
||||
Handle<JSArrayBuffer> old_buffer(memory_object->buffer());
|
||||
Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer());
|
||||
uint32_t old_size = 0;
|
||||
CHECK(old_buffer->byte_length()->ToUint32(&old_size));
|
||||
Handle<JSArrayBuffer> new_buffer;
|
||||
@ -482,7 +369,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
|
||||
isolate, old_buffer->allocation_base(),
|
||||
old_buffer->allocation_length(), old_buffer->backing_store(),
|
||||
old_size, old_buffer->is_external(), old_buffer->has_guard_region());
|
||||
memory_object->set_buffer(*new_buffer);
|
||||
memory_object->set_array_buffer(*new_buffer);
|
||||
}
|
||||
DCHECK_EQ(0, old_size % WasmModule::kPageSize);
|
||||
return old_size / WasmModule::kPageSize;
|
||||
@ -504,7 +391,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
|
||||
DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
|
||||
DCHECK(instance_wrapper->has_instance());
|
||||
Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
|
||||
DCHECK(IsWasmInstance(*instance));
|
||||
DCHECK(instance->IsWasmInstanceObject());
|
||||
uint32_t max_pages = instance->GetMaxMemoryPages();
|
||||
|
||||
// Grow memory object buffer and update instances associated with it.
|
||||
@ -518,31 +405,16 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
|
||||
instance_wrapper = instance_wrapper->next_wrapper();
|
||||
DCHECK(WasmInstanceWrapper::IsWasmInstanceWrapper(*instance_wrapper));
|
||||
Handle<WasmInstanceObject> instance = instance_wrapper->instance_object();
|
||||
DCHECK(IsWasmInstance(*instance));
|
||||
DCHECK(instance->IsWasmInstanceObject());
|
||||
SetInstanceMemory(isolate, instance, new_buffer);
|
||||
UncheckedUpdateInstanceMemory(isolate, instance, old_mem_start, old_size);
|
||||
}
|
||||
}
|
||||
memory_object->set_buffer(*new_buffer);
|
||||
memory_object->set_array_buffer(*new_buffer);
|
||||
DCHECK_EQ(0, old_size % WasmModule::kPageSize);
|
||||
return old_size / WasmModule::kPageSize;
|
||||
}
|
||||
|
||||
DEFINE_OBJ_ACCESSORS(WasmInstanceObject, compiled_module, kCompiledModule,
|
||||
WasmCompiledModule)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, globals_buffer,
|
||||
kGlobalsArrayBuffer, JSArrayBuffer)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, memory_buffer,
|
||||
kMemoryArrayBuffer, JSArrayBuffer)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, memory_object, kMemoryObject,
|
||||
WasmMemoryObject)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, debug_info, kDebugInfo,
|
||||
WasmDebugInfo)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, instance_wrapper,
|
||||
kWasmMemInstanceWrapper, WasmInstanceWrapper)
|
||||
DEFINE_OPTIONAL_OBJ_ACCESSORS(WasmInstanceObject, directly_called_instances,
|
||||
kDirectlyCalledInstances, FixedArray)
|
||||
|
||||
WasmModuleObject* WasmInstanceObject::module_object() {
|
||||
return *compiled_module()->wasm_module();
|
||||
}
|
||||
@ -557,38 +429,12 @@ Handle<WasmDebugInfo> WasmInstanceObject::GetOrCreateDebugInfo(
|
||||
return new_info;
|
||||
}
|
||||
|
||||
WasmInstanceObject* WasmInstanceObject::cast(Object* object) {
|
||||
DCHECK(IsWasmInstanceObject(object));
|
||||
return reinterpret_cast<WasmInstanceObject*>(object);
|
||||
}
|
||||
|
||||
bool WasmInstanceObject::IsWasmInstanceObject(Object* object) {
|
||||
if (!object->IsJSObject()) return false;
|
||||
|
||||
JSObject* obj = JSObject::cast(object);
|
||||
Isolate* isolate = obj->GetIsolate();
|
||||
if (obj->GetEmbedderFieldCount() != kFieldCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Object* mem = obj->GetEmbedderField(kMemoryArrayBuffer);
|
||||
if (!(mem->IsUndefined(isolate) || mem->IsJSArrayBuffer()) ||
|
||||
!WasmCompiledModule::IsWasmCompiledModule(
|
||||
obj->GetEmbedderField(kCompiledModule))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All checks passed.
|
||||
return true;
|
||||
}
|
||||
|
||||
Handle<WasmInstanceObject> WasmInstanceObject::New(
|
||||
Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
|
||||
Handle<JSFunction> instance_cons(
|
||||
isolate->native_context()->wasm_instance_constructor());
|
||||
Handle<JSObject> instance_object =
|
||||
isolate->factory()->NewJSObject(instance_cons, TENURED);
|
||||
instance_object->SetEmbedderField(kWrapperTracerHeader, Smi::kZero);
|
||||
|
||||
Handle<Symbol> instance_sym(isolate->native_context()->wasm_instance_sym());
|
||||
Object::SetProperty(instance_object, instance_sym, instance_object, STRICT)
|
||||
@ -596,11 +442,10 @@ Handle<WasmInstanceObject> WasmInstanceObject::New(
|
||||
Handle<WasmInstanceObject> instance(
|
||||
reinterpret_cast<WasmInstanceObject*>(*instance_object), isolate);
|
||||
|
||||
instance->SetEmbedderField(kCompiledModule, *compiled_module);
|
||||
instance->SetEmbedderField(kMemoryObject, isolate->heap()->undefined_value());
|
||||
instance->set_compiled_module(*compiled_module);
|
||||
Handle<WasmInstanceWrapper> instance_wrapper =
|
||||
WasmInstanceWrapper::New(isolate, instance);
|
||||
instance->SetEmbedderField(kWasmMemInstanceWrapper, *instance_wrapper);
|
||||
instance->set_instance_wrapper(*instance_wrapper);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -656,16 +501,6 @@ uint32_t WasmInstanceObject::GetMaxMemoryPages() {
|
||||
return FLAG_wasm_max_mem_pages;
|
||||
}
|
||||
|
||||
WasmInstanceObject* WasmExportedFunction::instance() {
|
||||
return WasmInstanceObject::cast(GetEmbedderField(kInstance));
|
||||
}
|
||||
|
||||
int WasmExportedFunction::function_index() {
|
||||
int32_t func_index;
|
||||
CHECK(GetEmbedderField(kIndex)->ToInt32(&func_index));
|
||||
return func_index;
|
||||
}
|
||||
|
||||
WasmExportedFunction* WasmExportedFunction::cast(Object* object) {
|
||||
DCHECK(object && object->IsJSFunction());
|
||||
DCHECK_EQ(Code::JS_TO_WASM_FUNCTION,
|
||||
@ -694,14 +529,16 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
|
||||
isolate->factory()->NewSharedFunctionInfo(name, export_wrapper, false);
|
||||
shared->set_length(arity);
|
||||
shared->set_internal_formal_parameter_count(arity);
|
||||
Handle<JSFunction> function = isolate->factory()->NewFunction(
|
||||
Handle<JSFunction> js_function = isolate->factory()->NewFunction(
|
||||
isolate->wasm_function_map(), name, export_wrapper);
|
||||
function->SetEmbedderField(kWrapperTracerHeader, Smi::kZero);
|
||||
|
||||
Handle<WasmExportedFunction> function(
|
||||
reinterpret_cast<WasmExportedFunction*>(*js_function), isolate);
|
||||
|
||||
function->set_shared(*shared);
|
||||
function->set_instance(*instance);
|
||||
function->set_function_index(func_index);
|
||||
|
||||
function->SetEmbedderField(kInstance, *instance);
|
||||
function->SetEmbedderField(kIndex, Smi::FromInt(func_index));
|
||||
return Handle<WasmExportedFunction>::cast(function);
|
||||
}
|
||||
|
||||
@ -710,16 +547,16 @@ bool WasmSharedModuleData::IsWasmSharedModuleData(Object* object) {
|
||||
FixedArray* arr = FixedArray::cast(object);
|
||||
if (arr->length() != kFieldCount) return false;
|
||||
Isolate* isolate = arr->GetIsolate();
|
||||
if (!arr->get(kModuleWrapper)->IsForeign()) return false;
|
||||
if (!arr->get(kModuleBytes)->IsUndefined(isolate) &&
|
||||
!arr->get(kModuleBytes)->IsSeqOneByteString())
|
||||
if (!arr->get(kModuleWrapperIndex)->IsForeign()) return false;
|
||||
if (!arr->get(kModuleBytesIndex)->IsUndefined(isolate) &&
|
||||
!arr->get(kModuleBytesIndex)->IsSeqOneByteString())
|
||||
return false;
|
||||
if (!arr->get(kScript)->IsScript()) return false;
|
||||
if (!arr->get(kAsmJsOffsetTable)->IsUndefined(isolate) &&
|
||||
!arr->get(kAsmJsOffsetTable)->IsByteArray())
|
||||
if (!arr->get(kScriptIndex)->IsScript()) return false;
|
||||
if (!arr->get(kAsmJsOffsetTableIndex)->IsUndefined(isolate) &&
|
||||
!arr->get(kAsmJsOffsetTableIndex)->IsByteArray())
|
||||
return false;
|
||||
if (!arr->get(kBreakPointInfos)->IsUndefined(isolate) &&
|
||||
!arr->get(kBreakPointInfos)->IsFixedArray())
|
||||
if (!arr->get(kBreakPointInfosIndex)->IsUndefined(isolate) &&
|
||||
!arr->get(kBreakPointInfosIndex)->IsFixedArray())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -736,41 +573,34 @@ wasm::WasmModule* WasmSharedModuleData::module() {
|
||||
// a Managed<WasmModule> object, as well as cases when it's managed
|
||||
// by the embedder. CcTests fall into the latter case.
|
||||
return *(reinterpret_cast<wasm::WasmModule**>(
|
||||
Foreign::cast(get(kModuleWrapper))->foreign_address()));
|
||||
Foreign::cast(get(kModuleWrapperIndex))->foreign_address()));
|
||||
}
|
||||
|
||||
DEFINE_OPTIONAL_ARR_ACCESSORS(WasmSharedModuleData, module_bytes, kModuleBytes,
|
||||
SeqOneByteString);
|
||||
DEFINE_ARR_GETTER(WasmSharedModuleData, script, kScript, Script);
|
||||
DEFINE_OPTIONAL_ARR_ACCESSORS(WasmSharedModuleData, asm_js_offset_table,
|
||||
kAsmJsOffsetTable, ByteArray);
|
||||
DEFINE_OPTIONAL_ARR_GETTER(WasmSharedModuleData, breakpoint_infos,
|
||||
kBreakPointInfos, FixedArray);
|
||||
DEFINE_OPTIONAL_ARR_GETTER(WasmSharedModuleData, lazy_compilation_orchestrator,
|
||||
kLazyCompilationOrchestrator, Foreign);
|
||||
|
||||
Handle<WasmSharedModuleData> WasmSharedModuleData::New(
|
||||
Isolate* isolate, Handle<Foreign> module_wrapper,
|
||||
Handle<SeqOneByteString> module_bytes, Handle<Script> script,
|
||||
Handle<ByteArray> asm_js_offset_table) {
|
||||
Handle<FixedArray> arr =
|
||||
isolate->factory()->NewFixedArray(kFieldCount, TENURED);
|
||||
arr->set(kWrapperTracerHeader, Smi::kZero);
|
||||
arr->set(kModuleWrapper, *module_wrapper);
|
||||
arr->set(kModuleWrapperIndex, *module_wrapper);
|
||||
if (!module_bytes.is_null()) {
|
||||
arr->set(kModuleBytes, *module_bytes);
|
||||
arr->set(kModuleBytesIndex, *module_bytes);
|
||||
}
|
||||
if (!script.is_null()) {
|
||||
arr->set(kScript, *script);
|
||||
arr->set(kScriptIndex, *script);
|
||||
}
|
||||
if (!asm_js_offset_table.is_null()) {
|
||||
arr->set(kAsmJsOffsetTable, *asm_js_offset_table);
|
||||
arr->set(kAsmJsOffsetTableIndex, *asm_js_offset_table);
|
||||
}
|
||||
|
||||
DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*arr));
|
||||
return Handle<WasmSharedModuleData>::cast(arr);
|
||||
}
|
||||
|
||||
Foreign* WasmSharedModuleData::lazy_compilation_orchestrator() {
|
||||
return Foreign::cast(get(kLazyCompilationOrchestratorIndex));
|
||||
}
|
||||
|
||||
bool WasmSharedModuleData::is_asm_js() {
|
||||
bool asm_js = module()->is_asm_js();
|
||||
DCHECK_EQ(asm_js, script()->IsUserJavaScript());
|
||||
@ -780,7 +610,7 @@ bool WasmSharedModuleData::is_asm_js() {
|
||||
|
||||
void WasmSharedModuleData::ReinitializeAfterDeserialization(
|
||||
Isolate* isolate, Handle<WasmSharedModuleData> shared) {
|
||||
DCHECK(shared->get(kModuleWrapper)->IsUndefined(isolate));
|
||||
DCHECK(shared->get(kModuleWrapperIndex)->IsUndefined(isolate));
|
||||
#ifdef DEBUG
|
||||
// No BreakpointInfo objects should survive deserialization.
|
||||
if (shared->has_breakpoint_infos()) {
|
||||
@ -790,7 +620,7 @@ void WasmSharedModuleData::ReinitializeAfterDeserialization(
|
||||
}
|
||||
#endif
|
||||
|
||||
shared->set(kBreakPointInfos, isolate->heap()->undefined_value());
|
||||
shared->set(kBreakPointInfosIndex, isolate->heap()->undefined_value());
|
||||
|
||||
WasmModule* module = nullptr;
|
||||
{
|
||||
@ -815,7 +645,7 @@ void WasmSharedModuleData::ReinitializeAfterDeserialization(
|
||||
Handle<WasmModuleWrapper> module_wrapper =
|
||||
WasmModuleWrapper::New(isolate, module);
|
||||
|
||||
shared->set(kModuleWrapper, *module_wrapper);
|
||||
shared->set(kModuleWrapperIndex, *module_wrapper);
|
||||
DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared));
|
||||
}
|
||||
|
||||
@ -860,7 +690,7 @@ void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared,
|
||||
breakpoint_infos = handle(shared->breakpoint_infos(), isolate);
|
||||
} else {
|
||||
breakpoint_infos = isolate->factory()->NewFixedArray(4, TENURED);
|
||||
shared->set(kBreakPointInfos, *breakpoint_infos);
|
||||
shared->set(kBreakPointInfosIndex, *breakpoint_infos);
|
||||
}
|
||||
|
||||
int insert_pos =
|
||||
@ -884,7 +714,7 @@ void WasmSharedModuleData::AddBreakpoint(Handle<WasmSharedModuleData> shared,
|
||||
if (need_realloc) {
|
||||
new_breakpoint_infos = isolate->factory()->NewFixedArray(
|
||||
2 * breakpoint_infos->length(), TENURED);
|
||||
shared->set(kBreakPointInfos, *new_breakpoint_infos);
|
||||
shared->set(kBreakPointInfosIndex, *new_breakpoint_infos);
|
||||
// Copy over the entries [0, insert_pos).
|
||||
for (int i = 0; i < insert_pos; ++i)
|
||||
new_breakpoint_infos->set(i, breakpoint_infos->get(i));
|
||||
@ -946,7 +776,7 @@ void WasmSharedModuleData::PrepareForLazyCompilation(
|
||||
LazyCompilationOrchestrator* orch = new LazyCompilationOrchestrator();
|
||||
Handle<Managed<LazyCompilationOrchestrator>> orch_handle =
|
||||
Managed<LazyCompilationOrchestrator>::New(isolate, orch);
|
||||
shared->set(WasmSharedModuleData::kLazyCompilationOrchestrator, *orch_handle);
|
||||
shared->set(kLazyCompilationOrchestratorIndex, *orch_handle);
|
||||
}
|
||||
|
||||
Handle<WasmCompiledModule> WasmCompiledModule::New(
|
||||
@ -1575,28 +1405,25 @@ Handle<Code> WasmCompiledModule::CompileLazy(
|
||||
Handle<WasmInstanceWrapper> WasmInstanceWrapper::New(
|
||||
Isolate* isolate, Handle<WasmInstanceObject> instance) {
|
||||
Handle<FixedArray> array =
|
||||
isolate->factory()->NewFixedArray(kWrapperPropertyCount, TENURED);
|
||||
isolate->factory()->NewFixedArray(kFieldCount, TENURED);
|
||||
Handle<WasmInstanceWrapper> instance_wrapper(
|
||||
reinterpret_cast<WasmInstanceWrapper*>(*array), isolate);
|
||||
Handle<WeakCell> cell = isolate->factory()->NewWeakCell(instance);
|
||||
instance_wrapper->set(kWrapperInstanceObject, *cell);
|
||||
instance_wrapper->set(kWrapperInstanceObjectIndex, *cell);
|
||||
return instance_wrapper;
|
||||
}
|
||||
|
||||
bool WasmInstanceWrapper::IsWasmInstanceWrapper(Object* obj) {
|
||||
if (!obj->IsFixedArray()) return false;
|
||||
Handle<FixedArray> array = handle(FixedArray::cast(obj));
|
||||
if (array->length() != kWrapperPropertyCount) return false;
|
||||
if (!array->get(kWrapperInstanceObject)->IsWeakCell()) return false;
|
||||
if (array->length() != kFieldCount) return false;
|
||||
if (!array->get(kWrapperInstanceObjectIndex)->IsWeakCell()) return false;
|
||||
Isolate* isolate = array->GetIsolate();
|
||||
if (!array->get(kNextInstanceWrapper)->IsUndefined(isolate) &&
|
||||
!array->get(kNextInstanceWrapper)->IsFixedArray())
|
||||
if (!array->get(kNextInstanceWrapperIndex)->IsUndefined(isolate) &&
|
||||
!array->get(kNextInstanceWrapperIndex)->IsFixedArray())
|
||||
return false;
|
||||
if (!array->get(kPreviousInstanceWrapper)->IsUndefined(isolate) &&
|
||||
!array->get(kPreviousInstanceWrapper)->IsFixedArray())
|
||||
if (!array->get(kPreviousInstanceWrapperIndex)->IsUndefined(isolate) &&
|
||||
!array->get(kPreviousInstanceWrapperIndex)->IsFixedArray())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
DEFINE_OPTIONAL_ARR_ACCESSORS(WasmDebugInfo, locals_names, kLocalsNames,
|
||||
FixedArray)
|
||||
|
@ -13,6 +13,12 @@
|
||||
#include "src/wasm/wasm-limits.h"
|
||||
#include "src/wasm/wasm-module.h"
|
||||
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/heap/heap.h"
|
||||
|
||||
// Has to be the last include (doesn't have include guards)
|
||||
#include "src/objects/object-macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace wasm {
|
||||
@ -25,34 +31,42 @@ class WasmDebugInfo;
|
||||
class WasmInstanceObject;
|
||||
class WasmInstanceWrapper;
|
||||
|
||||
#define DECLARE_CASTS(name) \
|
||||
static bool Is##name(Object* object); \
|
||||
static name* cast(Object* object)
|
||||
#define DECL_OOL_QUERY(type) static bool Is##type(Object* object);
|
||||
#define DECL_OOL_CAST(type) static type* cast(Object* object);
|
||||
|
||||
#define DECLARE_GETTER(name, type) type* name()
|
||||
#define DECL_GETTER(name, type) type* name();
|
||||
|
||||
#define DECLARE_ACCESSORS(name, type) \
|
||||
void set_##name(type* value); \
|
||||
DECLARE_GETTER(name, type)
|
||||
#define DECL_OPTIONAL_ACCESSORS(name, type) \
|
||||
INLINE(bool has_##name()); \
|
||||
DECL_ACCESSORS(name, type)
|
||||
|
||||
#define DECLARE_OPTIONAL_ACCESSORS(name, type) \
|
||||
bool has_##name(); \
|
||||
DECLARE_ACCESSORS(name, type)
|
||||
#define DECL_OPTIONAL_GETTER(name, type) \
|
||||
INLINE(bool has_##name()); \
|
||||
DECL_GETTER(name, type)
|
||||
|
||||
#define DECLARE_OPTIONAL_GETTER(name, type) \
|
||||
bool has_##name(); \
|
||||
DECLARE_GETTER(name, type)
|
||||
#define DEF_SIZE(parent) \
|
||||
static const int kSize = parent::kHeaderSize + kFieldCount * kPointerSize; \
|
||||
static const int kParentSize = parent::kHeaderSize; \
|
||||
static const int kHeaderSize = kSize;
|
||||
#define DEF_OFFSET(name) \
|
||||
static const int k##name##Offset = \
|
||||
kSize + (k##name##Index - kFieldCount) * kPointerSize;
|
||||
|
||||
// Representation of a WebAssembly.Module JavaScript-level object.
|
||||
class WasmModuleObject : public JSObject {
|
||||
public:
|
||||
// If a second field is added, we need a kWrapperTracerHeader field as well.
|
||||
// TODO(titzer): add the brand as an embedder field instead of a property.
|
||||
enum Fields { kCompiledModule, kFieldCount };
|
||||
DECL_CAST(WasmModuleObject)
|
||||
|
||||
DECLARE_CASTS(WasmModuleObject);
|
||||
// Shared compiled code between multiple WebAssembly.Module objects.
|
||||
DECL_ACCESSORS(compiled_module, WasmCompiledModule)
|
||||
|
||||
WasmCompiledModule* compiled_module();
|
||||
enum { // --
|
||||
kCompiledModuleIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
DEF_SIZE(JSObject)
|
||||
DEF_OFFSET(CompiledModule)
|
||||
|
||||
static Handle<WasmModuleObject> New(
|
||||
Isolate* isolate, Handle<WasmCompiledModule> compiled_module);
|
||||
@ -61,23 +75,26 @@ class WasmModuleObject : public JSObject {
|
||||
// Representation of a WebAssembly.Table JavaScript-level object.
|
||||
class WasmTableObject : public JSObject {
|
||||
public:
|
||||
// The 0-th field is used by the Blink Wrapper Tracer.
|
||||
// TODO(titzer): add the brand as an embedder field instead of a property.
|
||||
enum Fields {
|
||||
kWrapperTracerHeader,
|
||||
kFunctions,
|
||||
kMaximum,
|
||||
kDispatchTables,
|
||||
DECL_CAST(WasmTableObject)
|
||||
|
||||
DECL_ACCESSORS(functions, FixedArray)
|
||||
DECL_INT_ACCESSORS(maximum_length)
|
||||
DECL_ACCESSORS(dispatch_tables, FixedArray)
|
||||
|
||||
enum { // --
|
||||
kFunctionsIndex,
|
||||
kMaximumLengthIndex,
|
||||
kDispatchTablesIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
DECLARE_CASTS(WasmTableObject);
|
||||
DECLARE_ACCESSORS(functions, FixedArray);
|
||||
DECLARE_GETTER(dispatch_tables, FixedArray);
|
||||
DEF_SIZE(JSObject)
|
||||
DEF_OFFSET(Functions)
|
||||
DEF_OFFSET(MaximumLength)
|
||||
DEF_OFFSET(DispatchTables)
|
||||
|
||||
uint32_t current_length();
|
||||
bool has_maximum_length();
|
||||
int64_t maximum_length(); // Returns < 0 if no maximum.
|
||||
inline uint32_t current_length() { return functions()->length(); }
|
||||
inline bool has_maximum_length() { return maximum_length() >= 0; }
|
||||
void grow(Isolate* isolate, uint32_t count);
|
||||
|
||||
static Handle<WasmTableObject> New(Isolate* isolate, uint32_t initial,
|
||||
@ -92,25 +109,28 @@ class WasmTableObject : public JSObject {
|
||||
// Representation of a WebAssembly.Memory JavaScript-level object.
|
||||
class WasmMemoryObject : public JSObject {
|
||||
public:
|
||||
// The 0-th field is used by the Blink Wrapper Tracer.
|
||||
// TODO(titzer): add the brand as an embedder field instead of a property.
|
||||
enum Fields : uint8_t {
|
||||
kWrapperTracerHeader,
|
||||
kArrayBuffer,
|
||||
kMaximum,
|
||||
kInstancesLink,
|
||||
DECL_CAST(WasmMemoryObject)
|
||||
|
||||
DECL_ACCESSORS(array_buffer, JSArrayBuffer)
|
||||
DECL_INT_ACCESSORS(maximum_pages)
|
||||
DECL_OPTIONAL_ACCESSORS(instances_link, WasmInstanceWrapper)
|
||||
|
||||
enum { // --
|
||||
kArrayBufferIndex,
|
||||
kMaximumPagesIndex,
|
||||
kInstancesLinkIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
DECLARE_CASTS(WasmMemoryObject);
|
||||
DECLARE_ACCESSORS(buffer, JSArrayBuffer);
|
||||
DECLARE_OPTIONAL_ACCESSORS(instances_link, WasmInstanceWrapper);
|
||||
DEF_SIZE(JSObject)
|
||||
DEF_OFFSET(ArrayBuffer)
|
||||
DEF_OFFSET(MaximumPages)
|
||||
DEF_OFFSET(InstancesLink)
|
||||
|
||||
void AddInstance(Isolate* isolate, Handle<WasmInstanceObject> object);
|
||||
void ResetInstancesLink(Isolate* isolate);
|
||||
inline void ResetInstancesLink(Isolate* isolate);
|
||||
uint32_t current_pages();
|
||||
bool has_maximum_pages();
|
||||
int32_t maximum_pages(); // Returns < 0 if there is no maximum.
|
||||
inline bool has_maximum_pages() { return maximum_pages() >= 0; }
|
||||
|
||||
static Handle<WasmMemoryObject> New(Isolate* isolate,
|
||||
Handle<JSArrayBuffer> buffer,
|
||||
@ -119,33 +139,39 @@ class WasmMemoryObject : public JSObject {
|
||||
static int32_t Grow(Isolate*, Handle<WasmMemoryObject>, uint32_t pages);
|
||||
};
|
||||
|
||||
// Representation of a WebAssembly.Instance JavaScript-level object.
|
||||
// A WebAssembly.Instance JavaScript-level object.
|
||||
class WasmInstanceObject : public JSObject {
|
||||
public:
|
||||
// The 0-th field is used by the Blink Wrapper Tracer.
|
||||
// TODO(titzer): add the brand as an embedder field instead of a property.
|
||||
enum Fields {
|
||||
kWrapperTracerHeader,
|
||||
kCompiledModule,
|
||||
kMemoryObject,
|
||||
kMemoryArrayBuffer,
|
||||
kGlobalsArrayBuffer,
|
||||
kDebugInfo,
|
||||
kWasmMemInstanceWrapper,
|
||||
// FixedArray of wasm instances whose code we imported (to keep them alive).
|
||||
kDirectlyCalledInstances,
|
||||
DECL_CAST(WasmInstanceObject)
|
||||
|
||||
DECL_ACCESSORS(compiled_module, WasmCompiledModule)
|
||||
DECL_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject)
|
||||
DECL_OPTIONAL_ACCESSORS(memory_buffer, JSArrayBuffer)
|
||||
DECL_OPTIONAL_ACCESSORS(globals_buffer, JSArrayBuffer)
|
||||
DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo)
|
||||
DECL_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper)
|
||||
// FixedArray of all instances whose code was imported
|
||||
DECL_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray)
|
||||
|
||||
enum { // --
|
||||
kCompiledModuleIndex,
|
||||
kMemoryObjectIndex,
|
||||
kMemoryBufferIndex,
|
||||
kGlobalsBufferIndex,
|
||||
kDebugInfoIndex,
|
||||
kInstanceWrapperIndex,
|
||||
kDirectlyCalledInstancesIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
DECLARE_CASTS(WasmInstanceObject);
|
||||
|
||||
DECLARE_ACCESSORS(compiled_module, WasmCompiledModule);
|
||||
DECLARE_OPTIONAL_ACCESSORS(globals_buffer, JSArrayBuffer);
|
||||
DECLARE_OPTIONAL_ACCESSORS(memory_buffer, JSArrayBuffer);
|
||||
DECLARE_OPTIONAL_ACCESSORS(memory_object, WasmMemoryObject);
|
||||
DECLARE_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo);
|
||||
DECLARE_OPTIONAL_ACCESSORS(instance_wrapper, WasmInstanceWrapper);
|
||||
DECLARE_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray);
|
||||
DEF_SIZE(JSObject)
|
||||
DEF_OFFSET(CompiledModule)
|
||||
DEF_OFFSET(MemoryObject)
|
||||
DEF_OFFSET(MemoryBuffer)
|
||||
DEF_OFFSET(GlobalsBuffer)
|
||||
DEF_OFFSET(DebugInfo)
|
||||
DEF_OFFSET(InstanceWrapper)
|
||||
DEF_OFFSET(DirectlyCalledInstances)
|
||||
|
||||
WasmModuleObject* module_object();
|
||||
V8_EXPORT_PRIVATE wasm::WasmModule* module();
|
||||
@ -164,16 +190,24 @@ class WasmInstanceObject : public JSObject {
|
||||
uint32_t GetMaxMemoryPages();
|
||||
};
|
||||
|
||||
// Representation of an exported wasm function.
|
||||
// A WASM function that is wrapped and exported to JavaScript.
|
||||
class WasmExportedFunction : public JSFunction {
|
||||
public:
|
||||
// The 0-th field is used by the Blink Wrapper Tracer.
|
||||
enum Fields { kWrapperTracerHeader, kInstance, kIndex, kFieldCount };
|
||||
DECL_OOL_QUERY(WasmExportedFunction)
|
||||
DECL_OOL_CAST(WasmExportedFunction)
|
||||
|
||||
DECLARE_CASTS(WasmExportedFunction);
|
||||
DECL_ACCESSORS(instance, WasmInstanceObject)
|
||||
DECL_INT_ACCESSORS(function_index)
|
||||
|
||||
WasmInstanceObject* instance();
|
||||
int function_index();
|
||||
enum { // --
|
||||
kInstanceIndex,
|
||||
kFunctionIndexIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
static const int kSize = JSFunction::kSize + kFieldCount * kPointerSize;
|
||||
DEF_OFFSET(Instance)
|
||||
DEF_OFFSET(FunctionIndex)
|
||||
|
||||
static Handle<WasmExportedFunction> New(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance,
|
||||
@ -184,31 +218,33 @@ class WasmExportedFunction : public JSFunction {
|
||||
|
||||
// Information shared by all WasmCompiledModule objects for the same module.
|
||||
class WasmSharedModuleData : public FixedArray {
|
||||
// The 0-th field is used by the Blink Wrapper Tracer.
|
||||
enum Fields {
|
||||
kWrapperTracerHeader,
|
||||
kModuleWrapper,
|
||||
kModuleBytes,
|
||||
kScript,
|
||||
kAsmJsOffsetTable,
|
||||
kBreakPointInfos,
|
||||
kLazyCompilationOrchestrator,
|
||||
public:
|
||||
DECL_OOL_QUERY(WasmSharedModuleData)
|
||||
DECL_OOL_CAST(WasmSharedModuleData)
|
||||
|
||||
DECL_GETTER(module, wasm::WasmModule)
|
||||
DECL_OPTIONAL_ACCESSORS(module_bytes, SeqOneByteString)
|
||||
DECL_ACCESSORS(script, Script)
|
||||
DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray)
|
||||
DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray)
|
||||
|
||||
enum { // --
|
||||
kModuleWrapperIndex,
|
||||
kModuleBytesIndex,
|
||||
kScriptIndex,
|
||||
kAsmJsOffsetTableIndex,
|
||||
kBreakPointInfosIndex,
|
||||
kLazyCompilationOrchestratorIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
public:
|
||||
DECLARE_CASTS(WasmSharedModuleData);
|
||||
|
||||
DECLARE_GETTER(module, wasm::WasmModule);
|
||||
DECLARE_OPTIONAL_ACCESSORS(module_bytes, SeqOneByteString);
|
||||
DECLARE_GETTER(script, Script);
|
||||
DECLARE_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray);
|
||||
DECLARE_OPTIONAL_GETTER(breakpoint_infos, FixedArray);
|
||||
|
||||
static Handle<WasmSharedModuleData> New(
|
||||
Isolate* isolate, Handle<Foreign> module_wrapper,
|
||||
Handle<SeqOneByteString> module_bytes, Handle<Script> script,
|
||||
Handle<ByteArray> asm_js_offset_table);
|
||||
DEF_SIZE(FixedArray)
|
||||
DEF_OFFSET(ModuleWrapper)
|
||||
DEF_OFFSET(ModuleBytes)
|
||||
DEF_OFFSET(Script)
|
||||
DEF_OFFSET(AsmJsOffsetTable)
|
||||
DEF_OFFSET(BreakPointInfos)
|
||||
DEF_OFFSET(LazyCompilationOrchestrator)
|
||||
|
||||
// Check whether this module was generated from asm.js source.
|
||||
bool is_asm_js();
|
||||
@ -224,8 +260,13 @@ class WasmSharedModuleData : public FixedArray {
|
||||
|
||||
static void PrepareForLazyCompilation(Handle<WasmSharedModuleData>);
|
||||
|
||||
static Handle<WasmSharedModuleData> New(
|
||||
Isolate* isolate, Handle<Foreign> module_wrapper,
|
||||
Handle<SeqOneByteString> module_bytes, Handle<Script> script,
|
||||
Handle<ByteArray> asm_js_offset_table);
|
||||
|
||||
private:
|
||||
DECLARE_OPTIONAL_GETTER(lazy_compilation_orchestrator, Foreign);
|
||||
DECL_OPTIONAL_GETTER(lazy_compilation_orchestrator, Foreign)
|
||||
friend class WasmCompiledModule;
|
||||
};
|
||||
|
||||
@ -255,7 +296,9 @@ class WasmSharedModuleData : public FixedArray {
|
||||
// we embed them as objects, and they may move.
|
||||
class WasmCompiledModule : public FixedArray {
|
||||
public:
|
||||
enum Fields { kFieldCount };
|
||||
enum { // --
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
static WasmCompiledModule* cast(Object* fixed_array) {
|
||||
SLOW_DCHECK(IsWasmCompiledModule(fixed_array));
|
||||
@ -544,18 +587,25 @@ class WasmCompiledModule : public FixedArray {
|
||||
|
||||
class WasmDebugInfo : public FixedArray {
|
||||
public:
|
||||
// The 0-th field is used by the Blink Wrapper Tracer.
|
||||
enum Fields {
|
||||
kWrapperTracerHeader,
|
||||
kInstance,
|
||||
kInterpreterHandle,
|
||||
kInterpretedFunctions,
|
||||
// FixedArray of FixedArray of <undefined|String>.
|
||||
kLocalsNames,
|
||||
DECL_OOL_QUERY(WasmDebugInfo)
|
||||
DECL_OOL_CAST(WasmDebugInfo)
|
||||
|
||||
DECL_GETTER(wasm_instance, WasmInstanceObject)
|
||||
DECL_OPTIONAL_ACCESSORS(locals_names, FixedArray)
|
||||
|
||||
enum { // --
|
||||
kInstanceIndex,
|
||||
kInterpreterHandleIndex,
|
||||
kInterpretedFunctionsIndex,
|
||||
kLocalsNamesIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
DECLARE_OPTIONAL_ACCESSORS(locals_names, FixedArray);
|
||||
DEF_SIZE(FixedArray)
|
||||
DEF_OFFSET(Instance)
|
||||
DEF_OFFSET(InterpreterHandle)
|
||||
DEF_OFFSET(InterpretedFunctions)
|
||||
DEF_OFFSET(LocalsNames)
|
||||
|
||||
static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>);
|
||||
|
||||
@ -566,9 +616,6 @@ class WasmDebugInfo : public FixedArray {
|
||||
V8_EXPORT_PRIVATE static wasm::WasmInterpreter* SetupForTesting(
|
||||
Handle<WasmInstanceObject>, wasm::WasmInstance*);
|
||||
|
||||
static bool IsDebugInfo(Object*);
|
||||
static WasmDebugInfo* cast(Object*);
|
||||
|
||||
// Set a breakpoint in the given function at the given byte offset within that
|
||||
// function. This will redirect all future calls to this function to the
|
||||
// interpreter and will always pause at the given offset.
|
||||
@ -605,8 +652,6 @@ class WasmDebugInfo : public FixedArray {
|
||||
// Returns the number of calls / function frames executed in the interpreter.
|
||||
uint64_t NumInterpretedCalls();
|
||||
|
||||
DECLARE_GETTER(wasm_instance, WasmInstanceObject);
|
||||
|
||||
// Update the memory view of the interpreter after executing GrowMemory in
|
||||
// compiled code.
|
||||
void UpdateMemory(JSArrayBuffer* new_memory);
|
||||
@ -625,63 +670,145 @@ class WasmDebugInfo : public FixedArray {
|
||||
|
||||
class WasmInstanceWrapper : public FixedArray {
|
||||
public:
|
||||
static Handle<WasmInstanceWrapper> New(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance);
|
||||
enum { // --
|
||||
kWrapperInstanceObjectIndex,
|
||||
kNextInstanceWrapperIndex,
|
||||
kPreviousInstanceWrapperIndex,
|
||||
kFieldCount
|
||||
};
|
||||
|
||||
static WasmInstanceWrapper* cast(Object* fixed_array) {
|
||||
SLOW_DCHECK(IsWasmInstanceWrapper(fixed_array));
|
||||
return reinterpret_cast<WasmInstanceWrapper*>(fixed_array);
|
||||
}
|
||||
static bool IsWasmInstanceWrapper(Object* obj);
|
||||
bool has_instance() { return get(kWrapperInstanceObject)->IsWeakCell(); }
|
||||
bool has_instance() { return get(kWrapperInstanceObjectIndex)->IsWeakCell(); }
|
||||
Handle<WasmInstanceObject> instance_object() {
|
||||
Object* obj = get(kWrapperInstanceObject);
|
||||
Object* obj = get(kWrapperInstanceObjectIndex);
|
||||
DCHECK(obj->IsWeakCell());
|
||||
WeakCell* cell = WeakCell::cast(obj);
|
||||
DCHECK(cell->value()->IsJSObject());
|
||||
return handle(WasmInstanceObject::cast(cell->value()));
|
||||
}
|
||||
bool has_next() { return IsWasmInstanceWrapper(get(kNextInstanceWrapper)); }
|
||||
bool has_next() {
|
||||
return IsWasmInstanceWrapper(get(kNextInstanceWrapperIndex));
|
||||
}
|
||||
bool has_previous() {
|
||||
return IsWasmInstanceWrapper(get(kPreviousInstanceWrapper));
|
||||
return IsWasmInstanceWrapper(get(kPreviousInstanceWrapperIndex));
|
||||
}
|
||||
void set_next_wrapper(Object* obj) {
|
||||
DCHECK(IsWasmInstanceWrapper(obj));
|
||||
set(kNextInstanceWrapper, obj);
|
||||
set(kNextInstanceWrapperIndex, obj);
|
||||
}
|
||||
void set_previous_wrapper(Object* obj) {
|
||||
DCHECK(IsWasmInstanceWrapper(obj));
|
||||
set(kPreviousInstanceWrapper, obj);
|
||||
set(kPreviousInstanceWrapperIndex, obj);
|
||||
}
|
||||
Handle<WasmInstanceWrapper> next_wrapper() {
|
||||
Object* obj = get(kNextInstanceWrapper);
|
||||
Object* obj = get(kNextInstanceWrapperIndex);
|
||||
DCHECK(IsWasmInstanceWrapper(obj));
|
||||
return handle(WasmInstanceWrapper::cast(obj));
|
||||
}
|
||||
Handle<WasmInstanceWrapper> previous_wrapper() {
|
||||
Object* obj = get(kPreviousInstanceWrapper);
|
||||
Object* obj = get(kPreviousInstanceWrapperIndex);
|
||||
DCHECK(IsWasmInstanceWrapper(obj));
|
||||
return handle(WasmInstanceWrapper::cast(obj));
|
||||
}
|
||||
void reset_next_wrapper() { set_undefined(kNextInstanceWrapper); }
|
||||
void reset_previous_wrapper() { set_undefined(kPreviousInstanceWrapper); }
|
||||
void reset_next_wrapper() { set_undefined(kNextInstanceWrapperIndex); }
|
||||
void reset_previous_wrapper() {
|
||||
set_undefined(kPreviousInstanceWrapperIndex);
|
||||
}
|
||||
void reset() {
|
||||
for (int kID = 0; kID < kWrapperPropertyCount; kID++) set_undefined(kID);
|
||||
for (int kID = 0; kID < kFieldCount; kID++) set_undefined(kID);
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
kWrapperInstanceObject,
|
||||
kNextInstanceWrapper,
|
||||
kPreviousInstanceWrapper,
|
||||
kWrapperPropertyCount
|
||||
};
|
||||
static Handle<WasmInstanceWrapper> New(Isolate* isolate,
|
||||
Handle<WasmInstanceObject> instance);
|
||||
};
|
||||
|
||||
#undef DECLARE_CASTS
|
||||
#undef DECLARE_GETTER
|
||||
#undef DECLARE_ACCESSORS
|
||||
#undef DECLARE_OPTIONAL_ACCESSORS
|
||||
#undef DECLARE_OPTIONAL_GETTER
|
||||
// TODO(titzer): these should be moved to wasm-objects-inl.h
|
||||
CAST_ACCESSOR(WasmInstanceObject)
|
||||
CAST_ACCESSOR(WasmMemoryObject)
|
||||
CAST_ACCESSOR(WasmModuleObject)
|
||||
CAST_ACCESSOR(WasmTableObject)
|
||||
|
||||
// WasmModuleObject
|
||||
ACCESSORS(WasmModuleObject, compiled_module, WasmCompiledModule,
|
||||
kCompiledModuleOffset)
|
||||
|
||||
// WasmTableObject
|
||||
ACCESSORS(WasmTableObject, functions, FixedArray, kFunctionsOffset)
|
||||
SMI_ACCESSORS(WasmTableObject, maximum_length, kMaximumLengthOffset)
|
||||
ACCESSORS(WasmTableObject, dispatch_tables, FixedArray, kDispatchTablesOffset)
|
||||
|
||||
// WasmMemoryObject
|
||||
ACCESSORS(WasmMemoryObject, array_buffer, JSArrayBuffer, kArrayBufferOffset)
|
||||
SMI_ACCESSORS(WasmMemoryObject, maximum_pages, kMaximumPagesOffset)
|
||||
ACCESSORS(WasmMemoryObject, instances_link, WasmInstanceWrapper,
|
||||
kInstancesLinkOffset)
|
||||
|
||||
// WasmInstanceObject
|
||||
ACCESSORS(WasmInstanceObject, compiled_module, WasmCompiledModule,
|
||||
kCompiledModuleOffset)
|
||||
ACCESSORS(WasmInstanceObject, memory_object, WasmMemoryObject,
|
||||
kMemoryObjectOffset)
|
||||
ACCESSORS(WasmInstanceObject, memory_buffer, JSArrayBuffer, kMemoryBufferOffset)
|
||||
ACCESSORS(WasmInstanceObject, globals_buffer, JSArrayBuffer,
|
||||
kGlobalsBufferOffset)
|
||||
ACCESSORS(WasmInstanceObject, debug_info, WasmDebugInfo, kDebugInfoOffset)
|
||||
ACCESSORS(WasmInstanceObject, instance_wrapper, WasmInstanceWrapper,
|
||||
kInstanceWrapperOffset)
|
||||
ACCESSORS(WasmInstanceObject, directly_called_instances, FixedArray,
|
||||
kDirectlyCalledInstancesOffset)
|
||||
|
||||
// WasmExportedFunction
|
||||
ACCESSORS(WasmExportedFunction, instance, WasmInstanceObject, kInstanceOffset)
|
||||
SMI_ACCESSORS(WasmExportedFunction, function_index, kFunctionIndexOffset)
|
||||
|
||||
// WasmSharedModuleData
|
||||
ACCESSORS(WasmSharedModuleData, module_bytes, SeqOneByteString,
|
||||
kModuleBytesOffset)
|
||||
ACCESSORS(WasmSharedModuleData, script, Script, kScriptOffset)
|
||||
ACCESSORS(WasmSharedModuleData, asm_js_offset_table, ByteArray,
|
||||
kAsmJsOffsetTableOffset)
|
||||
ACCESSORS(WasmSharedModuleData, breakpoint_infos, FixedArray,
|
||||
kBreakPointInfosOffset)
|
||||
|
||||
#define OPTIONAL_ACCESSOR(holder, name, offset) \
|
||||
bool holder::has_##name() { \
|
||||
return !READ_FIELD(this, offset)->IsUndefined(GetIsolate()); \
|
||||
}
|
||||
|
||||
OPTIONAL_ACCESSOR(WasmInstanceObject, debug_info, kDebugInfoOffset)
|
||||
OPTIONAL_ACCESSOR(WasmInstanceObject, memory_buffer, kMemoryBufferOffset)
|
||||
OPTIONAL_ACCESSOR(WasmInstanceObject, memory_object, kMemoryObjectOffset)
|
||||
OPTIONAL_ACCESSOR(WasmInstanceObject, instance_wrapper, kInstanceWrapperOffset)
|
||||
|
||||
OPTIONAL_ACCESSOR(WasmMemoryObject, instances_link, kInstancesLinkOffset)
|
||||
|
||||
OPTIONAL_ACCESSOR(WasmSharedModuleData, breakpoint_infos,
|
||||
kBreakPointInfosOffset)
|
||||
OPTIONAL_ACCESSOR(WasmSharedModuleData, asm_js_offset_table,
|
||||
kAsmJsOffsetTableOffset)
|
||||
OPTIONAL_ACCESSOR(WasmSharedModuleData, lazy_compilation_orchestrator,
|
||||
kLazyCompilationOrchestratorOffset)
|
||||
|
||||
ACCESSORS(WasmDebugInfo, locals_names, FixedArray, kLocalsNamesOffset)
|
||||
|
||||
OPTIONAL_ACCESSOR(WasmDebugInfo, locals_names, kLocalsNamesOffset)
|
||||
|
||||
inline void WasmMemoryObject::ResetInstancesLink(Isolate* isolate) {
|
||||
// This has to be a raw access to bypass typechecking.
|
||||
WRITE_FIELD(this, kInstancesLinkOffset, isolate->heap()->undefined_value());
|
||||
}
|
||||
|
||||
#undef DECL_OOL_QUERY
|
||||
#undef DECL_OOL_CAST
|
||||
#undef DECL_GETTER
|
||||
#undef DECL_OPTIONAL_ACCESSORS
|
||||
#undef DECL_OPTIONAL_GETTER
|
||||
|
||||
#include "src/objects/object-macros-undef.h"
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -272,9 +272,8 @@ class WasmSerializationTest {
|
||||
v8::Utils::OpenHandle(*deserialized_module));
|
||||
{
|
||||
DisallowHeapAllocation assume_no_gc;
|
||||
Handle<WasmCompiledModule> compiled_part(
|
||||
WasmCompiledModule::cast(module_object->GetEmbedderField(0)),
|
||||
current_isolate());
|
||||
Handle<WasmCompiledModule> compiled_part(module_object->compiled_module(),
|
||||
current_isolate());
|
||||
CHECK_EQ(memcmp(compiled_part->module_bytes()->GetCharsAddress(),
|
||||
wire_bytes().first, wire_bytes().second),
|
||||
0);
|
||||
@ -1109,7 +1108,7 @@ TEST(Run_WasmModule_Buffer_Externalized_GrowMem) {
|
||||
const bool free_memory = true;
|
||||
wasm::DetachWebAssemblyMemoryBuffer(isolate, memory, free_memory);
|
||||
CHECK_EQ(16, result);
|
||||
memory = handle(mem_obj->buffer());
|
||||
memory = handle(mem_obj->array_buffer());
|
||||
instance->set_memory_buffer(*memory);
|
||||
// Externalize should make no difference without the JS API as in this case
|
||||
// the buffer is not detached.
|
||||
|
@ -148,8 +148,12 @@ INSTANCE_TYPES = {
|
||||
244: "JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
245: "JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
246: "JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE",
|
||||
247: "JS_BOUND_FUNCTION_TYPE",
|
||||
248: "JS_FUNCTION_TYPE",
|
||||
247: "WASM_INSTANCE_TYPE",
|
||||
248: "WASM_MEMORY_TYPE",
|
||||
249: "WASM_MODULE_TYPE",
|
||||
250: "WASM_TABLE_TYPE",
|
||||
251: "JS_BOUND_FUNCTION_TYPE",
|
||||
252: "JS_FUNCTION_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
|
Loading…
Reference in New Issue
Block a user