From 9cf5db938e81eca0a429a8fd80dd2b1146bb0944 Mon Sep 17 00:00:00 2001 From: nickysn Date: Wed, 29 Jul 2020 17:43:20 +0000 Subject: [PATCH] [PATCH 43/83] update flow control, adding support for continue and break labels update temp var allocation update stack prepare allocation From d6342bd3096ca4d6866e1a2bf886f7a713f50e66 Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev Date: Wed, 18 Sep 2019 20:19:50 -0400 git-svn-id: branches/wasm@45920 - --- compiler/wasm/agwat.pas | 7 ++----- compiler/wasm/hlcgcpu.pas | 20 ++++++++++++++++---- compiler/wasm/nwasmflw.pas | 27 +++++++++++++++++++++++++++ compiler/wasm/tgcpu.pas | 12 +++++++----- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/compiler/wasm/agwat.pas b/compiler/wasm/agwat.pas index ecededb0d5..b7a7bcf5ee 100644 --- a/compiler/wasm/agwat.pas +++ b/compiler/wasm/agwat.pas @@ -475,11 +475,8 @@ implementation ait_label : begin - if (tai_label(hp).labsym.is_used) then - begin - writer.AsmWrite(tai_label(hp).labsym.name); - writer.AsmWriteLn(':'); - end; + // don't write any labels. Wasm don't support it + // labels are only allowed with the respective block structures end; ait_symbol : diff --git a/compiler/wasm/hlcgcpu.pas b/compiler/wasm/hlcgcpu.pas index e1b3b368ee..01baf77c2a 100644 --- a/compiler/wasm/hlcgcpu.pas +++ b/compiler/wasm/hlcgcpu.pas @@ -853,10 +853,10 @@ implementation case cmp_op of OC_EQ: //list.concat(taicpu.op_sym(a_i64_eq,lab)); - list.concat(taicpu.op_none(a_i64_eq)); + list.concat(taicpu.op_none(a_i32_eq)); OC_NE: //list.concat(taicpu.op_sym(a_i64_ne,lab)); - list.concat(taicpu.op_none(a_i64_ne)); + list.concat(taicpu.op_none(a_i32_ne)); else internalerror(2010120537); end; @@ -997,7 +997,7 @@ implementation begin result:=0; { fake location that indicates the value is already on the stack? } - if (ref.base=NR_EVAL_STACK_BASE) then + if (ref.base=NR_EVAL_STACK_BASE) or (ref.islocal) then exit; // setting up memory offset @@ -1321,7 +1321,19 @@ implementation procedure thlcgwasm.a_jmp_always(list: TAsmList; l: tasmlabel); begin - list.concat(taicpu.op_sym(a_br,current_asmdata.RefAsmSymbol(l.name,AT_METADATA))); + //todo: for proper jumping it's necessary to check + // all active blocks (if, block, loops) + // and jump to the proper one. + //list.concat(taicpu.op_const(a_i32_const, 0)); + if l = current_procinfo.CurrBreakLabel then begin + // todo: this should be moved to node generator pass2 + list.concat(taicpu.op_const(a_i32_const, 0)); + list.concat(taicpu.op_const(a_br,1)) + end else if l = current_procinfo.CurrContinueLabel then begin + list.concat(taicpu.op_const(a_i32_const, 0)); + list.concat(taicpu.op_const(a_br,0)) + end else + //Internalerror(2019091806); // unexpected jump end; procedure thlcgwasm.concatcopy_normal_array(list: TAsmList; size: tdef; const source, dest: treference); diff --git a/compiler/wasm/nwasmflw.pas b/compiler/wasm/nwasmflw.pas index 63e6ac7858..a6116b3dc7 100644 --- a/compiler/wasm/nwasmflw.pas +++ b/compiler/wasm/nwasmflw.pas @@ -76,13 +76,34 @@ begin end; procedure twasmwhilerepeatnode.pass_generate_code; +var + lcont,lbreak,lloop, + oldclabel,oldblabel : tasmlabel; + truelabel,falselabel : tasmlabel; + oldflowcontrol : tflowcontrol; begin + location_reset(location,LOC_VOID,OS_NO); + + current_asmdata.getjumplabel(lloop); + current_asmdata.getjumplabel(lcont); + current_asmdata.getjumplabel(lbreak); + + oldflowcontrol:=flowcontrol; + oldclabel:=current_procinfo.CurrContinueLabel; + oldblabel:=current_procinfo.CurrBreakLabel; + + include(flowcontrol,fc_inflowcontrol); + exclude(flowcontrol,fc_unwind_loop); + current_asmdata.CurrAsmList.concat(taicpu.op_none(a_block)); current_asmdata.CurrAsmList.concat(taicpu.op_none(a_loop)); if lnf_testatbegin in loopflags then pass_generate_code_condition; + current_procinfo.CurrContinueLabel:=lcont; + current_procinfo.CurrBreakLabel:=lbreak; + secondpass(right); if not (lnf_testatbegin in loopflags) then @@ -92,6 +113,12 @@ begin current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end)); current_asmdata.CurrAsmList.concat(taicpu.op_none(a_end)); + + current_procinfo.CurrContinueLabel:=oldclabel; + current_procinfo.CurrBreakLabel:=oldblabel; + { a break/continue in a while/repeat block can't be seen outside } + flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue,fc_inflowcontrol]); + end; { twasmifnode } diff --git a/compiler/wasm/tgcpu.pas b/compiler/wasm/tgcpu.pas index d0be2b6bd9..15c0c64ff5 100644 --- a/compiler/wasm/tgcpu.pas +++ b/compiler/wasm/tgcpu.pas @@ -367,8 +367,13 @@ unit tgcpu; procedure ttgwasm.gethltemp(list: TAsmList; def: tdef; forcesize: asizeint; temptype: ttemptype; out ref: treference); + var + wbt: TWasmBasicType; begin - inherited; + if Assigned(def) and defToWasmBasic(def, wbt) then begin + allocLocalVarToRef(wbt, ref); + end else + inherited; end; procedure ttgwasm.gethltempmanaged(list: TAsmList; def: tdef; temptype: ttemptype; out ref: treference); @@ -390,11 +395,8 @@ unit tgcpu; end; procedure ttgwasm.localVarToRef(idx: integer; size: integer; out ref: treference); - var - t: treftemppos; begin - t.val:=idx; - reference_reset_base(ref, current_procinfo.framepointer,idx,t,size,[]); + reference_reset_base(ref, current_procinfo.framepointer,idx,ctempposinvalid,size,[]); ref.islocal := true; updateFirstTemp; end;