v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
wasm-subtyping.h
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_WASM_WASM_SUBTYPING_H_
6#define V8_WASM_WASM_SUBTYPING_H_
7
8#if !V8_ENABLE_WEBASSEMBLY
9#error This header should only be included if WebAssembly is enabled.
10#endif // !V8_ENABLE_WEBASSEMBLY
11
12#include "src/wasm/value-type.h"
13
14namespace v8::internal::wasm {
15
16struct WasmModule;
17
19 ValueType subtype, ValueType supertype, const WasmModule* sub_module,
20 const WasmModule* super_module);
22 HeapType sub_heap, HeapType super_heap, const WasmModule* sub_module,
23 const WasmModule* super_module);
25 CanonicalValueType subtype, CanonicalValueType supertype);
26
27// Checks if type1, defined in module1, is equivalent with type2, defined in
28// module2.
29// Type equivalence (~) is described by the following rules:
30// - Two numeric or generic types are equivalent iff they are equal.
31// - Two indexed heap types are equivalent iff they are iso-recursively
32// equivalent (aka their canonicalized indices are equal).
34 ValueType type2,
35 const WasmModule* module1,
36 const WasmModule* module2);
37
38// Checks if {subtype}, defined in {module1}, is a subtype of {supertype},
39// defined in {module2}.
40// Subtyping between value types is described by the following rules
41// (structural subtyping):
42// - numeric types are subtype-related iff they are equal.
43// - (ref null ht1) <: (ref null ht2) iff ht1 <: ht2.
44// - (ref ht1) <: (ref null? ht2) iff ht1 <: ht2.
45// - rtt1 <: rtt2 iff rtt1 ~ rtt2.
46// For heap types, the following subtyping rules hold:
47// - The abstract heap types form the following type hierarchies:
48//
49// any func extern
50// / \ | |
51// eq \ nofunc noextern
52// / | \ \
53// i31 array struct string
54// \___|______|_____/
55// |
56// none
57//
58// - All functions are subtypes of func.
59// - All structs are subtypes of struct.
60// - All arrays are subtypes of array.
61// - An indexed heap type h1 is a subtype of indexed heap type h2 if h2 is
62// transitively an explicit canonical supertype of h1.
63// Note that {any} includes references introduced by the host which belong to
64// none of any's subtypes (e.g. JS objects).
65V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
66 const WasmModule* sub_module,
67 const WasmModule* super_module) {
68 if (subtype == supertype && sub_module == super_module) return true;
69 return IsSubtypeOfImpl(subtype, supertype, sub_module, super_module);
70}
71
72// Checks if {subtype} is a subtype of {supertype} (both defined in {module}).
73// TODO(369369573): Make sure this overload is not misused.
74V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
75 const WasmModule* module) {
76 // If the types are trivially identical, exit early.
77 if (V8_LIKELY(subtype == supertype)) return true;
78 return IsSubtypeOfImpl(subtype, supertype, module, module);
79}
80
82 CanonicalValueType supertype) {
83 if (subtype == supertype) return true;
84 return IsSubtypeOfImpl(subtype, supertype);
85}
86
88 const WasmModule* module1,
89 const WasmModule* module2) {
90 return !IsSubtypeOf(type1, type2, module1, module2) &&
91 !IsSubtypeOf(type2, type1, module2, module1);
92}
93
95 const WasmModule* sub_module,
96 const WasmModule* super_module) {
97 if (subtype == supertype && sub_module == super_module) return true;
98 return IsSubtypeOfImpl(subtype, supertype, sub_module, super_module);
99}
100
101// Checks if {subtype} is a subtype of {supertype} (both defined in {module}).
103 const WasmModule* module) {
104 // If the types are trivially identical, exit early.
105 if (V8_LIKELY(subtype == supertype)) return true;
106 return IsSubtypeOfImpl(subtype, supertype, module, module);
107}
108
110 const WasmModule* module1,
111 const WasmModule* module2) {
112 return !IsHeapSubtypeOf(heap1, heap2, module1, module2) &&
113 !IsHeapSubtypeOf(heap2, heap1, module2, module1);
114}
115
116// Checks whether {subtype_index} is valid as a declared subtype of
117// {supertype_index}.
118// - Both type must be of the same kind (function, struct, or array).
119// - Both type must have the same {is_shared} flag.
120// - Structs: Subtype must have at least as many fields as supertype,
121// covariance for respective immutable fields, equivalence for respective
122// mutable fields.
123// - Arrays: subtyping of respective element types for immutable arrays,
124// equivalence of element types for mutable arrays.
125// - Functions: equal number of parameter and return types. Contravariance for
126// respective parameter types, covariance for respective return types.
127V8_EXPORT_PRIVATE bool ValidSubtypeDefinition(ModuleTypeIndex subtype_index,
128 ModuleTypeIndex supertype_index,
129 const WasmModule* sub_module,
130 const WasmModule* super_module);
131
132// TODO(jkummerow): Deprecated, just inline it everywhere.
134 const WasmModule* module) {
135 return type.is_shared();
136}
137
141
143 : type(type), module(module) {}
144
146
147 bool operator==(const TypeInModule& other) const {
148 return type == other.type && module == other.module;
149 }
150};
151
152inline std::ostream& operator<<(std::ostream& oss, TypeInModule type) {
153 return oss << type.type.name() << "@"
154 << reinterpret_cast<intptr_t>(type.module);
155}
156
157// Returns the common ancestor of {type1} and {type2}. Returns kTop if they
158// don't have a common ancestor.
159V8_EXPORT_PRIVATE TypeInModule Union(ValueType type1, ValueType type2,
160 const WasmModule* module1,
161 const WasmModule* module2);
162
164 TypeInModule type2) {
165 return Union(type1.type, type2.type, type1.module, type2.module);
166}
167
168V8_EXPORT_PRIVATE TypeInModule Intersection(ValueType type1, ValueType type2,
169 const WasmModule* module1,
170 const WasmModule* module2);
171
173 TypeInModule type2) {
174 return Intersection(type1.type, type2.type, type1.module, type2.module);
175}
176
177// Returns the matching abstract null type (none, nofunc, noextern).
178ValueType ToNullSentinel(TypeInModule type);
179
180// Returns if two types share the same type hierarchy (any, extern, funcref).
181bool IsSameTypeHierarchy(HeapType type1, HeapType type2,
182 const WasmModule* module);
183
184} // namespace v8::internal::wasm
185
186#endif // V8_WASM_WASM_SUBTYPING_H_
ValueType ToNullSentinel(TypeInModule type)
V8_EXPORT_PRIVATE bool IsShared(ValueType type, const WasmModule *module)
bool IsSameTypeHierarchy(HeapType type1, HeapType type2, const WasmModule *module)
V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(HeapType subtype, HeapType supertype, const WasmModule *sub_module, const WasmModule *super_module)
V8_NOINLINE bool EquivalentTypes(ValueType type1, ValueType type2, const WasmModule *module1, const WasmModule *module2)
V8_INLINE bool IsHeapSubtypeOf(HeapType subtype, HeapType supertype, const WasmModule *sub_module, const WasmModule *super_module)
TypeInModule Intersection(ValueType type1, ValueType type2, const WasmModule *module1, const WasmModule *module2)
V8_EXPORT_PRIVATE TypeInModule Union(ValueType type1, ValueType type2, const WasmModule *module1, const WasmModule *module2)
bool ValidSubtypeDefinition(ModuleTypeIndex subtype_index, ModuleTypeIndex supertype_index, const WasmModule *sub_module, const WasmModule *super_module)
V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype, const WasmModule *sub_module, const WasmModule *super_module)
constexpr IndependentHeapType kWasmBottom
std::ostream & operator<<(std::ostream &os, LiftoffVarState slot)
V8_INLINE bool TypesUnrelated(ValueType type1, ValueType type2, const WasmModule *module1, const WasmModule *module2)
V8_INLINE bool HeapTypesUnrelated(HeapType heap1, HeapType heap2, const WasmModule *module1, const WasmModule *module2)
wasm::WasmModule WasmModule
#define V8_EXPORT_PRIVATE
Definition macros.h:460
TypeInModule(ValueType type, const WasmModule *module)
bool operator==(const TypeInModule &other) const
#define V8_INLINE
Definition v8config.h:500
#define V8_LIKELY(condition)
Definition v8config.h:661
#define V8_NOINLINE
Definition v8config.h:586