From b9ca30165cefbe0d857c4f2d32bbb6718b141bc5 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Sun, 15 Sep 2024 00:48:59 +0300 Subject: [PATCH] * WebAssembly: refactored tai_local, so that it is a single directive, containing multiple locals, instead of creating multiple tai_local directives, each containing a single local. No functional changes. --- compiler/aggas.pas | 27 ++++++++++++++++++--------- compiler/ogwasm.pas | 4 +++- compiler/wasm32/aasmcpu.pas | 23 +++++++++++++++++------ compiler/wasm32/agwasa.pas | 12 ++++++++---- compiler/wasm32/cpubase.pas | 1 + compiler/wasm32/cpupi.pas | 22 +++++++--------------- 6 files changed, 54 insertions(+), 35 deletions(-) diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 5e9cf8034d..b08242b90a 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -839,6 +839,23 @@ implementation end; writer.AsmLn; end; + + procedure WriteWasmLocalDirective(hp: tai_local); + var + t: TWasmBasicType; + first: boolean=true; + begin + writer.AsmWrite(#9'.local'#9); + for t in tai_local(hp).locals do + begin + if first then + first:=false + else + writer.AsmWrite(', '); + writer.AsmWrite(gas_wasm_basic_type_str[t]); + end; + writer.AsmLn; + end; {$endif WASM} var @@ -1638,15 +1655,7 @@ implementation {$ifdef WASM} ait_local: - begin - if tai_local(hp).first then - writer.AsmWrite(#9'.local'#9) - else - writer.AsmWrite(', '); - writer.AsmWrite(gas_wasm_basic_type_str[tai_local(hp).bastyp]); - if tai_local(hp).last then - writer.AsmLn; - end; + WriteWasmLocalDirective(tai_local(hp)); ait_globaltype: begin writer.AsmWrite(#9'.globaltype'#9); diff --git a/compiler/ogwasm.pas b/compiler/ogwasm.pas index 8301097ba7..0f40336c5e 100644 --- a/compiler/ogwasm.pas +++ b/compiler/ogwasm.pas @@ -1206,9 +1206,11 @@ implementation procedure TWasmObjData.DeclareLocal(al: tai_local); var ObjSymExtraData: TWasmObjSymbolExtraData; + t: TWasmBasicType; begin ObjSymExtraData:=TWasmObjSymbolExtraData(FObjSymbolsExtraDataList.Find(FLastFuncName)); - ObjSymExtraData.AddLocal(al.bastyp); + for t in al.locals do + ObjSymExtraData.AddLocal(t); end; procedure TWasmObjData.symbolpairdefine(akind: TSymbolPairKind; const asym, avalue: string); diff --git a/compiler/wasm32/aasmcpu.pas b/compiler/wasm32/aasmcpu.pas index b91fce546e..37956bda82 100644 --- a/compiler/wasm32/aasmcpu.pas +++ b/compiler/wasm32/aasmcpu.pas @@ -325,10 +325,10 @@ uses { tai_local } tai_local = class(tai) - bastyp: TWasmBasicType; - first: boolean; - last: boolean; - constructor create(abasictype: TWasmBasicType); + locals: TWasmLocalsDynArray; + constructor create(alocals: TWasmLocalsDynArray); + procedure AddLocal(abasictype: TWasmBasicType); + procedure AddLocals(alocals: TWasmLocalsDynArray); end; { tai_globaltype } @@ -1892,13 +1892,24 @@ uses { tai_local } - constructor tai_local.create(abasictype: TWasmBasicType); + constructor tai_local.create(alocals: TWasmLocalsDynArray); begin inherited Create; - bastyp := abasictype; + locals := Copy(alocals); typ := ait_local; end; + procedure tai_local.AddLocal(abasictype: TWasmBasicType); + begin + SetLength(locals,Length(locals)+1); + locals[high(locals)]:=abasictype; + end; + + procedure tai_local.AddLocals(alocals: TWasmLocalsDynArray); + begin + locals:=Concat(locals,alocals); + end; + { timpexp_ai } constructor tai_export_name.create(const aextname, aintname: ansistring; diff --git a/compiler/wasm32/agwasa.pas b/compiler/wasm32/agwasa.pas index ba57ecd621..4d98eb835e 100644 --- a/compiler/wasm32/agwasa.pas +++ b/compiler/wasm32/agwasa.pas @@ -401,6 +401,7 @@ implementation i,pos : longint; InlineLevel : longint; do_line : boolean; + t: TWasmBasicType; const WasmBasicTypeStr : array [TWasmBasicType] of string = ('unknown','i32','i64','f32','f64','funcref','externref','v128'); @@ -621,10 +622,13 @@ implementation ait_local : begin - writer.AsmWrite(#9#9'(local '); - writer.AsmWrite( WasmBasicTypeStr[ tai_local(hp).bastyp ] ); - writer.AsmWrite(')'); - writer.AsmLn; + for t in tai_local(hp).locals do + begin + writer.AsmWrite(#9#9'(local '); + writer.AsmWrite( WasmBasicTypeStr[ t ] ); + writer.AsmWrite(')'); + writer.AsmLn; + end; end; else diff --git a/compiler/wasm32/cpubase.pas b/compiler/wasm32/cpubase.pas index 18b154e1f3..017b4d938e 100644 --- a/compiler/wasm32/cpubase.pas +++ b/compiler/wasm32/cpubase.pas @@ -140,6 +140,7 @@ uses wbt_v128 ); TWasmResultType = array of TWasmBasicType; + TWasmLocalsDynArray = array of TWasmBasicType; { TWasmFuncType } diff --git a/compiler/wasm32/cpupi.pas b/compiler/wasm32/cpupi.pas index 865c477acb..7254f54221 100644 --- a/compiler/wasm32/cpupi.pas +++ b/compiler/wasm32/cpupi.pas @@ -897,12 +897,11 @@ implementation function prepare_locals: TAsmList; var local: tai_local; - first: Boolean; l : TWasmLocal; begin result:=TAsmList.create; - local:=nil; - first:=true; + local:=tai_local.create([]); + result.Concat(local); l:=ttgwasm(tg).localvars.first; FFuncType:=findfirst_tai_functype(aktproccode).functype; FLocals:=Copy(FFuncType.params); @@ -912,30 +911,23 @@ implementation begin SetLength(FLocals,Length(FLocals)+1); FLocals[High(FLocals)]:=l.typ; - local:=tai_local.create(l.typ); - local.first:=first; - first:=false; - result.Concat(local); + local.AddLocal(l.typ); l:=l.nextseq; Inc(FFirstFreeLocal); end; end; procedure add_extra_allocated_locals(localslist: TAsmList); - var - t: TWasmBasicType; begin - for t in FAllocatedLocals do - localslist.Concat(tai_local.create(t)); + if tai(localslist.First).typ<>ait_local then + internalerror(2024081501); + tai_local(localslist.First).AddLocals(FAllocatedLocals); end; procedure insert_localslist(destlist,localslist: TAsmList); begin if assigned(localslist) then - begin - tai_local(localslist.Last).last:=true; - destlist.insertListAfter(findfirst_tai_functype(destlist),localslist); - end; + destlist.insertListAfter(findfirst_tai_functype(destlist),localslist); end; procedure check_goto_br_instructions(list: TAsmList; out HasGotoBrInstructions: boolean);