···23232424### Tools:
25252626+- #3959, #7202, #10476: ocaml, in script mode, directive errors
2727+ (`#use "missing_file";;`) use stderr and exit with an error.
2828+ (Florian Angeletti, review by Gabriel Scherer)
2929+2630### Manual and documentation:
27312832- #7812, #10475: reworded the description of the behaviors of
···5963- #10472: refactor caml_sys_random_seed to ease future Multicore changes
6064 (Gabriel Scherer, review by Xavier Leroy)
61656666+- #10487: Move logic to get the type path from a constructor return type in
6767+ Types
6868+ (Nicolas Chataing, review by Jacques Garrigue)
6969+6270### Build system:
63716472### Bug fixes:
···6775 This allows stacktraces to work in gdb through C and OCaml calls.
6876 (Edwin Török, review by Nicolás Ojeda Bär and Xavier Leroy)
69777878+- #10461: `caml_send*` helper functions take derived pointers as arguments.
7979+ Those must be declared with type Addr instead of Val.
8080+ (Vincent Laviron, review by Xavier Leroy)
8181+8282+7083OCaml 4.13.0
7184-------------
72857386### Language features:
8787+8888+- #10039: Safepoints
8989+ Add poll points to native generated code. These are effectively
9090+ zero-sized allocations and fix some signal and remembered set
9191+ issues. Also multicore prerequisite.
9292+ (Sadiq Jaffer, Damien Doligez, Mark Shinwell, Anmol Sahoo, Stephen Dolan,
9393+ Xavier Leroy reviewed by ??)
74947595- #9331: Improve error messages for functor application and functor types.
7696 (Florian Angeletti and Gabriel Radanne, review by Leo White)
+3
INSTALL.adoc
···2020* Under Cygwin, the `gcc-core` package is required. `flexdll` is also necessary
2121 for shared library support.
22222323+* Binutils including `ar`, `ranlib`, and `strip` are required if your
2424+ distribution does not already provide them with the C compiler.
2525+2326== Configuration
24272528From the top directory, do:
+41-1
asmcomp/arm64/emit.mlp
···410410 loop instr.next (call_gc + 1, check_bound)
411411 | Lop (Ipoll _) ->
412412 loop instr.next (call_gc + 1, check_bound)
413413+ | Lop (Ipoll _) ->
414414+ loop instr.next (call_gc + 1, check_bound)
413415 | Lop (Iintop Icheckbound)
414416 | Lop (Iintop_imm (Icheckbound, _))
415417 | Lop (Ispecific (Ishiftcheckbound _)) ->
···644646 ` and {emit_reg r}, {emit_reg reg_alloc_ptr}, #{emit_nativeint dom_mask}\n`;
645647 ` ldr {emit_reg r}, [{emit_reg r}, #{emit_int domain_field}]`
646648649649+let assembly_code_for_poll env i ~far ~return_label =
650650+ let lbl_frame = record_frame_label env i.live (Dbg_alloc []) in
651651+ let lbl_call_gc = new_label() in
652652+ let lbl_after_poll = match return_label with
653653+ | None -> new_label()
654654+ | Some lbl -> lbl in
655655+ let offset = Domainstate.(idx_of_field Domain_young_limit) * 8 in
656656+ ` ldr {emit_reg reg_tmp1}, [{emit_reg reg_domain_state_ptr}, #{emit_int offset}]\n`;
657657+ ` cmp {emit_reg reg_alloc_ptr}, {emit_reg reg_tmp1}\n`;
658658+ if not far then begin
659659+ match return_label with
660660+ | None ->
661661+ ` b.ls {emit_label lbl_call_gc}\n`;
662662+ `{emit_label lbl_after_poll}:\n`
663663+ | Some return_label ->
664664+ ` b.hi {emit_label return_label}\n`;
665665+ ` b {emit_label lbl_call_gc}\n`;
666666+ end else begin
667667+ match return_label with
668668+ | None ->
669669+ ` b.hi {emit_label lbl_after_poll}\n`;
670670+ ` b {emit_label lbl_call_gc}\n`;
671671+ `{emit_label lbl_after_poll}:\n`
672672+ | Some return_label ->
673673+ let lbl = new_label () in
674674+ ` b.ls {emit_label lbl}\n`;
675675+ ` b {emit_label return_label}\n`;
676676+ `{emit_label lbl}: b {emit_label lbl_call_gc}\n`
677677+ end;
678678+ env.call_gc_sites <-
679679+ { gc_lbl = lbl_call_gc;
680680+ gc_return_lbl = lbl_after_poll;
681681+ gc_frame_lbl = lbl_frame; } :: env.call_gc_sites
682682+647683(* Output .text section directive, or named .text.caml.<name> if enabled. *)
648684649685let emit_named_text_section func_name =
···803839 | Lop(Ialloc { bytes = n; dbginfo }) ->
804840 assembly_code_for_allocation i ~n ~far:false ~dbginfo
805841 | Lop(Ispecific (Ifar_alloc { bytes = n; dbginfo })) ->
806806- assembly_code_for_allocation i ~n ~far:true ~dbginfo
842842+ assembly_code_for_allocation env i ~n ~far:true ~dbginfo
843843+ | Lop(Ipoll { return_label }) ->
844844+ assembly_code_for_poll env i ~far:false ~return_label
845845+ | Lop(Ispecific (Ifar_poll { return_label })) ->
846846+ assembly_code_for_poll env i ~far:true ~return_label
807847 | Lop(Iintop_imm(Iadd, n)) ->
808848 emit_addimm i.res.(0) i.arg.(0) n
809849 | Lop(Iintop_imm(Isub, n)) ->
···5151 in
5252 match instr.desc with
5353 | Lop (Ialloc _)
5454+ | Lop (Ipoll { return_label = None })
5455 | Lop (Iintop (Icheckbound))
5556 | Lop (Iintop_imm (Icheckbound, _))
5657 | Lop (Ispecific _) ->
···6465 opt_branch_overflows map pc lbl0 max_branch_offset
6566 || opt_branch_overflows map pc lbl1 max_branch_offset
6667 || opt_branch_overflows map pc lbl2 max_branch_offset
6868+ | Lop (Ipoll { return_label = Some lbl }) ->
6969+ (* A poll-and-branch instruction can branch to the label lbl,
7070+ but also to an out-of-line code block. *)
7171+ code_size + max_out_of_line_code_offset - pc >= max_branch_offset
7272+ || branch_overflows map pc lbl max_branch_offset
6773 | _ ->
6874 Misc.fatal_error "Unsupported instruction for branch relaxation"
6975···8692 fixup did_fix (pc + T.instr_size f instr.desc) instr.next
8793 else
8894 match instr.desc with
9595+ | Lop (Ipoll { return_label }) ->
9696+ instr.desc <- T.relax_poll ~return_label;
9797+ fixup true (pc + T.instr_size f instr.desc) instr.next
8998 | Lop (Ialloc { bytes = num_bytes; dbginfo }) ->
9099 instr.desc <- T.relax_allocation ~num_bytes ~dbginfo;
91100 fixup true (pc + T.instr_size f instr.desc) instr.next
+1-1
asmcomp/cmm_helpers.ml
···18771877 let cache = cache in
18781878 let fun_name = "caml_send" ^ Int.to_string arity in
18791879 let fun_args =
18801880- [obj, typ_val; tag, typ_int; cache, typ_val]
18801880+ [obj, typ_val; tag, typ_int; cache, typ_addr]
18811881 @ List.map (fun id -> (id, typ_val)) (List.tl args) in
18821882 let fun_dbg = placeholder_fun_dbg ~human_name:fun_name in
18831883 Cfunction
+2-1
asmcomp/i386/selection.ml
···321321322322end
323323324324-let fundecl f = (new selector)#emit_fundecl f
324324+let fundecl ~future_funcnames f = (new selector)#emit_fundecl
325325+ ~future_funcnames f
···258258259259 | Typedtree.Tpat_construct (_, cons_desc, _, _) when
260260 (* we give a name to the parameter only if it is unit *)
261261- (match get_desc cons_desc.cstr_res with
262262- Tconstr (p, _, _) ->
263263- Path.same p Predef.path_unit
264264- | _ ->
265265- false)
261261+ Path.same (Btype.cstr_type_path cons_desc) Predef.path_unit
266262 ->
267263 (* a () argument, it never has description *)
268264 Simple_name { sn_name = "()" ;
+2-2
stdlib/string.mli
···161161(** [starts_with ][~][prefix s] is [true] if and only if [s] starts with
162162 [prefix].
163163164164- @since 4.12.0 *)
164164+ @since 4.13.0 *)
165165166166val ends_with :
167167 suffix (* comment thwarts tools/sync_stdlib_docs *) :string -> string -> bool
168168(** [ends_with suffix s] is [true] if and only if [s] ends with [suffix].
169169170170- @since 4.12.0 *)
170170+ @since 4.13.0 *)
171171172172val contains_from : string -> int -> char -> bool
173173(** [contains_from s start c] is [true] if and only if [c] appears in [s]
+2-2
stdlib/stringLabels.mli
···161161(** [starts_with ][~][prefix s] is [true] if and only if [s] starts with
162162 [prefix].
163163164164- @since 4.12.0 *)
164164+ @since 4.13.0 *)
165165166166val ends_with :
167167 suffix (* comment thwarts tools/sync_stdlib_docs *) :string -> string -> bool
168168(** [ends_with ~suffix s] is [true] if and only if [s] ends with [suffix].
169169170170- @since 4.12.0 *)
170170+ @since 4.13.0 *)
171171172172val contains_from : string -> int -> char -> bool
173173(** [contains_from s start c] is [true] if and only if [c] appears in [s]
+8
testsuite/tests/asmgen/main.c
···2727}
2828#endif
29293030+/* This stub isn't needed for msvc32, since it's already in asmgen_i386nt.asm */
3131+#if !defined(_MSC_VER) || !defined(_M_IX86)
3232+void caml_call_gc()
3333+{
3434+3535+}
3636+#endif
3737+3038void caml_ml_array_bound_error(void)
3139{
3240 fprintf(stderr, "Fatal error: out-of-bound access in array or string\n");
···24172417 | exception Not_found -> ()
2418241824192419let mark_constructor_description_used usage env cstr =
24202420- let ty_path =
24212421- match get_desc cstr.cstr_res with
24222422- | Tconstr(path, _, _) -> path
24232423- | _ -> assert false
24242424- in
24202420+ let ty_path = Btype.cstr_type_path cstr in
24252421 mark_type_path_used env ty_path;
24262422 match Types.Uid.Tbl.find !used_constructors cstr.cstr_uid with
24272423 | mark -> mark usage
+1-4
typing/typecore.ml
···387387388388(* unification of a type with a Tconstr with freshly created arguments *)
389389let unify_head_only ~refine loc env ty constr =
390390- let path =
391391- match get_desc constr.cstr_res with
392392- | Tconstr(p, _, _) -> p
393393- | _ -> assert false in
390390+ let path = cstr_type_path constr in
394391 let decl = Env.find_type path !env in
395392 let ty' = Ctype.newconstr path (Ctype.instance_list decl.type_params) in
396393 unify_pat_types ~refine loc env ty' ty
+2-7
typing/typedecl.ml
···10351035 typext_params
10361036 end;
10371037 (* Ensure that constructor's type matches the type being extended *)
10381038- let cstr_type_path, cstr_type_params =
10391039- match get_desc cdescr.cstr_res with
10401040- Tconstr (p, _, _) ->
10411041- let decl = Env.find_type p env in
10421042- p, decl.type_params
10431043- | _ -> assert false
10441044- in
10381038+ let cstr_type_path = Btype.cstr_type_path cdescr in
10391039+ let cstr_type_params = (Env.find_type cstr_type_path env).type_params in
10451040 let cstr_types =
10461041 (Btype.newgenty
10471042 (Tconstr(cstr_type_path, cstr_type_params, ref Mnil)))