summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bytecomp/translclass.ml11
-rw-r--r--stdlib/oo.ml50
-rw-r--r--stdlib/oo.mli7
3 files changed, 38 insertions, 30 deletions
diff --git a/bytecomp/translclass.ml b/bytecomp/translclass.ml
index 01dc29c2c..501d1f30d 100644
--- a/bytecomp/translclass.ml
+++ b/bytecomp/translclass.ml
@@ -132,6 +132,14 @@ let transl_fields tbl public_methods meths fields cl_init =
Meths.fold (bind_methods tbl public_methods) meths
(List.fold_right (transl_field_cl tbl meths) fields cl_init)
+let creator args =
+ let table = Ident.create "table" in
+ let params =
+ table :: List.map (fun pat -> name_pattern "param" [pat, ()]) args
+ in
+ Lfunction (Curried, params,
+ Lapply (oo_prim "create_object",
+ List.map (fun p -> Lvar p) params))
let transl_class cl_id cl =
let public_methods = Lconst (transl_meth_list cl.cl_pub_meths) in
@@ -158,7 +166,8 @@ let transl_class cl_id cl =
[Lvar table; obj_init])))
cl.cl_field)
in
- Lapply (oo_prim "create_class", [Lvar cl_id; public_methods; cl_init])
+ Lapply (oo_prim "create_class",
+ [Lvar cl_id; public_methods; creator cl.cl_args; cl_init])
let class_stub =
Lprim(Pmakeblock(0, Mutable), [lambda_unit; lambda_unit; lambda_unit])
diff --git a/stdlib/oo.ml b/stdlib/oo.ml
index f3260c5b0..93909d2e0 100644
--- a/stdlib/oo.ml
+++ b/stdlib/oo.ml
@@ -47,10 +47,6 @@ let first_bucket = 0
let bucket_size = 32 (* Must be 256 or less *)
let initial_object_size = 2
-(**** Version ****)
-
-let version = ref 0
-
(**** Index ****)
type label = int
@@ -78,25 +74,31 @@ let dummy_item = (magic () : item)
type bucket = item array
+let version = ref 0
+
+let set_bucket_version (bucket : bucket) =
+ bucket.(bucket_size) <- (magic !version : item)
+
+let bucket_version bucket =
+ (magic bucket.(bucket_size) : int)
+
let bucket_list = ref []
let empty_bucket = [| |]
let new_bucket () =
let bucket = Array.create (bucket_size + 1) dummy_item in
- bucket.(bucket_size) <- (magic !version : item);
+ set_bucket_version bucket;
bucket_list := bucket :: !bucket_list;
bucket
let copy_bucket bucket =
let bucket = Array.copy bucket in
+ set_bucket_version bucket;
bucket.(bucket_size) <- (magic !version : item);
bucket_list := bucket :: !bucket_list;
bucket
-let bucket_version bucket =
- (magic bucket.(bucket_size) : int)
-
(**** Make a clean bucket ****)
let new_filled_bucket pos methods =
@@ -209,6 +211,10 @@ let new_method met =
let new_anonymous_method =
new_label
+(**** Types ****)
+
+type object = t array
+
(**** Sparse array ****)
module Vars = Map.Make(struct type t = string let compare = compare end)
@@ -290,7 +296,7 @@ let put array label element =
type t
type class_info =
- {mutable obj_init: t -> t;
+ {mutable obj_init: t;
mutable class_init: table -> unit;
mutable table: table}
@@ -432,7 +438,7 @@ let new_object table =
obj.(0) <- (magic table.buckets : t);
obj
-let create_class class_info public_methods class_init =
+let create_class class_info public_methods creator class_init =
let table = new_table () in
List.iter
(function met ->
@@ -445,26 +451,16 @@ let create_class class_info public_methods class_init =
inst_var_count := !inst_var_count + table.size - 1;
class_info.class_init <- class_init;
class_info.table <- table;
- let buckets = table.buckets in
- let initialization = Obj.magic (List.hd (List.hd table.init)) in
- class_info.obj_init <-
- (function x ->
- let obj = Obj.new_block object_tag table.size in
- Obj.set_field obj 0 (Obj.repr table.buckets);
- Obj.set_field obj 1 (Obj.repr (new_id ()));
- initialization obj x)
+ class_info.obj_init <- creator table
(**** Objects ****)
-type object = t array
-
-let inst_var obj lab =
- let (buck, elem) = decode lab in
- obj.((magic obj : int array array array).(0).(buck).(elem))
-
-let set_inst_var obj lab value =
- let (buck, elem) = decode lab in
- obj.((magic obj : int array array array).(0).(buck).(elem)) <- value
+let create_object table =
+ let obj = Obj.new_block object_tag table.size in
+ Obj.set_field obj 0 (Obj.repr table.buckets);
+ Obj.set_field obj 1 (Obj.repr (new_id ()));
+ let initialization = Obj.magic List.hd (List.hd table.init) in
+ initialization (Obj.obj obj)
let send obj lab =
let (buck, elem) = decode lab in
diff --git a/stdlib/oo.mli b/stdlib/oo.mli
index 07447097d..d5d5e0bf8 100644
--- a/stdlib/oo.mli
+++ b/stdlib/oo.mli
@@ -26,6 +26,7 @@ type label
val new_method: string -> label
(* Classes *)
+type t
type table
type item
type obj_init
@@ -38,11 +39,13 @@ val get_method_label: table -> string -> label
val get_variable: table -> string -> int
val hide_variable: table -> string -> unit
val get_private_variable: table -> string -> int
-val create_class: class_info -> string list -> (table -> unit) -> unit
+val create_class:
+ class_info -> string list -> (table -> t) ->
+ (table -> unit) -> unit
(* Objects *)
-type t
type object
+val create_object: table -> t
val send: object -> label -> t
(* Parameters *)