summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/gc/function_subtyping.js
blob: 3ef0d17dd3059baf72ef32887f5c256326319f0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// |jit-test| skip-if: !wasmGcEnabled()

// Validate rules for function subtyping:
// - Same number of parameters and results
// - Function return types are covariant
// - Function parameter types are contravariant
wasmValidateText(
`(module
    (type $A (sub (struct (field i32))))
    (type $B (sub $A (struct (field i32) (field i32))))
    (type $C (sub $B (struct (field i32) (field i32) (field i64))))
    (type $D (sub $B (struct (field i32) (field i32) (field f32))))

    ;; Same types (invariant)
    (type $func1 (sub (func (param (ref $A) (ref $A)) (result (ref $C)))))
    (type $func2 (sub $func1 (func (param (ref $A) (ref $A)) (result (ref $C)))))

    ;; Covariant return types are valid
    (type $func3 (sub (func (param (ref $A) (ref $A)) (result (ref $B)))))
    (type $func4 (sub $func3 (func (param (ref $A) (ref $A)) (result (ref $C)))))
    (type $func5 (sub (func (param (ref $A) (ref $A)) (result (ref $A) (ref $B)))))
    (type $func6 (sub $func5 (func (param (ref $A) (ref $A)) (result (ref $D) (ref $C)))))

    ;; Contravariant parameter types are valid
    (type $func7 (sub (func (param (ref $A) (ref $C)) (result (ref $C)))))
    (type $func8 (sub $func7 (func (param (ref $A) (ref $B)) (result (ref $C)))))
    (type $func9 (sub (func (param (ref $D) (ref $C)) (result (ref $C)))))
    (type $func10 (sub $func9 (func (param (ref $A) (ref $B)) (result (ref $C)))))

    ;; Mixing covariance and contravariance
    (type $func11 (sub (func (param (ref $D) (ref $C)) (result (ref $A)))))
    (type $func12 (sub $func11 (func (param (ref $A) (ref $B)) (result (ref $C)))))
)
`);

// Validate that incorrect subtyping examples are failing as expected
const typeError = /incompatible super type/;

var code =`
(module
    (type $A (struct (field i32)))
    (type $B (sub $A (struct (field i32) (field i32))))
    (type $C (sub $B (struct (field i32) (field i32) (field i64))))
    (type $D (sub $B (struct (field i32) (field i32) (field f32))))

    ;; Not the same number of arguments/results
    (type $func1 (func (param (ref $A) (ref $A)) (result (ref $C))))
    (type $func2 (sub $func1 (func (param (ref $A) (ref $A)) (result (ref $C) (ref $A)))))
)`;

wasmFailValidateText(code, typeError);

code =`
(module
    (type $A (sub (struct (field i32))))
    (type $B (sub $A (struct (field i32) (field i32))))
    (type $C (sub $B (struct (field i32) (field i32) (field i64))))
    (type $D (sub $B (struct (field i32) (field i32) (field f32))))

    ;; Contravariant result types are invalid
    (type $func3 (sub (func (param (ref $A) (ref $A)) (result (ref $C)))))
    (type $func4 (sub $func3 (func (param (ref $A) (ref $A)) (result (ref $A)))))
)`;

wasmFailValidateText(code, typeError);

code =`
(module
    (type $A (sub (struct (field i32))))
    (type $B (sub $A (struct (field i32) (field i32))))
    (type $C (sub $B (struct (field i32) (field i32) (field i64))))
    (type $D (sub $B (struct (field i32) (field i32) (field f32))))

    ;; Covariant parameters are invalid
    (type $func5 (sub (func (param (ref $A) (ref $A)) (result (ref $C)))))
    (type $func6 (sub $func5 (func (param (ref $B) (ref $A)) (result (ref $C)))))
)`;

wasmFailValidateText(code, typeError);