@@ -604,6 +604,8 @@ module Generate (Target : Target_sig.S) = struct
604604        in 
605605        Memory. allocate ~tag: 0  ~deadcode_sentinal: ctx.deadcode_sentinal l)
606606
607+   let  exception_handler_pc =  - 3 
608+ 
607609  let  rec  translate_expr  ctx  context  x  e  = 
608610    match  e with 
609611    |  Apply  { f; args; exact }
@@ -621,17 +623,21 @@ module Generate (Target : Target_sig.S) = struct
621623                  (load funct)
622624              in 
623625              let *  b =  is_closure f in 
626+               let  label =  label_index context exception_handler_pc in 
624627              if  b
625-               then  return (W. Call  (f, List. rev (closure :: acc)))
628+               then  return (W. Br_on_null  (label,  W. Call  (f, List. rev (closure :: acc) )))
626629              else 
627630                match  funct with 
628631                |  W. RefFunc  g  ->
629632                    (*  Functions with constant closures ignore their
630633                       environment. In case of partial application, we 
631634                       still need the closure. *)  
632635                    let *  cl =  if  exact then  Value. unit  else  return closure in 
633-                     return (W. Call  (g, List. rev (cl :: acc)))
634-                 |  _  -> return (W. Call_ref  (ty, funct, List. rev (closure :: acc))))
636+                     return (W. Br_on_null  (label, W. Call  (g, List. rev (cl :: acc))))
637+                 |  _  ->
638+                     return
639+                       (W. Br_on_null 
640+                          (label, W. Call_ref  (ty, funct, List. rev (closure :: acc)))))
635641          |  x  :: r  ->
636642              let *  x =  load x in 
637643              loop (x :: acc) r
@@ -643,7 +649,9 @@ module Generate (Target : Target_sig.S) = struct
643649        in 
644650        let *  args =  expression_list load args in 
645651        let *  closure =  load f in 
646-         return (W. Call  (apply, args @  [ closure ]))
652+         return
653+           (W. Br_on_null 
654+              (label_index context exception_handler_pc, W. Call  (apply, args @  [ closure ])))
647655    |  Block  (tag , a , _ , _ ) ->
648656        Memory. allocate
649657          ~deadcode_sentinal: ctx.deadcode_sentinal
@@ -869,32 +877,55 @@ module Generate (Target : Target_sig.S) = struct
869877          { params =  [] ; result =  []  }
870878          (body ~result_typ: []  ~fall_through: (`Block  pc) ~context: (`Block  pc :: context))
871879      in 
872-       if  List. is_empty result_typ
880+       if  true   &&   List. is_empty result_typ
873881      then  handler
874882      else 
875883        let *  ()  =  handler in 
876-         instr (W. Return  (Some  (RefI31  (Const  (I32  0l )))))
884+         let *  u =  Value. unit  in 
885+         instr (W. Return  (Some  u))
877886    else  body ~result_typ  ~fall_through  ~context 
878887
879-   let  wrap_with_handlers  p  pc  ~result_typ   ~fall_through   ~context   body  = 
888+   let  wrap_with_handlers  ~ location   p  pc  ~result_typ   ~fall_through   ~context   body  = 
880889    let  need_zero_divide_handler, need_bound_error_handler =  needed_handlers p pc in 
881890    wrap_with_handler
882-       need_bound_error_handler
883-       bound_error_pc
884-       (let *  f = 
885-          register_import ~name: " caml_bound_error" Fun  { params =  [] ; result =  []  })
886-        in 
887-        instr (CallInstr  (f, [] )))
891+       true 
892+       exception_handler_pc
893+       (match  location with 
894+       |  `Toplevel  ->
895+           let *  exn  = 
896+             register_import
897+               ~import_module: " env" 
898+               ~name: " caml_exception" 
899+               (Global  { mut =  true ; typ =  Type. value })
900+           in 
901+           let *  tag =  register_import ~name: exception_name (Tag  Type. value) in 
902+           instr (Throw  (tag, GlobalGet  exn ))
903+       |  `Exception_handler  ->
904+           let *  exn  = 
905+             register_import
906+               ~import_module: " env" 
907+               ~name: " caml_exception" 
908+               (Global  { mut =  true ; typ =  Type. value })
909+           in 
910+           instr (Br  (2 , Some  (GlobalGet  exn )))
911+       |  `Function  -> instr (Return  (Some  (RefNull  Any ))))
888912      (wrap_with_handler
889-          need_zero_divide_handler 
890-          zero_divide_pc 
913+          need_bound_error_handler 
914+          bound_error_pc 
891915         (let *  f = 
892-             register_import
893-               ~name: " caml_raise_zero_divide" 
894-               (Fun  { params =  [] ; result =  []  })
916+             register_import ~name: " caml_bound_error" Fun  { params =  [] ; result =  []  })
895917          in 
896918          instr (CallInstr  (f, [] )))
897-          body)
919+          (wrap_with_handler
920+             need_zero_divide_handler
921+             zero_divide_pc
922+             (let *  f = 
923+                register_import
924+                  ~name: " caml_raise_zero_divide" 
925+                  (Fun  { params =  [] ; result =  []  })
926+              in 
927+              instr (CallInstr  (f, [] )))
928+             body))
898929      ~result_typ 
899930      ~fall_through 
900931      ~context 
@@ -996,19 +1027,34 @@ module Generate (Target : Target_sig.S) = struct
9961027              instr (Br_table  (e, List. map ~f: dest l, dest a.(len -  1 )))
9971028          |  Raise  (x , _ ) -> (
9981029              let *  e =  load x in 
999-               let *  tag =  register_import ~name: exception_name (Tag  Type. value) in 
10001030              match  fall_through with 
10011031              |  `Catch  -> instr (Push  e)
10021032              |  `Block  _  |  `Return  |  `Skip  -> (
10031033                  match  catch_index context with 
10041034                  |  Some  i  -> instr (Br  (i, Some  e))
1005-                   |  None  -> instr (Throw  (tag, e))))
1035+                   |  None  ->
1036+                       if  Option. is_some name_opt
1037+                       then 
1038+                         let *  exn  = 
1039+                           register_import
1040+                             ~import_module: " env" 
1041+                             ~name: " caml_exception" 
1042+                             (Global  { mut =  true ; typ =  Type. value })
1043+                         in 
1044+                         let *  ()  =  instr (GlobalSet  (exn , e)) in 
1045+                         instr (Return  (Some  (RefNull  Any )))
1046+                       else 
1047+                         let *  tag = 
1048+                           register_import ~name: exception_name (Tag  Type. value)
1049+                         in 
1050+                         instr (Throw  (tag, e))))
10061051          |  Pushtrap  (cont , x , cont' ) ->
10071052              handle_exceptions
10081053                ~result_typ 
10091054                ~fall_through 
10101055                ~context: (extend_context fall_through context)
10111056                (wrap_with_handlers
1057+                    ~location: `Exception_handler 
10121058                   p
10131059                   (fst cont)
10141060                   (fun  ~result_typ   ~fall_through   ~context   ->
@@ -1079,6 +1125,10 @@ module Generate (Target : Target_sig.S) = struct
10791125           let *  ()  =  build_initial_env in 
10801126           let *  ()  = 
10811127             wrap_with_handlers
1128+                ~location: 
1129+                  (match  name_opt with 
1130+                  |  None  -> `Toplevel 
1131+                  |  Some  _  -> `Function )
10821132               p
10831133               pc
10841134               ~result_typ: [ Type. value ]
@@ -1130,7 +1180,9 @@ module Generate (Target : Target_sig.S) = struct
11301180               in 
11311181               let *  ()  =  instr (Drop  (Call  (f, [] ))) in 
11321182               cont)
1133-              ~init: (instr (Push  (RefI31  (Const  (I32  0l )))))
1183+              ~init: 
1184+                (let *  u =  Value. unit  in 
1185+                 instr (Push  u))
11341186             to_link)
11351187    in 
11361188    context.other_fields < - 
0 commit comments