summaryrefslogtreecommitdiff
path: root/lib/dyn.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dyn.ml')
-rw-r--r--lib/dyn.ml48
1 files changed, 36 insertions, 12 deletions
diff --git a/lib/dyn.ml b/lib/dyn.ml
index e756297f..63def9a1 100644
--- a/lib/dyn.ml
+++ b/lib/dyn.ml
@@ -1,25 +1,49 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Util
+open Errors
(* Dynamics, programmed with DANGER !!! *)
-type t = string * Obj.t
+type t = int * Obj.t
-let dyntab = ref ([] : string list)
+let dyntab = ref (Int.Map.empty : string Int.Map.t)
+(** Instead of working with tags as strings, which are costly, we use their
+ hash. We ensure unicity of the hash in the [create] function. If ever a
+ collision occurs, which is unlikely, it is sufficient to tweak the offending
+ dynamic tag. *)
-let create s =
- if List.mem s !dyntab then
- anomaly ("Dyn.create: already declared dynamic " ^ s);
- dyntab := s :: !dyntab;
- ((fun v -> (s,Obj.repr v)),
- (fun (s',rv) ->
- if s = s' then Obj.magic rv else failwith "dyn_out"))
+let create (s : string) =
+ let hash = Hashtbl.hash s in
+ let () =
+ if Int.Map.mem hash !dyntab then
+ let old = Int.Map.find hash !dyntab in
+ let msg = Pp.str ("Dynamic tag collision: " ^ s ^ " vs. " ^ old) in
+ anomaly ~label:"Dyn.create" msg
+ in
+ let () = dyntab := Int.Map.add hash s !dyntab in
+ let infun v = (hash, Obj.repr v) in
+ let outfun (nh, rv) =
+ if Int.equal hash nh then Obj.magic rv
+ else
+ let msg = (Pp.str ("dyn_out: expected " ^ s)) in
+ anomaly msg
+ in
+ (infun, outfun)
-let tag (s,_) = s
+let has_tag (s, _) tag =
+ let hash = Hashtbl.hash (tag : string) in
+ Int.equal s hash
+
+let tag (s,_) =
+ try Int.Map.find s !dyntab
+ with Not_found ->
+ let msg = Pp.str ("Unknown dynamic tag " ^ (string_of_int s)) in
+ anomaly msg
+
+let pointer_equal (t1,o1) (t2,o2) = t1 = t2 && o1 == o2