11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#if !V8_ENABLE_WEBASSEMBLY
61cb0ef41Sopenharmony_ci#error This header should only be included if WebAssembly is enabled.
71cb0ef41Sopenharmony_ci#endif  // !V8_ENABLE_WEBASSEMBLY
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#ifndef V8_WASM_WASM_SUBTYPING_H_
101cb0ef41Sopenharmony_ci#define V8_WASM_WASM_SUBTYPING_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "src/wasm/value-type.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8 {
151cb0ef41Sopenharmony_cinamespace internal {
161cb0ef41Sopenharmony_cinamespace wasm {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cistruct WasmModule;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciV8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
211cb0ef41Sopenharmony_ci    ValueType subtype, ValueType supertype, const WasmModule* sub_module,
221cb0ef41Sopenharmony_ci    const WasmModule* super_module);
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci// Checks if type1, defined in module1, is equivalent with type2, defined in
251cb0ef41Sopenharmony_ci// module2.
261cb0ef41Sopenharmony_ci// Type equivalence (~) is described by the following rules:
271cb0ef41Sopenharmony_ci// - Two numeric types are equivalent iff they are equal.
281cb0ef41Sopenharmony_ci// - T(ht1) ~ T(ht2) iff ht1 ~ ht2 for T in {ref, optref, rtt}.
291cb0ef41Sopenharmony_ci// Equivalence of heap types ht1 ~ ht2 is defined as follows:
301cb0ef41Sopenharmony_ci// - Two non-index heap types are equivalent iff they are equal.
311cb0ef41Sopenharmony_ci// - Two indexed heap types are equivalent iff they are iso-recursive
321cb0ef41Sopenharmony_ci//   equivalent.
331cb0ef41Sopenharmony_ciV8_NOINLINE V8_EXPORT_PRIVATE bool EquivalentTypes(ValueType type1,
341cb0ef41Sopenharmony_ci                                                   ValueType type2,
351cb0ef41Sopenharmony_ci                                                   const WasmModule* module1,
361cb0ef41Sopenharmony_ci                                                   const WasmModule* module2);
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// Checks if {subtype}, defined in {module1}, is a subtype of {supertype},
391cb0ef41Sopenharmony_ci// defined in {module2}.
401cb0ef41Sopenharmony_ci// Subtyping between value types is described by the following rules
411cb0ef41Sopenharmony_ci// (structural subtyping):
421cb0ef41Sopenharmony_ci// - numeric types are subtype-related iff they are equal.
431cb0ef41Sopenharmony_ci// - optref(ht1) <: optref(ht2) iff ht1 <: ht2.
441cb0ef41Sopenharmony_ci// - ref(ht1) <: ref/optref(ht2) iff ht1 <: ht2.
451cb0ef41Sopenharmony_ci// - rtt1 <: rtt2 iff rtt1 ~ rtt2.
461cb0ef41Sopenharmony_ci// For heap types, the following subtyping rules hold:
471cb0ef41Sopenharmony_ci// - The abstract heap types form the following type hierarchy:
481cb0ef41Sopenharmony_ci//           any
491cb0ef41Sopenharmony_ci//         /  |  \
501cb0ef41Sopenharmony_ci//       eq func  extern
511cb0ef41Sopenharmony_ci//      / \
521cb0ef41Sopenharmony_ci//   i31   data
531cb0ef41Sopenharmony_ci//          |
541cb0ef41Sopenharmony_ci//        array
551cb0ef41Sopenharmony_ci// - All functions are subtypes of func.
561cb0ef41Sopenharmony_ci// - All structs are subtypes of data.
571cb0ef41Sopenharmony_ci// - All arrays are subtypes of array.
581cb0ef41Sopenharmony_ci// - An indexed heap type h1 is a subtype of indexed heap type h2 if h2 is
591cb0ef41Sopenharmony_ci//   transitively an explicit canonical supertype of h1.
601cb0ef41Sopenharmony_ciV8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
611cb0ef41Sopenharmony_ci                           const WasmModule* sub_module,
621cb0ef41Sopenharmony_ci                           const WasmModule* super_module) {
631cb0ef41Sopenharmony_ci  if (subtype == supertype && sub_module == super_module) return true;
641cb0ef41Sopenharmony_ci  return IsSubtypeOfImpl(subtype, supertype, sub_module, super_module);
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci// Checks if {subtype} is a subtype of {supertype} (both defined in {module}).
681cb0ef41Sopenharmony_ciV8_INLINE bool IsSubtypeOf(ValueType subtype, ValueType supertype,
691cb0ef41Sopenharmony_ci                           const WasmModule* module) {
701cb0ef41Sopenharmony_ci  // If the types are trivially identical, exit early.
711cb0ef41Sopenharmony_ci  if (V8_LIKELY(subtype == supertype)) return true;
721cb0ef41Sopenharmony_ci  return IsSubtypeOfImpl(subtype, supertype, module, module);
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci// We have this function call IsSubtypeOf instead of the opposite because type
761cb0ef41Sopenharmony_ci// checks are much more common than heap type checks.
771cb0ef41Sopenharmony_ciV8_INLINE bool IsHeapSubtypeOf(HeapType::Representation subtype,
781cb0ef41Sopenharmony_ci                               HeapType::Representation supertype,
791cb0ef41Sopenharmony_ci                               const WasmModule* module) {
801cb0ef41Sopenharmony_ci  return IsSubtypeOf(ValueType::Ref(subtype, kNonNullable),
811cb0ef41Sopenharmony_ci                     ValueType::Ref(supertype, kNonNullable), module);
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci// Checks whether {subtype_index} is valid as a declared subtype of
851cb0ef41Sopenharmony_ci// {supertype_index}.
861cb0ef41Sopenharmony_ci// - Both type must be of the same kind (function, struct, or array).
871cb0ef41Sopenharmony_ci// - Structs: Subtype must have at least as many fields as supertype,
881cb0ef41Sopenharmony_ci//   covariance for respective immutable fields, equivalence for respective
891cb0ef41Sopenharmony_ci//   mutable fields.
901cb0ef41Sopenharmony_ci// - Arrays: subtyping of respective element types for immutable arrays,
911cb0ef41Sopenharmony_ci//   equivalence of element types for mutable arrays.
921cb0ef41Sopenharmony_ci// - Functions: equal number of parameter and return types. Contravariance for
931cb0ef41Sopenharmony_ci//   respective parameter types, covariance for respective return types.
941cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE bool ValidSubtypeDefinition(uint32_t subtype_index,
951cb0ef41Sopenharmony_ci                                              uint32_t supertype_index,
961cb0ef41Sopenharmony_ci                                              const WasmModule* sub_module,
971cb0ef41Sopenharmony_ci                                              const WasmModule* super_module);
981cb0ef41Sopenharmony_ci}  // namespace wasm
991cb0ef41Sopenharmony_ci}  // namespace internal
1001cb0ef41Sopenharmony_ci}  // namespace v8
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci#endif  // V8_WASM_WASM_SUBTYPING_H_
103