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