[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 <skalogryz.lists@gmail.com>
Date: Wed, 18 Sep 2019 20:19:50 -0400

git-svn-id: branches/wasm@45920 -
This commit is contained in:
nickysn 2020-07-29 17:43:20 +00:00
parent a1d18125ca
commit 9cf5db938e
4 changed files with 52 additions and 14 deletions

View File

@ -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 :

View File

@ -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);

View File

@ -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 }

View File

@ -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;