浏览代码

+ insert exception flag check and branch after each function call, when
compiling in WebAssembly branchful exceptions mode

Nikolay Nikolov 3 年之前
父节点
当前提交
7afb665c92
共有 4 个文件被更改,包括 39 次插入1 次删除
  1. 22 0
      compiler/wasm32/hlcgcpu.pas
  2. 3 1
      compiler/wasm32/nwasmcal.pas
  3. 4 0
      rtl/inc/compproc.inc
  4. 10 0
      rtl/wasm32/except_branchful.inc

+ 22 - 0
compiler/wasm32/hlcgcpu.pas

@@ -148,6 +148,7 @@ uses
       { Wasm-specific routines }
       { Wasm-specific routines }
 
 
       procedure g_procdef(list:TAsmList;pd: tprocdef);
       procedure g_procdef(list:TAsmList;pd: tprocdef);
+      procedure g_checkexceptions(list:TasmList);
 
 
       procedure a_load_stack_reg(list : TAsmList;size: tdef;reg: tregister);
       procedure a_load_stack_reg(list : TAsmList;size: tdef;reg: tregister);
       { extra_slots are the slots that are used by the reference, and that
       { extra_slots are the slots that are used by the reference, and that
@@ -2266,6 +2267,27 @@ implementation
       list.Concat(tai_functype.create(pd.mangledname,tcpuprocdef(pd).create_functype));
       list.Concat(tai_functype.create(pd.mangledname,tcpuprocdef(pd).create_functype));
     end;
     end;
 
 
+  procedure thlcgwasm.g_checkexceptions(list: TasmList);
+    var
+      pd: tprocdef;
+    begin
+      if not (ts_wasm_bf_exceptions in current_settings.targetswitches) then
+        internalerror(2021100501);
+
+      pd:=search_system_proc('fpc_raised_exception_flag');
+      g_call_system_proc(list,pd,[],nil).resetiftemp;
+
+      list.concat(taicpu.op_none(A_IF));
+      incblock;
+
+      decstack(current_asmdata.CurrAsmList,1);
+
+      list.concat(taicpu.op_const(a_br,br_blocks-raiseBr));
+
+      list.concat(taicpu.op_none(A_END_IF));
+      decblock;
+    end;
+
   procedure thlcgwasm.a_load_stack_reg(list: TAsmList; size: tdef; reg: tregister);
   procedure thlcgwasm.a_load_stack_reg(list: TAsmList; size: tdef; reg: tregister);
     begin
     begin
       list.concat(taicpu.op_reg(a_local_set,reg));
       list.concat(taicpu.op_reg(a_local_set,reg));

+ 3 - 1
compiler/wasm32/nwasmcal.pas

@@ -49,13 +49,15 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-      globtype, aasmdata, defutil, tgobj, hlcgcpu, symconst, symcpu;
+      globals, globtype, aasmdata, defutil, tgobj, hlcgcpu, symconst, symcpu;
 
 
       { twasmcallnode }
       { twasmcallnode }
 
 
     procedure twasmcallnode.extra_post_call_code;
     procedure twasmcallnode.extra_post_call_code;
       begin
       begin
         thlcgwasm(hlcg).g_adjust_stack_after_call(current_asmdata.CurrAsmList,procdefinition);
         thlcgwasm(hlcg).g_adjust_stack_after_call(current_asmdata.CurrAsmList,procdefinition);
+        if ts_wasm_bf_exceptions in current_settings.targetswitches then
+          thlcgwasm(hlcg).g_checkexceptions(current_asmdata.CurrAsmList);
       end;
       end;
 
 
     procedure twasmcallnode.do_release_unused_return_value;
     procedure twasmcallnode.do_release_unused_return_value;

+ 4 - 0
rtl/inc/compproc.inc

@@ -715,6 +715,10 @@ procedure fpc_dispatch_by_id(Result: Pointer; const Dispatch: pointer;DispDesc:
 Function fpc_PushExceptAddr (Ft: {$ifdef CPU16}SmallInt{$else}Longint{$endif};_buf,_newaddr : pointer): PJmp_buf ; compilerproc;
 Function fpc_PushExceptAddr (Ft: {$ifdef CPU16}SmallInt{$else}Longint{$endif};_buf,_newaddr : pointer): PJmp_buf ; compilerproc;
 Procedure fpc_PopAddrStack; compilerproc;
 Procedure fpc_PopAddrStack; compilerproc;
 {$endif}
 {$endif}
+{$ifdef FPC_WASM_BRANCHFUL_EXCEPTIONS}
+function fpc_raised_exception_flag: Boolean;compilerproc;
+procedure fpc_clear_exception_flag;compilerproc;
+{$endif FPC_WASM_BRANCHFUL_EXCEPTIONS}
 procedure fpc_Raiseexception (Obj : TObject; AnAddr : CodePointer; AFrame : Pointer); compilerproc;
 procedure fpc_Raiseexception (Obj : TObject; AnAddr : CodePointer; AFrame : Pointer); compilerproc;
 function fpc_PopObjectStack : TObject; compilerproc;
 function fpc_PopObjectStack : TObject; compilerproc;
 function fpc_PopSecondObjectStack : TObject; compilerproc;
 function fpc_PopSecondObjectStack : TObject; compilerproc;

+ 10 - 0
rtl/wasm32/except_branchful.inc

@@ -30,6 +30,16 @@ Var
 {$i psabieh.inc}
 {$i psabieh.inc}
 {$endif}
 {$endif}
 
 
+function fpc_raised_exception_flag: Boolean;[public,alias:'FPC_RAISED_EXCEPTION_FLAG']compilerproc;
+begin
+  result:=RaisedException;
+end;
+
+procedure fpc_clear_exception_flag;[public,alias:'FPC_CLEAR_EXCEPTION_FLAG']compilerproc;
+begin
+  RaisedException:=false;
+end;
+
 Function RaiseList : PExceptObject;
 Function RaiseList : PExceptObject;
 begin
 begin
   RaiseList:=ExceptObjectStack;
   RaiseList:=ExceptObjectStack;