Browse Source

[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 <[email protected]>
Date: Wed, 18 Sep 2019 20:19:50 -0400

git-svn-id: branches/wasm@45920 -
nickysn 5 years ago
parent
commit
9cf5db938e
4 changed files with 52 additions and 14 deletions
  1. 2 5
      compiler/wasm/agwat.pas
  2. 16 4
      compiler/wasm/hlcgcpu.pas
  3. 27 0
      compiler/wasm/nwasmflw.pas
  4. 7 5
      compiler/wasm/tgcpu.pas

+ 2 - 5
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 :

+ 16 - 4
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);

+ 27 - 0
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 }

+ 7 - 5
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;