• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/wasm/value-type.h"
9 
10 namespace v8 {
11 namespace internal {
12 namespace wasm {
13 
14 struct WasmModule;
15 
16 V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
17     ValueType subtype, ValueType supertype, const WasmModule* sub_module,
18     const WasmModule* super_module);
19 
20 // Checks if type1, defined in module1, is equivalent with type2, defined in
21 // module2.
22 // Type equivalence (~) is described by the following rules (structural
23 // equivalence):
24 // - Two numeric types are equivalent if they are equal.
25 // - optref(ht1) ~ optref(ht2) iff ht1 ~ ht2.
26 // - ref(ht1) ~ ref(ht2) iff ht1 ~ ht2.
27 // - rtt(d1, ht1) ~ rtt(d2, ht2) iff (d1 = d2 and ht1 ~ ht2).
28 // For heap types, the following rules hold:
29 // - Two generic heap types are equivalent iff they are equal.
30 // - Two structs are equivalent iff they contain the same number of fields and
31 // these are pairwise equivalent.
32 // - Two functions are equivalent iff they contain the same number of parameters
33 // and returns and these are pairwise equivalent.
34 // - Two arrays are equivalent iff their underlying types are equivalent.
35 V8_NOINLINE bool EquivalentTypes(ValueType type1, ValueType type2,
36                                  const WasmModule* module1,
37                                  const WasmModule* module2);
38 
39 // Checks if subtype, defined in module1, is a subtype of supertype, defined in
40 // module2.
41 // Subtyping between value types is described by the following rules
42 // (structural subtyping):
43 // - numeric types are subtype-related iff they are equal.
44 // - optref(ht1) <: optref(ht2) iff ht1 <: ht2.
45 // - ref(ht1) <: ref/optref(ht2) iff ht1 <: ht2.
46 // - rtt1 <: rtt2 iff rtt1 ~ rtt2.
47 // For heap types, the following subtyping rules hold:
48 // - Each generic heap type is a subtype of itself.
49 // - All functions are subtypes of func.
50 // - i31, structs and arrays are subtypes of eq.
51 // - Struct subtyping: Subtype must have at least as many fields as supertype,
52 //   covariance for immutable fields, equivalence for mutable fields.
53 // - Array subtyping (mutable only) is the equivalence relation.
54 // - Function subtyping is the equivalence relation (note: this rule might
55 //   change in the future to include type variance).
IsSubtypeOf(ValueType subtype,ValueType supertype,const WasmModule * sub_module,const WasmModule * super_module)56 V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
57                            const WasmModule* sub_module,
58                            const WasmModule* super_module) {
59   if (subtype == supertype && sub_module == super_module) return true;
60   return IsSubtypeOfImpl(subtype, supertype, sub_module, super_module);
61 }
62 
63 // Checks if 'subtype' is a subtype of 'supertype' (both defined in module).
IsSubtypeOf(ValueType subtype,ValueType supertype,const WasmModule * module)64 V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
65                            const WasmModule* module) {
66   // If the types are trivially identical, exit early.
67   if (V8_LIKELY(subtype == supertype)) return true;
68   return IsSubtypeOfImpl(subtype, supertype, module, module);
69 }
70 
71 // Returns the weakest type that is a subtype of both a and b
72 // (which is currently always one of a, b, or kWasmBottom).
73 // TODO(manoskouk): Update this once we have settled on a type system for
74 // reference types.
75 ValueType CommonSubtype(ValueType a, ValueType b, const WasmModule* module);
76 
77 }  // namespace wasm
78 }  // namespace internal
79 }  // namespace v8
80 
81 #endif  // V8_WASM_WASM_SUBTYPING_H_
82