diff --git a/compiler/bin-js_of_ocaml/check_runtime.ml b/compiler/bin-js_of_ocaml/check_runtime.ml index 12ebf6cf4a..490dd06834 100644 --- a/compiler/bin-js_of_ocaml/check_runtime.ml +++ b/compiler/bin-js_of_ocaml/check_runtime.ml @@ -46,6 +46,7 @@ let f (runtime_files, bytecode, target_env) = Config.set_target `JavaScript; Config.set_effects_backend `Disabled; Linker.reset (); + Generate.reset (); let runtime_files, builtin = List.partition_map runtime_files ~f:(fun name -> match Builtins.find name with diff --git a/compiler/bin-js_of_ocaml/compile.ml b/compiler/bin-js_of_ocaml/compile.ml index d70b682f38..39b836c264 100644 --- a/compiler/bin-js_of_ocaml/compile.ml +++ b/compiler/bin-js_of_ocaml/compile.ml @@ -166,6 +166,7 @@ let run Jsoo_cmdline.Arg.eval common; Config.set_effects_backend effects; Linker.reset (); + Generate.reset (); (match output_file with | `Stdout, _ -> () | `Name name, _ when debug_mem () -> Debug.start_profiling name diff --git a/compiler/bin-js_of_ocaml/link.ml b/compiler/bin-js_of_ocaml/link.ml index 7529d209fa..8cad3216e6 100644 --- a/compiler/bin-js_of_ocaml/link.ml +++ b/compiler/bin-js_of_ocaml/link.ml @@ -162,6 +162,7 @@ let f Config.set_target `JavaScript; Jsoo_cmdline.Arg.eval common; Linker.reset (); + Generate.reset (); let with_output f = match output_file with | None -> f stdout diff --git a/compiler/lib-dynlink/js_of_ocaml_compiler_dynlink.ml b/compiler/lib-dynlink/js_of_ocaml_compiler_dynlink.ml index 941997b98d..188f9f1ed4 100644 --- a/compiler/lib-dynlink/js_of_ocaml_compiler_dynlink.ml +++ b/compiler/lib-dynlink/js_of_ocaml_compiler_dynlink.ml @@ -45,6 +45,7 @@ let () = Config.set_effects_backend (Jsoo_runtime.Sys.Config.effects ()); Linker.reset (); List.iter aliases ~f:(fun (a, b) -> Primitive.alias a b); + Generate.reset (); (* this needs to stay synchronized with toplevel.js *) let toplevel_compile (s : string) (debug : Instruct.debug_event list array) : unit -> J.t = diff --git a/compiler/lib-runtime-files/gen/gen.ml b/compiler/lib-runtime-files/gen/gen.ml index a13ad8d38f..b2ff945784 100644 --- a/compiler/lib-runtime-files/gen/gen.ml +++ b/compiler/lib-runtime-files/gen/gen.ml @@ -73,6 +73,7 @@ let () = | `Effects b -> Js_of_ocaml_compiler.Config.set_effects_backend b); List.iter Js_of_ocaml_compiler.Target_env.all ~f:(fun target_env -> Js_of_ocaml_compiler.Linker.reset (); + Js_of_ocaml_compiler.Generate.reset (); List.iter fragments ~f:(fun (filename, frags) -> Js_of_ocaml_compiler.Linker.load_fragments ~target_env ~filename frags); let linkinfos = Js_of_ocaml_compiler.Linker.init () in diff --git a/compiler/lib/annot_lexer.mll b/compiler/lib/annot_lexer.mll index 7addab857b..1e788d3f1d 100644 --- a/compiler/lib/annot_lexer.mll +++ b/compiler/lib/annot_lexer.mll @@ -25,6 +25,7 @@ rule main = parse | "Requires" {TRequires} | "Version" {TVersion} | "Weakdef" {TWeakdef} + | "Inline" {TInline} | "Always" {TAlways} | "If" {TIf} | "Alias" {TAlias} diff --git a/compiler/lib/annot_parser.mly b/compiler/lib/annot_parser.mly index 8736533a13..00f76e3670 100644 --- a/compiler/lib/annot_parser.mly +++ b/compiler/lib/annot_parser.mly @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -%token TProvides TRequires TVersion TWeakdef TIf TAlways TAlias +%token TProvides TRequires TVersion TWeakdef TInline TIf TAlways TAlias %token TA_Pure TA_Const TA_Mutable TA_Mutator TA_Shallow TA_Object_literal %token TIdent TIdent_percent TVNum %token TComma TColon EOF EOL LE LT GE GT EQ LPARENT RPARENT @@ -40,6 +40,7 @@ annot: | TVersion TColon l=separated_nonempty_list(TComma,version) endline { `Version (l) } | TWeakdef endline { `Weakdef } + | TInline endline { `Inline } | TAlways endline { `Always } | TDeprecated endline { `Deprecated $1 } | TAlias TColon name=TIdent endline { `Alias (name) } diff --git a/compiler/lib/generate.ml b/compiler/lib/generate.ml index 5653585e4b..9857a2fab4 100644 --- a/compiler/lib/generate.ml +++ b/compiler/lib/generate.ml @@ -365,13 +365,6 @@ let one = J.ENum (J.Num.of_targetint Targetint.one) let zero = J.ENum (J.Num.of_targetint Targetint.zero) -let plus_int x y = - match x, y with - | J.ENum y, x when J.Num.is_zero y -> x - | x, J.ENum y when J.Num.is_zero y -> x - | J.ENum x, J.ENum y -> J.ENum (J.Num.add x y) - | x, y -> J.EBin (J.Plus, x, y) - let bool e = J.ECond (e, one, zero) (****) @@ -1082,16 +1075,6 @@ let register_un_prims names ?(need_loc = false) k f = let register_un_prim name k f = register_un_prims [ name ] k f -let register_un_prim_ctx name k f = - register_prims [ name ] k (fun name l ctx loc -> - match l with - | [ x ] -> - let open Expr_builder in - let* cx = access' ~ctx x in - let* () = info (kind k) in - return (f ctx cx loc) - | _ -> invalid_arity name l ~loc ~expected:1) - let register_bin_prims names k f = register_prims names k (fun name l ctx loc -> match l with @@ -1119,28 +1102,7 @@ let register_tern_prims names k f = let register_tern_prim name k f = register_tern_prims [ name ] k f -let register_un_math_prim name prim = - let prim = Utf8_string.of_string_exn prim in - register_un_prim name `Pure (fun cx loc -> - J.call (J.dot (s_var "Math") prim) [ cx ] loc) - -let register_bin_math_prim name prim = - let prim = Utf8_string.of_string_exn prim in - register_bin_prims [ name ] `Pure (fun cx cy loc -> - J.call (J.dot (s_var "Math") prim) [ cx; cy ] loc) - let _ = - register_un_prim_ctx "%caml_format_int_special" `Pure (fun ctx cx loc -> - let s = J.EBin (J.Plus, str_js_utf8 "", cx) in - ocaml_string ~ctx ~loc s); - register_un_prim "%direct_obj_tag" `Pure (fun cx _loc -> Mlvalue.Block.tag cx); - register_bin_prims - [ "caml_array_unsafe_get" - ; "caml_array_unsafe_get_float" - ; "caml_floatarray_unsafe_get" - ] - `Mutable - (fun cx cy _ -> Mlvalue.Array.field cx cy); register_un_prims [ "caml_int32_of_int" ; "caml_int32_to_int" @@ -1154,83 +1116,6 @@ let _ = ] `Pure (fun cx _ -> cx); - register_bin_prims - [ "%int_add"; "caml_int32_add"; "caml_nativeint_add" ] - `Pure - (fun cx cy _ -> - match cx, cy with - | J.EBin (J.Minus, cz, J.ENum n), J.ENum m -> - to_int (J.EBin (J.Plus, cz, J.ENum (J.Num.add m (J.Num.neg n)))) - | _ -> to_int (plus_int cx cy)); - register_bin_prims - [ "%int_sub"; "caml_int32_sub"; "caml_nativeint_sub" ] - `Pure - (fun cx cy _ -> - match cx, cy with - | J.EBin (J.Minus, cz, J.ENum n), J.ENum m -> - to_int (J.EBin (J.Minus, cz, J.ENum (J.Num.add n m))) - | _ -> to_int (J.EBin (J.Minus, cx, cy))); - register_bin_prim "%direct_int_mul" `Pure (fun cx cy _ -> - to_int (J.EBin (J.Mul, cx, cy))); - register_bin_prim "%direct_int_div" `Pure (fun cx cy _ -> - to_int (J.EBin (J.Div, cx, cy))); - register_bin_prim "%direct_int_mod" `Pure (fun cx cy _ -> - to_int (J.EBin (J.Mod, cx, cy))); - register_bin_prims - [ "%int_and"; "caml_int32_and"; "caml_nativeint_and" ] - `Pure - (fun cx cy _ -> J.EBin (J.Band, cx, cy)); - register_bin_prims - [ "%int_or"; "caml_int32_or"; "caml_nativeint_or" ] - `Pure - (fun cx cy _ -> J.EBin (J.Bor, cx, cy)); - register_bin_prims - [ "%int_xor"; "caml_int32_xor"; "caml_nativeint_xor" ] - `Pure - (fun cx cy _ -> J.EBin (J.Bxor, cx, cy)); - register_bin_prims - [ "%int_lsl"; "caml_int32_shift_left"; "caml_nativeint_shift_left" ] - `Pure - (fun cx cy _ -> J.EBin (J.Lsl, cx, cy)); - register_bin_prims - [ "%int_lsr" - ; "caml_int32_shift_right_unsigned" - ; "caml_nativeint_shift_right_unsigned" - ] - `Pure - (fun cx cy _ -> to_int (J.EBin (J.Lsr, cx, cy))); - register_bin_prims - [ "%int_asr"; "caml_int32_shift_right"; "caml_nativeint_shift_right" ] - `Pure - (fun cx cy _ -> J.EBin (J.Asr, cx, cy)); - register_un_prims - [ "%int_neg"; "caml_int32_neg"; "caml_nativeint_neg" ] - `Pure - (fun cx _ -> to_int (J.EUn (J.Neg, cx))); - register_bin_prim "caml_eq_float" `Pure (fun cx cy _ -> - bool (J.EBin (J.EqEqEq, cx, cy))); - register_bin_prim "caml_neq_float" `Pure (fun cx cy _ -> - bool (J.EBin (J.NotEqEq, cx, cy))); - register_bin_prim "caml_ge_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Le, cy, cx))); - register_bin_prim "caml_le_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Le, cx, cy))); - register_bin_prim "caml_gt_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Lt, cy, cx))); - register_bin_prim "caml_lt_float" `Pure (fun cx cy _ -> bool (J.EBin (J.Lt, cx, cy))); - register_bin_prim "caml_add_float" `Pure (fun cx cy _ -> J.EBin (J.Plus, cx, cy)); - register_bin_prim "caml_sub_float" `Pure (fun cx cy _ -> J.EBin (J.Minus, cx, cy)); - register_bin_prim "caml_mul_float" `Pure (fun cx cy _ -> J.EBin (J.Mul, cx, cy)); - register_bin_prim "caml_div_float" `Pure (fun cx cy _ -> J.EBin (J.Div, cx, cy)); - register_un_prim "caml_neg_float" `Pure (fun cx _ -> J.EUn (J.Neg, cx)); - register_bin_prim "caml_fmod_float" `Pure (fun cx cy _ -> J.EBin (J.Mod, cx, cy)); - register_tern_prims - [ "caml_array_unsafe_set" - ; "caml_array_unsafe_set_float" - ; "caml_floatarray_unsafe_set" - ; "caml_array_unsafe_set_addr" - ] - `Mutator - (fun cx cy cz _ -> J.EBin (J.Eq, Mlvalue.Array.field cx cy, cz)); - register_un_prims [ "caml_alloc_dummy"; "caml_alloc_dummy_float" ] `Pure (fun _ _ -> - J.array []); register_un_prims [ "caml_int_of_float" ; "caml_int32_of_float" @@ -1240,20 +1125,6 @@ let _ = ] `Pure (fun cx _loc -> to_int cx); - register_un_math_prim "caml_abs_float" "abs"; - register_un_math_prim "caml_acos_float" "acos"; - register_un_math_prim "caml_asin_float" "asin"; - register_un_math_prim "caml_atan_float" "atan"; - register_bin_math_prim "caml_atan2_float" "atan2"; - register_un_math_prim "caml_ceil_float" "ceil"; - register_un_math_prim "caml_cos_float" "cos"; - register_un_math_prim "caml_exp_float" "exp"; - register_un_math_prim "caml_floor_float" "floor"; - register_un_math_prim "caml_log_float" "log"; - register_bin_math_prim "caml_power_float" "pow"; - register_un_math_prim "caml_sin_float" "sin"; - register_un_math_prim "caml_sqrt_float" "sqrt"; - register_un_math_prim "caml_tan_float" "tan"; register_un_prim "caml_js_from_bool" `Pure (fun cx _ -> J.EUn (J.Not, J.EUn (J.Not, cx))); register_un_prim "caml_js_to_bool" `Pure (fun cx _ -> to_int cx); @@ -1318,6 +1189,17 @@ let remove_unused_tail_args ctx exact trampolined args = else args else args +(* var substitution *) +class subst sub = + object + inherit Js_traverse.map as super + + method expression x = + match x with + | EVar v -> ( try sub v with Not_found -> super#expression x) + | _ -> super#expression x + end + let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t = let open Expr_builder in match e with @@ -1539,13 +1421,52 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t let name = Primitive.resolve name_orig in match internal_prim name with | Some f -> f name l ctx loc - | None -> + | None -> ( if String.starts_with name ~prefix:"%" then failwith (Printf.sprintf "Unresolved internal primitive: %s" name); - let prim = Share.get_prim (runtime_fun ctx) name ctx.Ctx.share in - let* () = info ~need_loc:true (kind (Primitive.kind name)) in - let* args = list_map (fun x -> access' ~ctx x) l in - return (J.call prim args loc)) + match Linker.inline ~name with + | Some (req, f) + when Option.is_none ctx.Ctx.exported_runtime || List.is_empty req -> ( + let c = new Js_traverse.rename_variable ~esm:false in + let f = c#expression f in + match f with + | EFun + ( None + , ( { async = false; generator = false } + , { list = params; rest = None } + , [ (Return_statement (Some body, _), _) ] + , _loc ) ) + when List.length params = List.length l -> + let* l = list_map (fun x -> access' ~ctx x) l in + let params = + List.map params ~f:(fun (x, _) -> + match x with + | BindingIdent x -> x + | BindingPattern _ -> assert false) + in + let sub = + let t = Hashtbl.create (List.length l) in + List.iter2 params l ~f:(fun p x -> + let k = + match p with + | J.V v -> v + | _ -> assert false + in + Hashtbl.add t k x); + + fun x -> + match x with + | J.S _ -> J.EVar x + | J.V x -> Hashtbl.find t x + in + let r = new subst sub in + return (r#expression body) + | _ -> assert false) + | None | Some _ -> + let prim = Share.get_prim (runtime_fun ctx) name ctx.Ctx.share in + let* () = info ~need_loc:true (kind (Primitive.kind name)) in + let* args = list_map (fun x -> access' ~ctx x) l in + return (J.call prim args loc))) | Not, [ x ] -> let* cx = access' ~ctx x in return (J.EBin (J.Minus, one, cx)) @@ -2289,7 +2210,7 @@ let f if times () then Format.eprintf " code gen.: %a@." Timer.print t'; p -let init () = +let reset () = Hashtbl.iter (fun name (k, _) -> Primitive.register name k None None) internal_primitives diff --git a/compiler/lib/generate.mli b/compiler/lib/generate.mli index 8635eadffc..3fb0076d26 100644 --- a/compiler/lib/generate.mli +++ b/compiler/lib/generate.mli @@ -29,4 +29,4 @@ val f : -> deadcode_sentinal:Code.Var.t -> Javascript.program -val init : unit -> unit +val reset : unit -> unit diff --git a/compiler/lib/javascript.ml b/compiler/lib/javascript.ml index 3167679ff8..ab1f319ee8 100644 --- a/compiler/lib/javascript.ml +++ b/compiler/lib/javascript.ml @@ -42,6 +42,8 @@ module Num : sig val is_neg : t -> bool + val is_int : t -> bool + (** Arithmetic *) val add : t -> t -> t @@ -134,6 +136,11 @@ end = struct let is_neg s = Char.equal s.[0] '-' + let is_int s = + String.for_all s ~f:(function + | '0' .. '9' | '-' -> true + | _ -> false) + let neg s = match String.drop_prefix s ~prefix:"-" with | None -> "-" ^ s diff --git a/compiler/lib/javascript.mli b/compiler/lib/javascript.mli index 6b59dc758f..803748dacb 100644 --- a/compiler/lib/javascript.mli +++ b/compiler/lib/javascript.mli @@ -43,6 +43,8 @@ module Num : sig val is_neg : t -> bool + val is_int : t -> bool + (** Arithmetic *) val add : t -> t -> t diff --git a/compiler/lib/js_traverse.ml b/compiler/lib/js_traverse.ml index 6221fe1e3a..d3a44ec218 100644 --- a/compiler/lib/js_traverse.ml +++ b/compiler/lib/js_traverse.ml @@ -1702,23 +1702,23 @@ class simpl = method expression e = let e = super#expression e in - let is_zero x = - match Num.to_string x with - | "0" | "0." -> true - | _ -> false - in match e with | EBin (Plus, e1, e2) -> ( match e1, e2 with - | _, ENum n when Num.is_neg n -> EBin (Minus, e1, ENum (Num.neg n)) - | ENum n, _ when Num.is_neg n -> EBin (Minus, e2, ENum (Num.neg n)) - | ENum zero, (ENum _ as x) when is_zero zero -> x - | (ENum _ as x), ENum zero when is_zero zero -> x + | ENum n1, ENum n2 when Num.is_int n1 && Num.is_int n2 -> ENum (Num.add n1 n2) + | _, ENum n when Num.is_neg n -> + m#expression (EBin (Minus, e1, ENum (Num.neg n))) + | ENum n, _ when Num.is_neg n -> + m#expression (EBin (Minus, e2, ENum (Num.neg n))) + | ENum zero, x when Num.is_zero zero -> x + | x, ENum zero when Num.is_zero zero -> x | _ -> e) | EBin (Minus, e1, e2) -> ( match e1, e2 with + | EBin (Minus, e0, ENum n1), ENum n2 when Num.is_int n1 && Num.is_int n2 -> + EBin (Minus, e0, ENum (Num.add n1 n2)) | _, ENum n when Num.is_neg n -> EBin (Plus, e1, ENum (Num.neg n)) - | (ENum _ as x), ENum zero when is_zero zero -> x + | (ENum _ as x), ENum zero when Num.is_zero zero -> x | _ -> e) | EFun (None, (({ generator = false; async = true | false }, _, body, _) as fun_decl)) diff --git a/compiler/lib/linker.ml b/compiler/lib/linker.ml index 7c91801297..55b937a56f 100644 --- a/compiler/lib/linker.ml +++ b/compiler/lib/linker.ml @@ -176,6 +176,7 @@ module Fragment = struct ; has_macro : bool ; version_constraint_ok : bool ; weakdef : bool + ; inline : bool ; always : bool ; code : Javascript.program pack ; conditions : bool StringMap.t @@ -267,6 +268,7 @@ module Fragment = struct ; requires = [] ; version_constraint_ok = true ; weakdef = false + ; inline = false ; always = false ; has_macro = false ; code = Ok code @@ -301,6 +303,7 @@ module Fragment = struct fragment.version_constraint_ok && version_match l } | `Weakdef -> { fragment with weakdef = true } + | `Inline -> { fragment with inline = true } | `Always -> { fragment with always = true } | `Alias name -> { fragment with aliases = StringSet.add name fragment.aliases } @@ -425,6 +428,7 @@ type provided = ; pi : Parse_info.t ; filename : string ; weakdef : bool + ; inline : bool ; target_env : Target_env.t ; aliases : StringSet.t } @@ -442,8 +446,7 @@ let reset () = Hashtbl.clear provided; Hashtbl.clear provided_rev; Hashtbl.clear code_pieces; - Primitive.reset (); - Generate.init () + Primitive.reset () let list_all ?from () = let include_ = @@ -480,6 +483,7 @@ let load_fragment ~target_env ~filename (f : Fragment.t) = ; requires ; version_constraint_ok ; weakdef + ; inline ; always ; code ; fragment_target @@ -572,7 +576,14 @@ let load_fragment ~target_env ~filename (f : Fragment.t) = Hashtbl.add provided name - { id; pi; filename; weakdef; target_env = fragment_target; aliases }; + { id + ; pi + ; filename + ; weakdef + ; inline + ; target_env = fragment_target + ; aliases + }; Hashtbl.add provided_rev id (name, pi); Hashtbl.add code_pieces id (code, has_macro, requires, deprecated); StringSet.iter (fun alias -> Primitive.alias alias name) aliases; @@ -777,3 +788,15 @@ let deprecated ~name = let _, _, _, deprecated = Hashtbl.find code_pieces x.id in Option.is_some deprecated with Not_found -> false + +let inline ~name = + match Hashtbl.find provided (Primitive.resolve name) with + | exception Not_found -> None + | { id; inline; _ } -> + if inline + then + let code, _has_macro, req, _deprecated = Hashtbl.find code_pieces id in + match unpack code with + | [ (Function_declaration (_, f), _) ] -> Some (req, Javascript.EFun (None, f)) + | _ -> None + else None diff --git a/compiler/lib/linker.mli b/compiler/lib/linker.mli index bc3b9b4caf..8d6dc7f1b0 100644 --- a/compiler/lib/linker.mli +++ b/compiler/lib/linker.mli @@ -71,4 +71,6 @@ val missing : state -> string list val origin : name:string -> string option +val inline : name:string -> (string list * Javascript.expression) option + val deprecated : name:string -> bool diff --git a/compiler/lib/primitive.ml b/compiler/lib/primitive.ml index ea25ad2f6c..f59c119d8f 100644 --- a/compiler/lib/primitive.ml +++ b/compiler/lib/primitive.ml @@ -50,6 +50,7 @@ type t = | `Provides of string * kind * kind_arg list option | `Version of ((int -> int -> bool) * string) list | `Weakdef + | `Inline | `Always | `Alias of string | `Deprecated of string diff --git a/compiler/lib/primitive.mli b/compiler/lib/primitive.mli index 38bea133a0..38a067b206 100644 --- a/compiler/lib/primitive.mli +++ b/compiler/lib/primitive.mli @@ -46,6 +46,7 @@ type t = | `Provides of string * kind * kind_arg list option | `Version of ((int -> int -> bool) * string) list | `Weakdef + | `Inline | `Always | `Alias of string | `Deprecated of string diff --git a/compiler/tests-compiler/gh1768.ml b/compiler/tests-compiler/gh1768.ml index ddf036a8fc..1b56af34b4 100644 --- a/compiler/tests-compiler/gh1768.ml +++ b/compiler/tests-compiler/gh1768.ml @@ -55,7 +55,7 @@ let () = global_data = runtime.caml_get_global_data(), Assert_failure = global_data.Assert_failure, _a_ = [0, caml_string_of_jsbytes("test.ml"), 4, 27]; - function h(x){x[1] = function(x, y){return x + y | 0;};} + function h(x){x[1] = runtime.caml_add;} function f(param){ return [0, function(param){ diff --git a/compiler/tests-compiler/obj.ml b/compiler/tests-compiler/obj.ml index 9e8ee2a850..7f877589a1 100644 --- a/compiler/tests-compiler/obj.ml +++ b/compiler/tests-compiler/obj.ml @@ -52,8 +52,7 @@ let%expect_test "static eval of string get" = //end function my_size(x){return x.length - 1;} //end - function my_field(x, i){return x[i + 1];} - //end + not found function my_set_field(x, i, o){x[i + 1] = o; return 0;} //end function my_new_block(x, l){return runtime.caml_obj_block(x + 1 | 0, 3);} diff --git a/compiler/tests-full/stdlib.cma.expected.js b/compiler/tests-full/stdlib.cma.expected.js index ef3d35552f..fef927c5d3 100644 --- a/compiler/tests-full/stdlib.cma.expected.js +++ b/compiler/tests-full/stdlib.cma.expected.js @@ -360,6 +360,7 @@ caml_atomic_load = runtime.caml_atomic_load, caml_create_bytes = runtime.caml_create_bytes, caml_float_of_string = runtime.caml_float_of_string, + caml_format_int_special = runtime.caml_format_int_special, caml_int_of_string = runtime.caml_int_of_string, caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, caml_ml_bytes_length = runtime.caml_ml_bytes_length, @@ -460,7 +461,7 @@ ? param !== cst_true$0 ? 0 : _a_ : _b_ /*<>*/ ; } - function string_of_int(n){ /*<>*/ return "" + n;} + var string_of_int = /*<>*/ caml_format_int_special; function int_of_string_opt(s){ /*<>*/ try{ var _m_ = /*<>*/ [0, caml_int_of_string(s)]; @@ -745,7 +746,8 @@ /*<>*/ return output_bytes(stdout, s) /*<>*/ ; } function print_int(i){ - /*<>*/ return output_string(stdout, "" + i); + /*<>*/ return /*<>*/ output_string + (stdout, /*<>*/ caml_format_int_special(i)) /*<>*/ ; } function print_float(f){ /*<>*/ return /*<>*/ output_string @@ -770,7 +772,8 @@ /*<>*/ return output_bytes(stderr, s) /*<>*/ ; } function prerr_int(i){ - /*<>*/ return output_string(stderr, "" + i); + /*<>*/ return /*<>*/ output_string + (stderr, /*<>*/ caml_format_int_special(i)) /*<>*/ ; } function prerr_float(f){ /*<>*/ return /*<>*/ output_string @@ -2884,7 +2887,8 @@ caml_bytes_unsafe_set = runtime.caml_bytes_unsafe_set, caml_create_bytes = runtime.caml_create_bytes, caml_hash = runtime.caml_hash, - caml_string_of_bytes = runtime.caml_string_of_bytes; + caml_string_of_bytes = runtime.caml_string_of_bytes, + caml_sub = runtime.caml_sub; function caml_call1(f, a0){ return (f.l >= 0 ? f.l : f.l = f.length) === 1 ? f(a0) @@ -2947,9 +2951,7 @@ function uppercase_ascii(c){ /*<>*/ return 25 < c - 97 >>> 0 ? c : c - 32 | 0 /*<>*/ ; } - function compare(c1, c2){ - /*<>*/ return c1 - c2 | 0; - /*<>*/ } + var compare = /*<>*/ caml_sub; function equal(c1, c2){ /*<>*/ return 0 === (c1 - c2 | 0) ? 1 : 0; /*<>*/ } @@ -4797,7 +4799,7 @@ function max(x, y){ /*<>*/ return y <= x ? x : y /*<>*/ ; } - function to_string(x){ /*<>*/ return "" + x;} + var to_string = /*<>*/ runtime.caml_format_int_special; function seeded_hash(seed, x){ /*<>*/ return caml_hash(10, 100, seed, x) /*<>*/ ; } @@ -8101,7 +8103,7 @@ /*<>*/ } function min(x, y){ a: - if(! (x < y)){ + if(! (y > x)){ /*<>*/ if (! caml_signbit_float(y) @@ -8113,7 +8115,7 @@ } function max(x, y){ a: - if(! (x < y)){ + if(! (y > x)){ /*<>*/ if (! caml_signbit_float(y) @@ -8126,7 +8128,7 @@ function min_max(x, y){ /*<>*/ if(x === x && y === y){ a: - if(! (x < y)){ + if(! (y > x)){ /*<>*/ if (! caml_signbit_float(y) @@ -8140,7 +8142,7 @@ /*<>*/ } function min_num(x, y){ a: - if(! (x < y)){ + if(! (y > x)){ /*<>*/ if (! caml_signbit_float(y) @@ -8152,7 +8154,7 @@ } function max_num(x, y){ a: - if(! (x < y)){ + if(! (y > x)){ /*<>*/ if (! caml_signbit_float(y) @@ -8168,7 +8170,7 @@ /*<>*/ if(y !== y) /*<>*/ return [0, x, x]; a: - if(! (x < y)){ + if(! (y > x)){ /*<>*/ if (! caml_signbit_float(y) @@ -25834,6 +25836,7 @@ "use strict"; var runtime = globalThis.jsoo_runtime, + caml_add = runtime.caml_add, caml_array_make = runtime.caml_array_make, caml_check_bound = runtime.caml_check_bound, caml_maybe_attach_backtrace = runtime.caml_maybe_attach_backtrace, @@ -25880,9 +25883,9 @@ cst_Weak_Make_hash_bucket_cann = "Weak.Make: hash bucket cannot grow more"; function create(l){ var - _J_ = /*<>*/ 0 <= l ? 1 : 0, - _K_ = _J_ ? l <= Stdlib_Obj[23][15] ? 1 : 0 : _J_; - if(1 - _K_) /*<>*/ caml_call1(Stdlib[1], cst_Weak_create); + _H_ = /*<>*/ 0 <= l ? 1 : 0, + _I_ = _H_ ? l <= Stdlib_Obj[23][15] ? 1 : 0 : _H_; + if(1 - _I_) /*<>*/ caml_call1(Stdlib[1], cst_Weak_create); /*<>*/ return runtime.caml_weak_create(l) /*<>*/ ; } function length(x){ @@ -25890,10 +25893,10 @@ /*<>*/ } function raise_if_invalid_offset(e, o, msg){ var - _G_ = /*<>*/ 0 <= o ? 1 : 0, - _H_ = _G_ ? o < /*<>*/ length(e) ? 1 : 0 : _G_, - _I_ = /*<>*/ 1 - _H_; - return _I_ ? /*<>*/ caml_call1(Stdlib[1], msg) : _I_ /*<>*/ ; + _E_ = /*<>*/ 0 <= o ? 1 : 0, + _F_ = _E_ ? o < /*<>*/ length(e) ? 1 : 0 : _E_, + _G_ = /*<>*/ 1 - _F_; + return _G_ ? /*<>*/ caml_call1(Stdlib[1], msg) : _G_ /*<>*/ ; } function set(e, o, x){ /*<>*/ raise_if_invalid_offset(e, o, cst_Weak_set); @@ -25923,13 +25926,13 @@ ( /*<>*/ length(e1) - l | 0) >= o1 && 0 <= o2 && ( /*<>*/ length(e2) - l | 0) >= o2){ var - _E_ = /*<>*/ 0 !== l ? 1 : 0, - _F_ = - _E_ + _C_ = /*<>*/ 0 !== l ? 1 : 0, + _D_ = + _C_ ? /*<>*/ runtime.caml_ephe_blit_key (e1, o1, e2, o2, l) - : _E_; - /*<>*/ return _F_; + : _C_; + /*<>*/ return _D_; } /*<>*/ return caml_call1(Stdlib[1], cst_Weak_blit) /*<>*/ ; } @@ -25937,14 +25940,14 @@ /*<>*/ if (0 <= ofs && 0 <= len && ( /*<>*/ length(ar) - len | 0) >= ofs){ - var _C_ = /*<>*/ (ofs + len | 0) - 1 | 0; - if(_C_ >= ofs){ + var _A_ = /*<>*/ (ofs + len | 0) - 1 | 0; + if(_A_ >= ofs){ var i = ofs; for(;;){ /*<>*/ set(ar, i, x); - var _D_ = /*<>*/ i + 1 | 0; - if(_C_ === i) break; - i = _D_; + var _B_ = /*<>*/ i + 1 | 0; + if(_A_ === i) break; + i = _B_; } } /*<>*/ return 0; @@ -25971,15 +25974,15 @@ 0] /*<>*/ ; /*<>*/ } function clear(t){ - var _A_ = /*<>*/ t[1].length - 2 | 0, _z_ = 0; - if(_A_ >= 0){ - var i = _z_; + var _y_ = /*<>*/ t[1].length - 2 | 0, _x_ = 0; + if(_y_ >= 0){ + var i = _x_; for(;;){ /*<>*/ caml_check_bound(t[1], i)[i + 1] = emptybucket; /*<>*/ caml_check_bound(t[2], i)[i + 1] = [0]; - var _B_ = /*<>*/ i + 1 | 0; - if(_A_ === i) break; - i = _B_; + var _z_ = /*<>*/ i + 1 | 0; + if(_y_ === i) break; + i = _z_; } } /*<>*/ t[3] = limit; @@ -26038,19 +26041,19 @@ for(;;){ if(length(b) <= i) /*<>*/ return accu; var - _y_ = /*<>*/ check(b, i) ? 1 : 0, - accu$0 = /*<>*/ accu + _y_ | 0, + _w_ = /*<>*/ check(b, i) ? 1 : 0, + accu$0 = /*<>*/ accu + _w_ | 0, i$0 = i + 1 | 0; i = i$0; accu = accu$0; } /*<>*/ } function count(t){ - var _v_ = /*<>*/ 0; + var _t_ = /*<>*/ 0; /*<>*/ return caml_call3 (Stdlib_Array[20], - function(_w_, _x_){ - /*<>*/ return count_bucket(_v_, _w_, _x_); + function(_u_, _v_){ + /*<>*/ return count_bucket(_t_, _u_, _v_); }, t[1], 0) /*<>*/ ; @@ -26093,17 +26096,17 @@ /*<>*/ caml_check_bound(t[1], index)[index + 1] = newbucket$0; /*<>*/ caml_check_bound(t[2], index)[index + 1] = newhashes; var - _r_ = /*<>*/ sz <= t[3] ? 1 : 0, - _s_ = _r_ ? t[3] < newsz ? 1 : 0 : _r_; - if(_s_){ + _p_ = /*<>*/ sz <= t[3] ? 1 : 0, + _q_ = _p_ ? t[3] < newsz ? 1 : 0 : _p_; + if(_q_){ /*<>*/ t[4] = t[4] + 1 | 0; var i$4 = /*<>*/ 0; for(;;){ var - _h_ = /*<>*/ t[5], - bucket = /*<>*/ caml_check_bound(t[1], _h_)[_h_ + 1], - _i_ = /*<>*/ t[5], - hbucket = /*<>*/ caml_check_bound(t[2], _i_)[_i_ + 1], + _f_ = /*<>*/ t[5], + bucket = /*<>*/ caml_check_bound(t[1], _f_)[_f_ + 1], + _g_ = /*<>*/ t[5], + hbucket = /*<>*/ caml_check_bound(t[2], _g_)[_g_ + 1], len = /*<>*/ length(bucket), prev_len = /*<>*/ (((len - 3 | 0) * 2 | 0) + 2 | 0) / 3 | 0, @@ -26121,8 +26124,8 @@ else if( /*<>*/ check(bucket, j)){ /*<>*/ blit(bucket, j, bucket, i$0, 1); var - _j_ = /*<>*/ caml_check_bound(hbucket, j)[j + 1]; - /*<>*/ caml_check_bound(hbucket, i$0)[i$0 + 1] = _j_; + _h_ = /*<>*/ caml_check_bound(hbucket, j)[j + 1]; + /*<>*/ caml_check_bound(hbucket, i$0)[i$0 + 1] = _h_; var j$0 = /*<>*/ j - 1 | 0, i$2 = i$0 + 1 | 0; i$0 = i$2; j = j$0; @@ -26130,37 +26133,37 @@ else{var j$1 = /*<>*/ j - 1 | 0; j = j$1;} } /*<>*/ if(0 === prev_len){ - var _k_ = /*<>*/ t[5]; - /*<>*/ caml_check_bound(t[1], _k_)[_k_ + 1] = emptybucket; - var _l_ = /*<>*/ t[5]; - /*<>*/ caml_check_bound(t[2], _l_)[_l_ + 1] = [0]; + var _i_ = /*<>*/ t[5]; + /*<>*/ caml_check_bound(t[1], _i_)[_i_ + 1] = emptybucket; + var _j_ = /*<>*/ t[5]; + /*<>*/ caml_check_bound(t[2], _j_)[_j_ + 1] = [0]; } else{ var newbucket = /*<>*/ create(prev_len); /*<>*/ blit(bucket, 0, newbucket, 0, prev_len); - var _o_ = /*<>*/ t[5]; - /*<>*/ caml_check_bound(t[1], _o_)[_o_ + 1] = newbucket; + var _m_ = /*<>*/ t[5]; + /*<>*/ caml_check_bound(t[1], _m_)[_m_ + 1] = newbucket; var - _p_ = + _n_ = /*<>*/ caml_call3 (Stdlib_Array[6], hbucket, 0, prev_len), - _q_ = /*<>*/ t[5]; - /*<>*/ caml_check_bound(t[2], _q_)[_q_ + 1] = _p_; + _o_ = /*<>*/ t[5]; + /*<>*/ caml_check_bound(t[2], _o_)[_o_ + 1] = _n_; } var - _m_ = /*<>*/ t[3] < len ? 1 : 0, - _n_ = _m_ ? prev_len <= t[3] ? 1 : 0 : _m_; - if(_n_) /*<>*/ t[4] = t[4] - 1 | 0; + _k_ = /*<>*/ t[3] < len ? 1 : 0, + _l_ = _k_ ? prev_len <= t[3] ? 1 : 0 : _k_; + if(_l_) /*<>*/ t[4] = t[4] - 1 | 0; } /*<>*/ t[5] = caml_mod(t[5] + 1 | 0, t[1].length - 1); - var _u_ = /*<>*/ i$4 + 1 | 0; + var _s_ = /*<>*/ i$4 + 1 | 0; if(2 === i$4) break; - i$4 = _u_; + i$4 = _s_; } } var - _t_ = /*<>*/ ((t[1].length - 1) / 2 | 0) < t[4] ? 1 : 0; - if(! _t_) return _t_; + _r_ = /*<>*/ ((t[1].length - 1) / 2 | 0) < t[4] ? 1 : 0; + if(! _r_) return _r_; var oldlen = /*<>*/ t[1].length - 1, newlen = @@ -26334,10 +26337,7 @@ var totlen = /*<>*/ caml_call3 - (Stdlib_Array[18], - function(_g_, _f_){ /*<>*/ return _g_ + _f_ | 0;}, - 0, - lens), + (Stdlib_Array[18], caml_add, 0, lens), _a_ = /*<>*/ len - 1 | 0, _c_ = /*<>*/ len / 2 | 0, _b_ = /*<>*/ caml_check_bound(lens, _a_)[_a_ + 1], @@ -35763,8 +35763,7 @@ /*<>*/ } function div(x, y){ /*<>*/ if - ( /*<>*/ Math.abs(y[2]) - <= /*<>*/ Math.abs(y[1])){ + ( /*<<+ieee_754.js:292:9>>*/ Math.abs(y[1]) >= Math.abs(y[2])){ var r = /*<>*/ y[2] / y[1], d = /*<>*/ y[1] + r * y[2]; @@ -35789,54 +35788,51 @@ /*<>*/ return runtime.caml_hypot_float(x[1], x[2]) /*<>*/ ; } function arg(x){ - /*<>*/ return /*<>*/ Math.atan2 + /*<>*/ return /*<<+ieee_754.js:316:9>>*/ Math.atan2 (x[2], x[1]) /*<>*/ ; } function polar(n, a){ /*<>*/ return [254, - /*<>*/ Math.cos(a) * n, - /*<>*/ Math.sin(a) * n] /*<>*/ ; + /*<<+ieee_754.js:328:9>>*/ Math.cos(a) * n, + /*<<+ieee_754.js:358:9>>*/ Math.sin(a) * n] /*<>*/ ; /*<>*/ } function sqrt(x){ /*<>*/ if(x[1] === 0. && x[2] === 0.) /*<>*/ return _a_; var - r = /*<>*/ Math.abs(x[1]), - i = /*<>*/ Math.abs(x[2]); - /*<>*/ if(i <= r) + r = /*<>*/ /*<<+ieee_754.js:292:9>>*/ Math.abs(x[1]), + i = /*<>*/ /*<<+ieee_754.js:292:9>>*/ Math.abs(x[2]); + /*<>*/ if(r >= i) var q = /*<>*/ i / r, w = - /*<>*/ /*<>*/ Math.sqrt(r) - * - /*<>*/ Math.sqrt - (0.5 * (1. + /*<>*/ Math.sqrt(1. + q * q))); + /*<>*/ /*<<+ieee_754.js:364:9>>*/ Math.sqrt(r) + * Math.sqrt(0.5 * (1. + Math.sqrt(1. + q * q))); else var q$0 = /*<>*/ r / i, w = - /*<>*/ /*<>*/ Math.sqrt(i) - * - /*<>*/ Math.sqrt - (0.5 * (q$0 + /*<>*/ Math.sqrt(1. + q$0 * q$0))); - /*<>*/ if(0. <= x[1]) + /*<>*/ /*<<+ieee_754.js:364:9>>*/ Math.sqrt(i) + * Math.sqrt(0.5 * (q$0 + Math.sqrt(1. + q$0 * q$0))); + /*<>*/ if(x[1] >= 0.) /*<>*/ return [254, w, 0.5 * x[2] / w]; - var w$0 = /*<>*/ 0. <= x[2] ? w : - w; + var w$0 = /*<>*/ x[2] >= 0. ? w : - w; /*<>*/ return [254, 0.5 * i / w, w$0]; /*<>*/ } function exp(x){ - var e = /*<>*/ Math.exp(x[1]); + var + e = /*<>*/ /*<<+ieee_754.js:334:9>>*/ Math.exp(x[1]); /*<>*/ return [254, - e * /*<>*/ Math.cos(x[2]), - e * /*<>*/ Math.sin(x[2])] /*<>*/ ; + e * /*<<+ieee_754.js:328:9>>*/ Math.cos(x[2]), + e * /*<<+ieee_754.js:358:9>>*/ Math.sin(x[2])] /*<>*/ ; /*<>*/ } function log(x){ var _b_ = - /*<>*/ /*<>*/ Math.atan2 + /*<>*/ /*<<+ieee_754.js:316:9>>*/ Math.atan2 (x[2], x[1]); /*<>*/ return [254, - /*<>*/ Math.log + /*<<+ieee_754.js:346:9>>*/ Math.log ( /*<>*/ norm(x)), _b_] /*<>*/ ; /*<>*/ } diff --git a/compiler/tests-toplevel/dune b/compiler/tests-toplevel/dune index f3eb01f5fb..9c976f1f4f 100644 --- a/compiler/tests-toplevel/dune +++ b/compiler/tests-toplevel/dune @@ -1,6 +1,6 @@ (executables (names test_toplevel) - (libraries js_of_ocaml-compiler.dynlink compiler-libs.toplevel) + (libraries js_of_ocaml js_of_ocaml-compiler.dynlink compiler-libs.toplevel) (flags (:standard -linkall)) (js_of_ocaml diff --git a/compiler/tests-toplevel/test_toplevel.ml b/compiler/tests-toplevel/test_toplevel.ml index 4b1999537f..3c45b7e76f 100644 --- a/compiler/tests-toplevel/test_toplevel.ml +++ b/compiler/tests-toplevel/test_toplevel.ml @@ -1,3 +1,12 @@ +let () = + Printexc.register_printer (fun x -> + match Js_of_ocaml.Js_error.of_exn x with + | None -> None + | Some e -> + if true + then Js_of_ocaml.Js_error.raise_ e + else Some (Js_of_ocaml.Js_error.message e)) + let () = let content = {| diff --git a/runtime/js/array.js b/runtime/js/array.js index e0bd1a9c60..6065ce686c 100644 --- a/runtime/js/array.js +++ b/runtime/js/array.js @@ -115,6 +115,15 @@ function caml_array_set(array, index, newval) { return 0; } +//Provides: caml_array_unsafe_set +//Alias: caml_array_unsafe_set_float +//Alias: caml_floatarray_unsafe_set +//Alias: caml_array_unsafe_set_addr +//Inline +function caml_array_unsafe_set(a, i, v) { + return (a[i + 1] = v); +} + //Provides: caml_array_get mutable (mutable, const) //Requires: caml_array_bound_error //Alias: caml_array_get_float @@ -125,6 +134,13 @@ function caml_array_get(array, index) { return array[index + 1]; } +//Provides: caml_array_unsafe_get mutable (mutable, const) +//Alias: caml_array_unsafe_get_float +//Alias: caml_floatarray_unsafe_get +//Inline +function caml_array_unsafe_get(a, i) { + return a[i + 1]; +} //Provides: caml_array_fill function caml_array_fill(array, ofs, len, v) { for (var i = 0; i < len; i++) { diff --git a/runtime/js/format.js b/runtime/js/format.js index 40c215310e..1d6e3a0d2c 100644 --- a/runtime/js/format.js +++ b/runtime/js/format.js @@ -140,3 +140,11 @@ function caml_finish_formatting(f, rawbuffer) { if (f.justify === "-") for (var i = len; i < f.width; i++) buffer += " "; return caml_string_of_jsbytes(buffer); } + +//Provides: caml_format_int_special const +//Alias: %caml_format_int_special +//Requires: caml_string_of_jsstring +//Inline +function caml_format_int_special(x) { + return caml_string_of_jsstring ("" + x); +} diff --git a/runtime/js/ieee_754.js b/runtime/js/ieee_754.js index f0fc1cf124..9c8c7f0def 100644 --- a/runtime/js/ieee_754.js +++ b/runtime/js/ieee_754.js @@ -214,6 +214,162 @@ function caml_float_compare(x, y) { return 0; } +//Provides: caml_eq_float const +//Inline +function caml_eq_float(a, b) { + return a === b ? 1 : 0; +} + +//Provides: caml_neq_float const +//Inline +function caml_neq_float(a, b) { + return a !== b ? 1 : 0; +} + +//Provides: caml_ge_float const +//Inline +function caml_ge_float(a, b) { + return a >= b ? 1 : 0; +} + +//Provides: caml_le_float const +//Inline +function caml_le_float(a, b) { + return a <= b ? 1 : 0; +} + +//Provides: caml_gt_float const +//Inline +function caml_gt_float(a, b) { + return a > b ? 1 : 0; +} + +//Provides: caml_lt_float const +//Inline +function caml_lt_float(a, b) { + return a < b ? 1 : 0; +} + +//Provides: caml_add_float const +//Inline +function caml_add_float(a, b) { + return a + b; +} + +//Provides: caml_sub_float const +//Inline +function caml_sub_float(a, b) { + return a - b; +} + +//Provides: caml_mul_float const +//Inline +function caml_mul_float(a, b) { + return a * b; +} + +//Provides: caml_div_float const +//Inline +function caml_div_float(a, b) { + return a / b; +} + +//Provides: caml_neg_float const +//Inline +function caml_neg_float(a) { + return -a; +} + +//Provides: caml_fmod_float const +//Inline +function caml_fmod_float(a, b) { + return a % b; +} + +//Provides: caml_abs_float const +//Inline +function caml_abs_float(a) { + return Math.abs(a); +} + +//Provides: caml_acos_float const +//Inline +function caml_acos_float(a) { + return Math.acos(a); +} + +//Provides: caml_asin_float const +//Inline +function caml_asin_float(a) { + return Math.asin(a); +} + +//Provides: caml_atan_float const +//Inline +function caml_atan_float(a) { + return Math.atan(a); +} + +//Provides: caml_atan2_float const +//Inline +function caml_atan2_float(a, b) { + return Math.atan2(a, b); +} + +//Provides: caml_ceil_float const +//Inline +function caml_ceil_float(a) { + return Math.ceil(a); +} + +//Provides: caml_cos_float const +//Inline +function caml_cos_float(a) { + return Math.cos(a); +} + +//Provides: caml_exp_float const +//Inline +function caml_exp_float(a) { + return Math.exp(a); +} + +//Provides: caml_floor_float const +//Inline +function caml_floor_float(a) { + return Math.floor(a); +} + +//Provides: caml_log_float const +//Inline +function caml_log_float(a) { + return Math.log(a); +} + +//Provides: caml_power_float const +//Inline +function caml_power_float(a, b) { + return Math.pow(a, b); +} + +//Provides: caml_sin_float const +//Inline +function caml_sin_float(a) { + return Math.sin(a); +} + +//Provides: caml_sqrt_float const +//Inline +function caml_sqrt_float(a) { + return Math.sqrt(a); +} + +//Provides: caml_tan_float const +//Inline +function caml_tan_float(a) { + return Math.tan(a); +} + //Provides: caml_copysign_float const function caml_copysign_float(x, y) { if (y === 0) y = 1 / y; diff --git a/runtime/js/ints.js b/runtime/js/ints.js index 961058f2f3..904fa9774b 100644 --- a/runtime/js/ints.js +++ b/runtime/js/ints.js @@ -140,6 +140,108 @@ function caml_mul(a, b) { return Math.imul(a, b); } +//Provides: caml_add const +//Alias: %int_add +//Alias: caml_int32_add +//Alias: caml_nativeint_add +//Inline +function caml_add(a, b) { + return (a + b) | 0; +} + +//Provides: caml_sub const +//Alias: %int_sub +//Alias: caml_int32_sub +//Alias: caml_nativeint_sub +//Inline +function caml_sub(a, b) { + return (a - b) | 0; +} + +//Provides: caml_mul_direct const +//Alias: %direct_int_mul +//Inline +function caml_mul_direct(a, b) { + return (a * b) | 0; +} + +//Provides: caml_div_direct const +//Alias: %direct_int_div +//Inline +function caml_div_direct(a, b) { + return (a / b) | 0; +} + +//Provides: caml_mod_direct const +//Alias: %direct_int_mod +//Inline +function caml_mod_direct(a, b) { + return (a % b) | 0; +} + +//Provides: caml_int_and const +//Alias: %int_and +//Alias: caml_int32_and +//Alias: caml_nativeint_and +//Inline +function caml_int_and(a, b) { + return a & b; +} + +//Provides: caml_int_or const +//Alias: %int_or +//Alias: caml_int32_or +//Alias: caml_nativeint_or +//Inline +function caml_int_or(a, b) { + return a | b; +} + +//Provides: caml_int_xor const +//Alias: %int_xor +//Alias: caml_int32_xor +//Alias: caml_nativeint_xor +//Inline +function caml_int_xor(a, b) { + return a ^ b; +} + +//Provides: caml_int_shift_left const +//Alias: %int_lsl +//Alias: caml_int32_shift_left +//Alias: caml_nativeint_shift_left +//Inline +function caml_int_shift_left(a, i) { + return a << i; +} + +//Provides: caml_int_shift_right_unsigned const +//Alias: %int_lsr +//Alias: caml_int32_shift_right_unsigned +//Alias: caml_nativeint_shift_right_unsigned +//Inline +function caml_int_shift_right_unsigned(a, i) { + return (a >>> i) | 0; +} + +//Provides: caml_int_shift_right const +//Alias: %int_asr +//Alias: caml_int32_shift_right +//Alias: caml_nativeint_shift_right +//Inline +function caml_int_shift_right(a, i) { + return a >> i; +} + +//Provides: caml_int_neg const +//Alias: %int_neg +//Alias: caml_int32_neg +//Alias: caml_nativeint_neg +//Inline +function caml_int_neg(a) { + return -a | 0; +} + //Provides: caml_div //Requires: caml_raise_zero_divide //Alias: caml_int32_div diff --git a/runtime/js/obj.js b/runtime/js/obj.js index 2d2ab48b0d..63d10f2ba1 100644 --- a/runtime/js/obj.js +++ b/runtime/js/obj.js @@ -38,6 +38,13 @@ function caml_alloc_dummy_infix() { }; } +//Provides: caml_alloc_dummy const +//Alias: caml_alloc_dummy_float +//Inline +function caml_alloc_dummy(_unit) { + return []; +} + //Provides: caml_obj_tag //Requires: caml_is_ml_bytes, caml_is_ml_string function caml_obj_tag(x) { @@ -49,6 +56,13 @@ function caml_obj_tag(x) { else return 1000; } +//Provides: caml_obj_tag_direct const +//Alias: %direct_obj_tag +//Inline +function caml_obj_tag_direct(b) { + return b[0]; +} + //Provides: caml_obj_set_tag (mutable, const) //Version: < 5.0 function caml_obj_set_tag(x, tag) {