mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-06 18:47:56 +02:00
+ support nil comparison of WebAssembly reference types (externref and funcref)
This commit is contained in:
parent
9daabb2123
commit
8cd6606970
@ -2675,9 +2675,9 @@ implementation
|
||||
case nodetype of
|
||||
equaln,unequaln :
|
||||
begin
|
||||
if is_voidpointer(right.resultdef) then
|
||||
if is_voidpointer(right.resultdef) and (left.nodetype<>niln) then
|
||||
inserttypeconv(right,left.resultdef)
|
||||
else if is_voidpointer(left.resultdef) then
|
||||
else if is_voidpointer(left.resultdef) and (right.nodetype<>niln) then
|
||||
inserttypeconv(left,right.resultdef)
|
||||
else if not(equal_defs(ld,rd)) then
|
||||
IncompatibleTypes(ld,rd);
|
||||
@ -2704,6 +2704,16 @@ implementation
|
||||
inserttypeconv_internal(right,charfarpointertype)
|
||||
else
|
||||
inserttypeconv_internal(right,charnearpointertype);
|
||||
{$elseif defined(wasm)}
|
||||
if is_wasm_reference_type(left.resultdef) then
|
||||
inserttypeconv(right,left.resultdef)
|
||||
else if is_wasm_reference_type(right.resultdef) then
|
||||
inserttypeconv(left,right.resultdef)
|
||||
else
|
||||
begin
|
||||
inserttypeconv_internal(left,charpointertype);
|
||||
inserttypeconv_internal(right,charpointertype);
|
||||
end;
|
||||
{$else}
|
||||
inserttypeconv_internal(left,charpointertype);
|
||||
inserttypeconv_internal(right,charpointertype);
|
||||
|
@ -754,19 +754,62 @@ implementation
|
||||
procedure thlcgwasm.a_cmp_const_ref_stack(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; const ref: treference);
|
||||
var
|
||||
tmpref: treference;
|
||||
regtyp: TRegisterType;
|
||||
begin
|
||||
tmpref:=ref;
|
||||
if tmpref.base<>NR_EVAL_STACK_BASE then
|
||||
a_load_ref_stack(list,size,tmpref,prepare_stack_for_ref(list,tmpref,false));
|
||||
a_load_const_stack(list,size,a,def2regtyp(size));
|
||||
a_cmp_stack_stack(list,size,cmp_op);
|
||||
regtyp:=def2regtyp(size);
|
||||
case regtyp of
|
||||
R_EXTERNREFREGISTER,
|
||||
R_FUNCREFREGISTER:
|
||||
begin
|
||||
if a<>0 then
|
||||
internalerror(2023061103);
|
||||
if not (cmp_op in [OC_EQ,OC_NE]) then
|
||||
internalerror(2023061104);
|
||||
list.Concat(taicpu.op_none(a_ref_is_null));
|
||||
if cmp_op=OC_NE then
|
||||
begin
|
||||
a_load_const_stack(list,s32inttype,0,R_INTREGISTER);
|
||||
a_cmp_stack_stack(list,s32inttype,OC_EQ);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
a_load_const_stack(list,size,a,regtyp);
|
||||
a_cmp_stack_stack(list,size,cmp_op);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgwasm.a_cmp_const_reg_stack(list: TAsmList; size: tdef; cmp_op: topcmp; a: tcgint; reg: tregister);
|
||||
var
|
||||
regtyp: TRegisterType;
|
||||
begin
|
||||
a_load_reg_stack(list,size,reg);
|
||||
a_load_const_stack(list,size,a,def2regtyp(size));
|
||||
a_cmp_stack_stack(list,size,cmp_op);
|
||||
regtyp:=def2regtyp(size);
|
||||
case regtyp of
|
||||
R_EXTERNREFREGISTER,
|
||||
R_FUNCREFREGISTER:
|
||||
begin
|
||||
if a<>0 then
|
||||
internalerror(2023061105);
|
||||
if not (cmp_op in [OC_EQ,OC_NE]) then
|
||||
internalerror(2023061106);
|
||||
list.Concat(taicpu.op_none(a_ref_is_null));
|
||||
if cmp_op=OC_NE then
|
||||
begin
|
||||
a_load_const_stack(list,s32inttype,0,R_INTREGISTER);
|
||||
a_cmp_stack_stack(list,s32inttype,OC_EQ);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
a_load_const_stack(list,size,a,regtyp);
|
||||
a_cmp_stack_stack(list,size,cmp_op);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgwasm.a_cmp_ref_reg_stack(list: TAsmList; size: tdef; cmp_op: topcmp; const ref: treference; reg: tregister);
|
||||
|
@ -33,6 +33,16 @@ begin
|
||||
testproc5 := nil;
|
||||
end;
|
||||
|
||||
function testproc6: Boolean;
|
||||
var
|
||||
q: WasmExternRef;
|
||||
begin
|
||||
testproc6 := q = nil;
|
||||
testproc6 := nil = q;
|
||||
testproc6 := q <> nil;
|
||||
testproc6 := nil <> q;
|
||||
end;
|
||||
|
||||
begin
|
||||
testproc5(nil);
|
||||
end.
|
||||
|
@ -38,6 +38,16 @@ begin
|
||||
testproc5 := nil;
|
||||
end;
|
||||
|
||||
function testproc6: Boolean;
|
||||
var
|
||||
q: TWasmFuncRef;
|
||||
begin
|
||||
testproc6 := q = nil;
|
||||
testproc6 := nil = q;
|
||||
testproc6 := q <> nil;
|
||||
testproc6 := nil <> q;
|
||||
end;
|
||||
|
||||
begin
|
||||
testproc5(nil);
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user