• 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 #if !V8_ENABLE_WEBASSEMBLY
6 #error This header should only be included if WebAssembly is enabled.
7 #endif  // !V8_ENABLE_WEBASSEMBLY
8 
9 #ifndef V8_WASM_WASM_SUBTYPING_H_
10 #define V8_WASM_WASM_SUBTYPING_H_
11 
12 #include "src/wasm/value-type.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace wasm {
17 
18 struct WasmModule;
19 
20 V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
21     ValueType subtype, ValueType supertype, const WasmModule* sub_module,
22     const WasmModule* super_module);
23 
24 // Checks if type1, defined in module1, is equivalent with type2, defined in
25 // module2.
26 // Type equivalence (~) is described by the following rules:
27 // - Two numeric types are equivalent iff they are equal.
28 // - T(ht1) ~ T(ht2) iff ht1 ~ ht2 for T in {ref, optref, rtt}.
29 // Equivalence of heap types ht1 ~ ht2 is defined as follows:
30 // - Two non-index heap types are equivalent iff they are equal.
31 // - Two indexed heap types are equivalent iff they are iso-recursive
32 //   equivalent.
33 V8_NOINLINE V8_EXPORT_PRIVATE bool EquivalentTypes(ValueType type1,
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 // - optref(ht1) <: optref(ht2) iff ht1 <: ht2.
44 // - ref(ht1) <: ref/optref(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 hierarchy:
48 //           any
49 //         /  |  \
50 //       eq func  extern
51 //      / \
52 //   i31   data
53 //          |
54 //        array
55 // - All functions are subtypes of func.
56 // - All structs are subtypes of data.
57 // - All arrays are subtypes of array.
58 // - An indexed heap type h1 is a subtype of indexed heap type h2 if h2 is
59 //   transitively an explicit canonical supertype of h1.
IsSubtypeOf(ValueType subtype,ValueType supertype,const WasmModule * sub_module,const WasmModule * super_module)60 V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
61                            const WasmModule* sub_module,
62                            const WasmModule* super_module) {
63   if (subtype == supertype && sub_module == super_module) return true;
64   return IsSubtypeOfImpl(subtype, supertype, sub_module, super_module);
65 }
66 
67 // Checks if {subtype} is a subtype of {supertype} (both defined in {module}).
IsSubtypeOf(ValueType subtype,ValueType supertype,const WasmModule * module)68 V8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
69                            const WasmModule* module) {
70   // If the types are trivially identical, exit early.
71   if (V8_LIKELY(subtype == supertype)) return true;
72   return IsSubtypeOfImpl(subtype, supertype, module, module);
73 }
74 
75 // We have this function call IsSubtypeOf instead of the opposite because type
76 // checks are much more common than heap type checks.
IsHeapSubtypeOf(HeapType::Representation subtype,HeapType::Representation supertype,const WasmModule * module)77 V8_INLINE bool IsHeapSubtypeOf(HeapType::Representation subtype,
78                                HeapType::Representation supertype,
79                                const WasmModule* module) {
80   return IsSubtypeOf(ValueType::Ref(subtype, kNonNullable),
81                      ValueType::Ref(supertype, kNonNullable), module);
82 }
83 
84 // Checks whether {subtype_index} is valid as a declared subtype of
85 // {supertype_index}.
86 // - Both type must be of the same kind (function, struct, or array).
87 // - Structs: Subtype must have at least as many fields as supertype,
88 //   covariance for respective immutable fields, equivalence for respective
89 //   mutable fields.
90 // - Arrays: subtyping of respective element types for immutable arrays,
91 //   equivalence of element types for mutable arrays.
92 // - Functions: equal number of parameter and return types. Contravariance for
93 //   respective parameter types, covariance for respective return types.
94 V8_EXPORT_PRIVATE bool ValidSubtypeDefinition(uint32_t subtype_index,
95                                               uint32_t supertype_index,
96                                               const WasmModule* sub_module,
97                                               const WasmModule* super_module);
98 }  // namespace wasm
99 }  // namespace internal
100 }  // namespace v8
101 
102 #endif  // V8_WASM_WASM_SUBTYPING_H_
103