Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
* Runtime: fix caml_string_concat when not using JS strings (#1874)
* Runtime: consistent bigarray hashing across all architectures (#1977)
* Runtime: fix caml_utf8_of_utf16 bug in high surrogate case (#2008)
* Runtime/wasm: fix method lookup (#2034, #2038)
* Runtime/wasm/js: fix method lookup (#2034, #2038, #2039)
* Tools: fix jsoo_mktop and jsoo_mkcmis (#1877)
* Toplevel: fix for when use-js-strings is disabled (#1997)

Expand Down
18 changes: 16 additions & 2 deletions compiler/bin-js_of_ocaml/check_runtime.ml
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,30 @@ let f (runtime_files, bytecode, target_env) =
in
let needed = StringSet.of_list (List.map ~f:fst needed) in
let needed =
(* this list was copied from parse_bytecode *)
List.fold_left
~f:(fun acc x -> StringSet.remove x acc)
~init:needed
[ "caml_ensure_stack_capacity"
[ (* this list was copied from parse_bytecode *)
"caml_ensure_stack_capacity"
; "caml_process_pending_actions_with_root"
; "caml_make_array"
; "caml_array_of_uniform_array"
]
in
let needed =
(* internal primitives *)
List.fold_left
~f:(fun acc x -> StringSet.add x acc)
~init:needed
[ "caml_register_global"
; "caml_js_set"
; "caml_js_get"
; "caml_get_global_data"
; "caml_oo_cache_id"
; "caml_get_public_method"
; "caml_get_cached_method"
]
in
let from_runtime1 = Linker.list_all () in
let from_runtime2 = Primitive.get_external () in
(* [from_runtime2] is a superset of [from_runtime1].
Expand Down
35 changes: 15 additions & 20 deletions compiler/lib/parse_bytecode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ type globals =
; mutable is_const : bool array
; mutable is_exported : bool array
; mutable named_value : string option array
; mutable cache_ids : Var.t list
; constants : Code.constant array
; primitives : string array
}
Expand All @@ -541,6 +542,7 @@ let make_globals size constants primitives =
; is_const = Array.make size false
; is_exported = Array.make size false
; named_value = Array.make size None
; cache_ids = []
; constants
; primitives
}
Expand Down Expand Up @@ -818,8 +820,6 @@ let tagged_blocks = ref Addr.Map.empty

let compiled_blocks : (_ * instr list * last) Addr.Map.t ref = ref Addr.Map.empty

let method_cache_id = ref 1

let clo_offset_3 = 3

type compile_info =
Expand Down Expand Up @@ -2353,34 +2353,29 @@ and compile infos pc state (instrs : instr list) =
(Let (x, Prim (Ult, [ Pv z; Pv y ])) :: instrs)
| GETPUBMET ->
let n = gets32 code (pc + 1) in
let cache = !method_cache_id in
incr method_cache_id;
let obj = State.accu state in
let state = State.push state in
let tag, state = State.fresh_var state in
let cache_id = Var.fresh_n "cache_id" in
state.globals.cache_ids <- cache_id :: state.globals.cache_ids;
let m, state = State.fresh_var state in

if debug_parser () then Format.printf "%a = %ld@." Var.print tag n;
if debug_parser ()
then
Format.printf
"%a = caml_get_public_method(%a, %a)@."
"%a = caml_get_cached_method(%a, %ld)@."
Var.print
m
Var.print
obj
Var.print
tag;
n;
compile
infos
(pc + 3)
state
(Let
( m
, Prim
( Extern "caml_get_public_method"
, [ Pv obj; Pv tag; Pc (Int (Targetint.of_int_exn cache)) ] ) )
:: Let (tag, const32 n)
( Extern "caml_get_cached_method"
, [ Pv obj; Pc (Int (Targetint.of_int32_exn n)); Pv cache_id ] ) )
:: instrs)
| GETDYNMET ->
let tag = State.accu state in
Expand All @@ -2401,12 +2396,7 @@ and compile infos pc state (instrs : instr list) =
infos
(pc + 1)
state
(Let
( m
, Prim
( Extern "caml_get_public_method"
, [ Pv obj; Pv tag; Pc (Int Targetint.zero) ] ) )
:: instrs)
(Let (m, Prim (Extern "caml_get_public_method", [ Pv obj; Pv tag ])) :: instrs)
| GETMETHOD ->
let lab = State.accu state in
let obj = State.peek 0 state in
Expand Down Expand Up @@ -2537,7 +2527,12 @@ let parse_bytecode code globals debug_data =
in
compiled_blocks := Addr.Map.empty;
tagged_blocks := Addr.Map.empty;
Code.compact p
let p = Code.compact p in
let body =
List.fold_left globals.cache_ids ~init:[] ~f:(fun body cache_id ->
Let (cache_id, Prim (Extern "caml_oo_cache_id", [])) :: body)
in
Code.prepend p body

module Toc : sig
type t
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/main.4.14.output
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,8 @@ caml_string_concat
caml_to_js_string (deprecated)

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sync.js:
MlMutex
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/main.5.2.output
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/main.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/main.5.4.output
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Unix.4.14.output
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,8 @@ caml_string_concat
caml_to_js_string (deprecated)

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sync.js:
MlMutex
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Unix.5.2.output
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Unix.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Unix.5.4.output
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Win32.4.14.output
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,8 @@ caml_string_concat
caml_to_js_string (deprecated)

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sync.js:
MlMutex
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Win32.5.2.output
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
3 changes: 0 additions & 3 deletions compiler/tests-check-prim/unix-Win32.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,8 @@ caml_runtime_events_read_poll
caml_runtime_events_user_resolve

From +stdlib.js:
caml_build_symbols
caml_is_printable
caml_maybe_print_stats
caml_register_global
jsoo_toplevel_reloc

From +sys.js:
caml_fatal_uncaught_exception
Expand Down
15 changes: 15 additions & 0 deletions compiler/tests-compiler/dune.inc
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,21 @@
(preprocess
(pps ppx_expect)))

(library
;; compiler/tests-compiler/oo.ml
(name oo_15)
(enabled_if true)
(modules oo)
(libraries js_of_ocaml_compiler unix str jsoo_compiler_expect_tests_helper)
(inline_tests
(enabled_if true)
(deps
(file %{project_root}/compiler/bin-js_of_ocaml/js_of_ocaml.exe)
(file %{project_root}/compiler/bin-jsoo_minify/jsoo_minify.exe)))
(flags (:standard -open Jsoo_compiler_expect_tests_helper))
(preprocess
(pps ppx_expect)))

(library
;; compiler/tests-compiler/rec.ml
(name rec_15)
Expand Down
54 changes: 54 additions & 0 deletions compiler/tests-compiler/oo.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2025 Hugo Heuzard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)

let%expect_test _ =
let prog =
{|

let f o = o#a

let o1 = object
method a = print_endline "a from o1"
end

let o2 = object
method b = ()
method a = print_endline "a from o2"
end

let () = f o1; f o2
|}
in
Util.compile_and_run prog;
[%expect {|
a from o1
a from o2
|}];
let program = Util.compile_and_parse prog in
Util.print_var_decl program "cache_id";
Util.print_fun_decl program (Some "f");
[%expect
{|
var cache_id = runtime.caml_oo_cache_id();
//end
function f(o){
return caml_call1(runtime.caml_get_cached_method(o, 97, cache_id), o);
}
//end
|}]
8 changes: 4 additions & 4 deletions compiler/tests-full/stdlib.cma.expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -31666,15 +31666,15 @@
/*<<camlinternalOO.ml:587:57>>*/ new_cache(table);
/*<<camlinternalOO.ml:492:2>>*/ return function(obj){
/*<<camlinternalOO.ml:492:18>>*/ return caml_call1
(caml_get_public_method(x$9, m$2, 0), x$9) /*<<camlinternalOO.ml:492:58>>*/ ;} /*<<camlinternalOO.ml:492:2>>*/ ;
(caml_get_public_method(x$9, m$2), x$9) /*<<camlinternalOO.ml:492:58>>*/ ;} /*<<camlinternalOO.ml:492:2>>*/ ;
case 21:
var
m$3 = /*<<camlinternalOO.ml:589:14>>*/ next(0),
n$16 = /*<<camlinternalOO.ml:589:32>>*/ next(0);
/*<<camlinternalOO.ml:589:56>>*/ new_cache(table);
/*<<camlinternalOO.ml:494:2>>*/ return function(obj){
var _g_ = /*<<camlinternalOO.ml:495:4>>*/ obj[n$16 + 1];
return caml_call1(caml_get_public_method(_g_, m$3, 0), _g_) /*<<camlinternalOO.ml:496:32>>*/ ;} /*<<camlinternalOO.ml:494:2>>*/ ;
return caml_call1(caml_get_public_method(_g_, m$3), _g_) /*<<camlinternalOO.ml:496:32>>*/ ;} /*<<camlinternalOO.ml:494:2>>*/ ;
case 22:
var
m$4 = /*<<camlinternalOO.ml:591:14>>*/ next(0),
Expand All @@ -31683,7 +31683,7 @@
/*<<camlinternalOO.ml:592:21>>*/ new_cache(table);
/*<<camlinternalOO.ml:498:2>>*/ return function(obj){
var _g_ = /*<<camlinternalOO.ml:499:4>>*/ obj[e$4 + 1][n$17 + 1];
return caml_call1(caml_get_public_method(_g_, m$4, 0), _g_) /*<<camlinternalOO.ml:502:34>>*/ ;} /*<<camlinternalOO.ml:498:2>>*/ ;
return caml_call1(caml_get_public_method(_g_, m$4), _g_) /*<<camlinternalOO.ml:502:34>>*/ ;} /*<<camlinternalOO.ml:498:2>>*/ ;
default:
var
m$5 = /*<<camlinternalOO.ml:594:14>>*/ next(0),
Expand All @@ -31695,7 +31695,7 @@
/*<<camlinternalOO.ml:505:14>>*/ caml_call1
(obj[1][n$18 + 1], obj);
/*<<camlinternalOO.ml:505:30>>*/ return caml_call1
(caml_get_public_method(_g_, m$5, 0), _g_) /*<<camlinternalOO.ml:505:59>>*/ ;} /*<<camlinternalOO.ml:504:2>>*/ ;
(caml_get_public_method(_g_, m$5), _g_) /*<<camlinternalOO.ml:505:59>>*/ ;} /*<<camlinternalOO.ml:504:2>>*/ ;
}
/*<<camlinternalOO.ml:595:24>>*/ return clo;
/*<<camlinternalOO.ml:595:37>>*/ }
Expand Down
Loading
Loading