Skip to content

Commit 6543bb3

Browse files
committed
Merge branch 'main' into main
2 parents 49fded7 + cda461d commit 6543bb3

29 files changed

+3171
-1496
lines changed

doc/developer-guide/wasmType_usage.md

Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,68 @@
11
# Use wasmType in typescript
22
## wasmType declaration
3-
Now we support use wasmType directly in typescript, and the types must be explicitly specified:
3+
Now we support use wasmType directly in typescript, these below types are supported:
4+
### wasm basic type
45
- `i32`
56
- `i64`
67
- `f32`
78
- `f64`
9+
- `anyref`
10+
### wasm heap type
11+
- `array`
12+
- `struct`
13+
814
## wasmType usage
9-
### For basic type
15+
During usage, we must follow some rules. And the wasm basic type rules is differ from wasm heap type rules.
16+
### wasm basic type
17+
We can use the wasm basic type as ts type name directly.
18+
### wasm heap type
19+
We should set a special comment to indicate that a wasm heap type structure will be created.
20+
21+
1. For `array`, we use `comment + array type alias` to represent the raw wasm array type.
22+
```ts
23+
// Wasmnizer-ts: @WASMArray@ <Not_Packed, Mutable, Nullable>
24+
type arrayType1 = string[];
25+
---> will create a raw wasm array type: array<stringref>
26+
27+
// Wasmnizer-ts: @WASMArray@
28+
type arrayType2 = i32[];
29+
---> will create a raw wasm array type: array<i32>
30+
```
31+
**Hint: `// Wasmnizer-ts: @WASMArray@ ` is necessary, and `<Not_Packed, Mutable, Nullable>` is optional. The latter shows that `if the array element is packed`, `if the array element is mutable`, `if the array is nullable`. The default value is `Not_Packed`, `Mutable` and `Nullable`.**
32+
33+
2. For `struct`, we use `comment + tuple type alias` to represent the raw wasm struct type.
34+
```ts
35+
// Wasmnizer-ts: @WASMStruct@ <[Not_Packed, Not_Packed], [Mutable, Mutable], Nullable, NULL>
36+
type structType1 = [arrayType1, i64];
37+
---> will create a raw wasm struct type: struct[array<stringref>, i64]
38+
39+
// Wasmnizer-ts: @WASMStruct@
40+
type structType2 = [i64, i32];
41+
---> will create a raw wasm struct type: struct[i64, i32]
42+
```
43+
**Hint: `// Wasmnizer-ts: @WASMStruct@ ` is necessary, and `<[Not_Packed, ...], [Mutable, ...], Nullable, BaseTypeName>` is optional. The latter shows that `if the struct fields are packed`, `if the struct fields are mutable`, `if the struct is nullable`, `the struct's base type name`. The default value is `[Not_Packed, ...]`, `[Mutable, ...]`, `Nullable` and `NULL`.**
44+
45+
The comments' optional attributes can be one of these enum value:
46+
```ts
47+
export enum PackedTypeKind {
48+
Not_Packed = 'Not_Packed',
49+
I8 = 'I8',
50+
I16 = 'I16',
51+
}
52+
53+
export enum MutabilityKind {
54+
Immutable = 'Immutable',
55+
Mutable = 'Mutable',
56+
}
57+
58+
export enum NullabilityKind {
59+
NonNullable = 'NonNullable',
60+
Nullable = 'Nullable',
61+
}
62+
```
63+
64+
## Example
65+
### Used as basic type
1066
If we define the wasmtype for variables, and the right value is LiteralValue or variables with the same wasmtype, the **no cast** will be generated.
1167
```ts
1268
const a: i32 = 100;
@@ -32,6 +88,27 @@ const a: f64 = 100;
3288
(f64.const 100)
3389
```
3490

91+
```ts
92+
// Wasmnizer-ts: @WASMArray@
93+
type arrayType2 = i32[];
94+
const a: arrayType2 = [100];
95+
-->
96+
(array.new_fixed $array0 1
97+
(i32.const 100)
98+
)
99+
```
100+
101+
```ts
102+
// Wasmnizer-ts: @WASMStruct@
103+
type structType2 = [i64, i32];
104+
const a: structType2 = [100, 200]
105+
--->
106+
(struct.new $45
107+
(i64.const 100)
108+
(i32.const 200)
109+
)
110+
```
111+
35112
If we don't define the wasmtype explicitly, then the variable will be regard as `number` type, **one cast** will be occurs.
36113
```ts
37114
const a = 100 as i32;
@@ -42,12 +119,21 @@ const a = 100 as i32;
42119
```
43120

44121

45-
### For array type
122+
### Used as array element type
46123
The array type should be explicitly specified too.
47124
```ts
48125
const a: i32[] = [1, 2];
49126
-->
50127
a will be regarded as i32[], the elements in right value are both i32.
128+
since we use struct to represent ts array, so the wasm structure is struct[array<i32>, i32].
129+
```
130+
```ts
131+
const x: arrayType2 = [100];
132+
const y: arrayType2 = [200];
133+
const a: arrayType2[] = [x, y];
134+
-->
135+
a will be regarded as arrayType2[], the elements in right value are both arrayType2.
136+
since we use struct to represent ts array, so the wasm structure is struct[array<array<i32>>, i32].
51137
```
52138
If array's type is not explicitly specified, then left value is regarded as number[], compilation error will occur.
53139
```ts
@@ -58,19 +144,20 @@ let a = [a1, a2];
58144
a will be regarded as number[], compile will fail.
59145
```
60146

61-
### For class type
147+
### Used as class property type
62148
Each property's wasm type should be explicitly specified.
63149
```ts
64150
class A {
65151
a: i32 = 1;
66152
b: i64 = 2;
67153
c: f32 = 3;
68154
d: f64 = 4;
155+
e: arrayType2 = [5];
69156
}
70157
-->
71-
The properties type are i32, i64, f32, f64 type.
158+
The properties type are i32, i64, f32, f64, array<i32> type.
72159
```
73-
If property's type is not explicitly specified, they will be regarded as number type, and **one cast** will occur.
160+
If property's type is not explicitly specified, they will be regarded as original ts type, and **one cast** will occur.
74161
```ts
75162
class A {
76163
a = 1 as i32;
@@ -81,31 +168,42 @@ class A {
81168
-->
82169
The properties type are both number type, and a, b, c all will be cast to f64.
83170
```
171+
Wasm heap type can not be used as casted target since the ts original type `number[]` can not be casted to `WASMArrayType`:
172+
```ts
173+
class A {
174+
e = [5] as arrayType2
175+
}
176+
-->
177+
Will cause compilation error since `cannot make cast value from "Array<NUMBER(6)(OBJECT)>(-1)" to "WASM_ARRAY(58)"`
178+
```
84179

85-
### For interface type
180+
### Used as interface property type
86181
Each property's wasm type should be explicitly specified.
87182
```ts
88183
interface I {
89184
a: i32;
90185
b: i64;
91186
c: f32;
92187
d: f64;
188+
e: arrayType2;
93189
}
94190
-->
95-
The properties type are i32, i64, f32, f64 type.
191+
The properties type are i32, i64, f32, f64, array<i32> type.
96192
```
97193

98-
### For object literal type
194+
### Used as object literal property type
99195
Since object literal's properties' type can not be defined, we only provide its value, so we judge properties' type by its real value type.
100196
```ts
197+
const x: arrayType2 = [5];
101198
const obj = {
102199
a: 1 as i32,
103200
b: 2 as i64,
104201
c: 3 as f32,
105202
d: 4 as f64,
203+
e: x as arrayType2,
106204
}
107205
-->
108-
The properties type are i32, i64, f32, f64 type.
206+
The properties type are i32, i64, f32, f64, array<i32> type.
109207
```
110208

111209
So, if we assign the obj's type to an interface type which has wasmtype, then we should ensure that the properties' value type should be wasmtype too.
@@ -115,12 +213,15 @@ interface I {
115213
b: i64;
116214
c: f32;
117215
d: f64;
216+
e: arrayType2;
118217
}
218+
const x: arrayType2 = [5];
119219
const obj: I = {
120220
a: 1 as i32,
121221
b: 2 as i64,
122222
c: 3 as f32,
123223
d: 4 as f64,
224+
e: x as arrayType2,
124225
}
125226
--->
126227
compile success
@@ -131,18 +232,20 @@ interface I {
131232
b: i64;
132233
c: f32;
133234
d: f64;
235+
e: arrayType2;
134236
}
135237
const obj: I = {
136238
a: 1,
137239
b: 2,
138240
c: 3,
139241
d: 4,
242+
e: [5],
140243
}
141244
--->
142245
compile fail
143246
```
144247

145-
### For funtion type
248+
### Used as funtion param type & return type
146249
The parameter's type and return type should be explicitly specified when using wasmtype.
147250
```ts
148251
function test(): i32 {
@@ -165,7 +268,16 @@ One cast will occur, the return type is number.
165268
)
166269
```
167270

168-
### binary operations
271+
```ts
272+
function test(): arrayType2 {
273+
const x: arrayType2 = [100];
274+
return x;
275+
}
276+
-->
277+
The return type is array<i32>.
278+
```
279+
280+
### type casting in binary operations
169281
If two operators with wasm type operate binary operations, they will cast to the larger type, and operate.
170282
```ts
171283
const a: i32 = 100;

lib/builtin/builtin_name.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export namespace BuiltinNames {
5959
export const findPropertyFlagAndIndex = 'find_property_flag_and_index';
6060
export const findPropertyType = 'find_property_type';
6161
export const getInfcProperty = 'get_infc_property';
62+
export const getTupleField = 'get_tuple_field';
6263

6364
// builtin globals
6465
export const builtinTypeManglePrefix = 'lib/builtin/lib.type.d';

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
},
6565
"lint-staged": {
6666
"*.ts": [
67-
"eslint --ignore-path .eslintignore --config .eslintrc.json --fix '**/*.ts'",
67+
"eslint --ignore-path .eslintignore --config .eslintrc.json --fix --quiet '**/*.ts'",
6868
"prettier --ignore-path .prettierignore --config .prettierrc.json --write '**/*.ts'"
6969
]
7070
},

runtime-library/stdlib/lib_array.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ array_concat_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
160160
return NULL;
161161
}
162162

163-
wasm_runtime_push_local_object_ref(exec_env, &local_ref);
163+
wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
164164
local_ref.val = (wasm_obj_t)new_arr;
165165
create_new_array = true;
166166

@@ -183,7 +183,7 @@ array_concat_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
183183

184184
fail:
185185
if (create_new_array) {
186-
wasm_runtime_pop_local_object_ref(exec_env);
186+
wasm_runtime_pop_local_obj_ref(exec_env);
187187
}
188188

189189
return new_arr_struct;
@@ -305,7 +305,7 @@ array_slice_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
305305
return NULL;
306306
}
307307

308-
wasm_runtime_push_local_object_ref(exec_env, &local_ref);
308+
wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
309309
local_ref.val = (wasm_obj_t)new_arr;
310310

311311
for (i = start; i < end; i++) {
@@ -326,7 +326,7 @@ array_slice_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
326326
wasm_struct_obj_set_field(new_arr_struct, 1, &tmp_val);
327327

328328
end:
329-
wasm_runtime_pop_local_object_ref(exec_env);
329+
wasm_runtime_pop_local_obj_ref(exec_env);
330330
return new_arr_struct;
331331
}
332332

@@ -500,7 +500,7 @@ array_splice_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
500500
goto end1;
501501
}
502502

503-
wasm_runtime_push_local_object_ref(exec_env, &local_ref);
503+
wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
504504
local_ref.val = (wasm_obj_t)delete_arr;
505505

506506
/* Copy deleted elements to delete_arr*/
@@ -551,7 +551,7 @@ array_splice_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
551551
tmp_val.u32 = delete_count;
552552
wasm_struct_obj_set_field(new_arr_struct, 1, &tmp_val);
553553

554-
wasm_runtime_pop_local_object_ref(exec_env);
554+
wasm_runtime_pop_local_obj_ref(exec_env);
555555
return new_arr_struct;
556556

557557
end1:
@@ -560,7 +560,7 @@ array_splice_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
560560
return NULL;
561561

562562
end2:
563-
wasm_runtime_pop_local_object_ref(exec_env);
563+
wasm_runtime_pop_local_obj_ref(exec_env);
564564
wasm_runtime_set_exception(wasm_runtime_get_module_inst(exec_env),
565565
"alloc memory failed");
566566
return NULL;
@@ -1059,7 +1059,7 @@ array_map_generic(wasm_exec_env_t exec_env, void *ctx, void *obj, void *closure)
10591059
"alloc memory failed");
10601060
return NULL;
10611061
}
1062-
wasm_runtime_push_local_object_ref(exec_env, &local_ref);
1062+
wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
10631063
local_ref.val = (wasm_obj_t)new_arr;
10641064

10651065
/* get current array element type */
@@ -1110,7 +1110,7 @@ array_map_generic(wasm_exec_env_t exec_env, void *ctx, void *obj, void *closure)
11101110
wasm_struct_obj_set_field(new_arr_struct, 1, &tmp_val);
11111111

11121112
end:
1113-
wasm_runtime_pop_local_object_ref(exec_env);
1113+
wasm_runtime_pop_local_obj_ref(exec_env);
11141114
return new_arr_struct;
11151115
}
11161116

@@ -1190,7 +1190,7 @@ array_filter_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
11901190
"alloc memory failed");
11911191
goto end1;
11921192
}
1193-
wasm_runtime_push_local_object_ref(exec_env, &local_ref);
1193+
wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
11941194
local_ref.val = (wasm_obj_t)new_arr;
11951195

11961196
for (i = 0; i < new_arr_len; i++) {
@@ -1211,7 +1211,7 @@ array_filter_generic(wasm_exec_env_t exec_env, void *ctx, void *obj,
12111211
wasm_struct_obj_set_field(new_arr_struct, 1, &tmp_val);
12121212

12131213
end2:
1214-
wasm_runtime_pop_local_object_ref(exec_env);
1214+
wasm_runtime_pop_local_obj_ref(exec_env);
12151215

12161216
end1:
12171217
if (include_refs) {

runtime-library/utils/object_utils.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ call_wasm_func_with_boxing(wasm_exec_env_t exec_env, dyn_ctx_t ctx,
442442
) {
443443
/* unbox_value_from_any will create anyref for any-objects, we must
444444
* hold its reference to avoid it being claimed */
445-
wasm_runtime_push_local_object_ref(exec_env,
445+
wasm_runtime_push_local_obj_ref(exec_env,
446446
&local_refs[local_ref_count]);
447447
local_refs[local_ref_count++].val = tmp_param.gc_obj;
448448
}
@@ -454,7 +454,7 @@ call_wasm_func_with_boxing(wasm_exec_env_t exec_env, dyn_ctx_t ctx,
454454
}
455455

456456
if (local_ref_count) {
457-
wasm_runtime_pop_local_object_refs(exec_env, local_ref_count);
457+
wasm_runtime_pop_local_obj_refs(exec_env, local_ref_count);
458458
}
459459

460460
is_success =

0 commit comments

Comments
 (0)