-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[WebAssembly] Add support for nonnull_extern_ref type #148935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,10 @@ | |
// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +reference-types -o - -emit-llvm %s | FileCheck %s | ||
|
||
typedef __externref_t externref_t; | ||
typedef __non_null_externref_t nn_externref_t; | ||
|
||
void helper(externref_t); | ||
void helper_2(nn_externref_t); | ||
|
||
// CHECK-LABEL: @handle( | ||
// CHECK-NEXT: entry: | ||
|
@@ -16,3 +18,48 @@ void helper(externref_t); | |
void handle(externref_t obj) { | ||
helper(obj); | ||
} | ||
|
||
|
||
// CHECK-LABEL: @handle_2( | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: [[OBJ_ADDR:%.*]] = alloca ptr addrspace(10), align 1 | ||
// CHECK-NEXT: store ptr addrspace(10) [[OBJ:%.*]], ptr [[OBJ_ADDR]], align 1 | ||
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(10), ptr [[OBJ_ADDR]], align 1 | ||
// CHECK-NEXT: call void @helper_2(ptr addrspace(10) [[TMP0]]) | ||
// CHECK-NEXT: ret void | ||
// | ||
void handle_2(nn_externref_t obj) { | ||
helper_2(obj); | ||
} | ||
|
||
|
||
nn_externref_t socketpair_js_concat(nn_externref_t, nn_externref_t) | ||
__attribute__((import_module("wasm:js-string"), import_name("concat"))); | ||
|
||
nn_externref_t get_string_ref(const char *s); | ||
void print_string_ref(nn_externref_t); | ||
|
||
// CHECK-LABEL: @socketpair_example( | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: [[STR1:%.*]] = alloca ptr addrspace(10), align 1 | ||
// CHECK-NEXT: [[STR2:%.*]] = alloca ptr addrspace(10), align 1 | ||
// CHECK-NEXT: [[RESULT:%.*]] = alloca ptr addrspace(10), align 1 | ||
// CHECK-NEXT: [[CALL:%.*]] = call ptr addrspace(10) @get_string_ref(ptr noundef @.str) | ||
// CHECK-NEXT: store ptr addrspace(10) [[CALL]], ptr [[STR1]], align 1 | ||
// CHECK-NEXT: [[CALL1:%.*]] = call ptr addrspace(10) @get_string_ref(ptr noundef @.str.1) | ||
// CHECK-NEXT: store ptr addrspace(10) [[CALL1]], ptr [[STR2]], align 1 | ||
// CHECK-NEXT: [[TMP0:%.*]] = load ptr addrspace(10), ptr [[STR1]], align 1 | ||
// CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(10), ptr [[STR2]], align 1 | ||
// CHECK-NEXT: [[CALL2:%.*]] = call ptr addrspace(10) @socketpair_js_concat(ptr addrspace(10) [[TMP0]], ptr addrspace(10) [[TMP1]]) | ||
// CHECK-NEXT: store ptr addrspace(10) [[CALL2]], ptr [[RESULT]], align 1 | ||
// CHECK-NEXT: [[TMP2:%.*]] = load ptr addrspace(10), ptr [[RESULT]], align 1 | ||
// CHECK-NEXT: call void @print_string_ref(ptr addrspace(10) [[TMP2]]) | ||
// CHECK-NEXT: ret void | ||
// | ||
void socketpair_example() { | ||
nn_externref_t str1 = get_string_ref("Hello, "); | ||
nn_externref_t str2 = get_string_ref("world!"); | ||
nn_externref_t result = socketpair_js_concat(str1, str2); | ||
print_string_ref(result); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be interesting to have some tests to ensure the semantics of non-null externref. For example, you can't construct a null and assign it to non-null externref. You cannot assign an nullable externref to a non-nullable externref, however the opposite should work. You should be able to assign a non-nullable to a nullable. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,10 @@ __externref_t r1; | |
extern __externref_t r2; | ||
static __externref_t r3; | ||
|
||
__non_null_externref_t nn_r1; | ||
extern __non_null_externref_t nn_r2; | ||
static __non_null_externref_t nn_r3; | ||
|
||
__externref_t *t1; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t **t2; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t ******t3; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
|
@@ -19,10 +23,24 @@ __externref_t t7[0]; // expected-error {{WebAssembly table must be s | |
static __externref_t t8[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}} | ||
static __externref_t (*t9)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
|
||
__non_null_externref_t *nn_t1; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__non_null_externref_t **nn_t2; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__non_null_externref_t ******nn_t3; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
static __non_null_externref_t nn_t4[3]; // expected-error {{only zero-length WebAssembly tables are currently supported}} | ||
static __non_null_externref_t nn_t5[]; // expected-error {{only zero-length WebAssembly tables are currently supported}} | ||
static __non_null_externref_t nn_t6[] = {0}; // expected-error {{only zero-length WebAssembly tables are currently supported}} | ||
__non_null_externref_t nn_t7[0]; // expected-error {{WebAssembly table must be static}} | ||
static __non_null_externref_t nn_t8[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}} | ||
static __non_null_externref_t (*nn_t9)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
|
||
static __externref_t table[0]; | ||
static __externref_t other_table[0] = {}; | ||
static __externref_t another_table[] = {}; // expected-error {{only zero-length WebAssembly tables are currently supported}} | ||
|
||
static __non_null_externref_t nn_table[0]; | ||
static __non_null_externref_t nn_other_table[0] = {}; | ||
static __non_null_externref_t nn_another_table[] = {}; // expected-error {{only zero-length WebAssembly tables are currently supported}} | ||
|
||
struct s { | ||
__externref_t f1; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t f2[0]; // expected-error {{field has sizeless type '__externref_t'}} | ||
|
@@ -33,6 +51,17 @@ struct s { | |
__externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
}; | ||
|
||
|
||
struct nn_s { | ||
__externref_t nn_f1; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t nn_f2[0]; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t nn_f3[]; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t nn_f4[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}} | ||
__externref_t *nn_f5; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t ****nn_f6; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t (*nn_f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
}; | ||
|
||
union u { | ||
__externref_t f1; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t f2[0]; // expected-error {{field has sizeless type '__externref_t'}} | ||
|
@@ -43,16 +72,38 @@ union u { | |
__externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
}; | ||
|
||
|
||
union nn_u { | ||
__externref_t nn_f1; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t nn_f2[0]; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t nn_f3[]; // expected-error {{field has sizeless type '__externref_t'}} | ||
__externref_t nn_f4[0][0]; // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}} | ||
__externref_t *nn_f5; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t ****nn_f6; // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t (*f7)[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
badumbatish marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
void illegal_argument_1(__externref_t table[]); // expected-error {{cannot use WebAssembly table as a function parameter}} | ||
void illegal_argument_2(__externref_t table[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}} | ||
void illegal_argument_3(__externref_t *table); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
void illegal_argument_4(__externref_t ***table); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
void illegal_argument_5(__externref_t (*table)[0]); // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
void illegal_argument_6(__externref_t table[0]); // expected-error {{cannot use WebAssembly table as a function parameter}} | ||
|
||
void illegal_nn_argument_1(__non_null_externref_t table[]); // expected-error {{cannot use WebAssembly table as a function parameter}} | ||
void illegal_nn_argument_2(__non_null_externref_t table[0][0]); // expected-error {{multi-dimensional arrays of WebAssembly references are not allowed}} | ||
void illegal_nn_argument_3(__non_null_externref_t *table); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
void illegal_nn_argument_4(__non_null_externref_t ***table); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
void illegal_nn_argument_5(__non_null_externref_t (*table)[0]); // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
void illegal_nn_argument_6(__non_null_externref_t table[0]); // expected-error {{cannot use WebAssembly table as a function parameter}} | ||
|
||
__externref_t *illegal_return_1(); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t ***illegal_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__externref_t (*illegal_return_3())[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
|
||
__non_null_externref_t *illegal_nn_return_1(); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__non_null_externref_t ***illegal_nn_return_2(); // expected-error {{pointer to WebAssembly reference type is not allowed}} | ||
__non_null_externref_t (*illegal_nn_return_3())[0]; // expected-error {{cannot form a pointer to a WebAssembly table}} | ||
|
||
void varargs(int, ...); | ||
typedef void (*__funcref funcref_t)(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -308,6 +308,13 @@ Type *Type::getWasm_ExternrefTy(LLVMContext &C) { | |
return Ty; | ||
} | ||
|
||
Type *Type::getWasm_NonNullExternrefTy(LLVMContext &C) { | ||
// opaque pointer in addrspace(10) | ||
// TODO: Hey Jasmine, Is this correct? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because you cannot assign non-null to null externrefs interchangeably, it's almost like a different type. My initial thought would be to create a new AS for this. |
||
static PointerType *Ty = PointerType::get(C, 10); | ||
return Ty; | ||
} | ||
|
||
Type *Type::getWasm_FuncrefTy(LLVMContext &C) { | ||
// opaque pointer in addrspace(20) | ||
static PointerType *Ty = PointerType::get(C, 20); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be 11 or something... So that when we constraint the types behaviour we can differentiate it from (the nullable) externref.