summaryrefslogtreecommitdiff
path: root/src/Contexts.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/Contexts.ml')
-rw-r--r--src/Contexts.ml118
1 files changed, 59 insertions, 59 deletions
diff --git a/src/Contexts.ml b/src/Contexts.ml
index 07535e06..510976f4 100644
--- a/src/Contexts.ml
+++ b/src/Contexts.ml
@@ -5,56 +5,56 @@ module V = Values
open ValuesUtils
(** Some global counters.
- *
- * Note that those counters were initially stored in [eval_ctx] values,
- * but it proved better to make them global and stateful:
- * - when branching (and thus executing on several paths with different
- * contexts) it is better to really have unique ids everywhere (and
- * not have fresh ids shared by several contexts even though introduced
- * after the branching) because at some point we might need to merge the
- * different contexts
- * - also, it is a lot more convenient to not store those counters in contexts
- * objects
- *
- * =============
- * **WARNING**:
- * =============
- * Pay attention when playing with closures, as you may not always generate
- * fresh identifiers without noticing it, especially when using type abbreviations.
- * For instance, consider the following:
- * ```
- * type fun_type = unit -> ...
- * fn f x : fun_type =
- * let id = fresh_id () in
- * ...
- *
- * let g = f x in // <-- the fresh identifier gets generated here
- * let x1 = g () in // <-- no fresh generation here
- * let x2 = g () in
- * ...
- * ```
- *
- * This is why, in such cases, we often introduce all the inputs, even
- * when they are not used (which happens!).
- * ```
- * fn f x : fun_type =
- * fun .. ->
- * let id = fresh_id () in
- * ...
- * ```
- *
- * Note that in practice, we never reuse closures, except when evaluating
- * a branching in the execution (which is fine, because the branches evaluate
- * independentely of each other). Still, it is always a good idea to be
- * defensive.
- *
- * However, the same problem arises with logging.
- *
- * Also, a more defensive way would be to not use global references, and
- * store the counters in the evaluation context. This is actually what was
- * originally done, before we updated the code to use global counters because
- * it proved more convenient (and even before updating the code of the
- * interpreter to use CPS).
+
+ Note that those counters were initially stored in {!eval_ctx} values,
+ but it proved better to make them global and stateful:
+ - when branching (and thus executing on several paths with different
+ contexts) it is better to really have unique ids everywhere (and
+ not have fresh ids shared by several contexts even though introduced
+ after the branching) because at some point we might need to merge the
+ different contexts
+ - also, it is a lot more convenient to not store those counters in contexts
+ objects
+
+ =============
+ **WARNING**:
+ =============
+ Pay attention when playing with closures, as you may not always generate
+ fresh identifiers without noticing it, especially when using type abbreviations.
+ For instance, consider the following:
+ {[
+ type fun_type = unit -> ...
+ fn f x : fun_type =
+ let id = fresh_id () in
+ ...
+
+ let g = f x in // <-- the fresh identifier gets generated here
+ let x1 = g () in // <-- no fresh generation here
+ let x2 = g () in
+ ...
+ ]}
+
+ This is why, in such cases, we often introduce all the inputs, even
+ when they are not used (which happens!).
+ {[
+ fn f x : fun_type =
+ fun .. ->
+ let id = fresh_id () in
+ ...
+ ]}
+
+ Note that in practice, we never reuse closures, except when evaluating
+ a branching in the execution (which is fine, because the branches evaluate
+ independentely of each other). Still, it is always a good idea to be
+ defensive.
+
+ However, the same problem arises with logging.
+
+ Also, a more defensive way would be to not use global references, and
+ store the counters in the evaluation context. This is actually what was
+ originally done, before we updated the code to use global counters because
+ it proved more convenient (and even before updating the code of the
+ interpreter to use CPS).
*)
let symbolic_value_id_counter, fresh_symbolic_value_id =
@@ -87,12 +87,12 @@ let reset_global_counters () =
abstraction_id_counter := AbstractionId.generator_zero;
fun_call_id_counter := FunCallId.generator_zero
+(** A binder used in an environment, to map a variable to a value *)
type binder = {
index : VarId.id; (** Unique variable identifier *)
name : string option; (** Possible name *)
}
[@@deriving show]
-(** A binder used in an environment, to map a variable to a value *)
(** Environment value: mapping from variable to value, abstraction (only
used in symbolic mode) or stack frame delimiter.
@@ -113,7 +113,7 @@ type env_elem =
name = "iter_env_elem";
variety = "iter";
ancestors = [ "iter_abs" ];
- nude = true (* Don't inherit [VisitorsRuntime.iter] *);
+ nude = true (* Don't inherit {!VisitorsRuntime.iter} *);
concrete = true;
},
visitors
@@ -121,7 +121,7 @@ type env_elem =
name = "map_env_elem";
variety = "map";
ancestors = [ "map_abs" ];
- nude = true (* Don't inherit [VisitorsRuntime.iter] *);
+ nude = true (* Don't inherit {!VisitorsRuntime.iter} *);
concrete = true;
}]
@@ -133,7 +133,7 @@ type env = env_elem list
name = "iter_env";
variety = "iter";
ancestors = [ "iter_env_elem" ];
- nude = true (* Don't inherit [VisitorsRuntime.iter] *);
+ nude = true (* Don't inherit {!VisitorsRuntime.iter} *);
concrete = true;
},
visitors
@@ -141,7 +141,7 @@ type env = env_elem list
name = "map_env";
variety = "map";
ancestors = [ "map_env_elem" ];
- nude = true (* Don't inherit [VisitorsRuntime.iter] *);
+ nude = true (* Don't inherit {!VisitorsRuntime.iter} *);
concrete = true;
}]
@@ -189,13 +189,13 @@ type config = {
}
[@@deriving show]
+(** See {!config} *)
type partial_config = {
check_invariants : bool;
greedy_expand_symbolics_with_borrows : bool;
allow_bottom_below_borrow : bool;
return_unit_end_abs_with_no_loans : bool;
}
-(** See [config] *)
let config_of_partial (mode : interpreter_mode) (config : partial_config) :
config =
@@ -220,6 +220,7 @@ type fun_context = { fun_decls : fun_decl FunDeclId.Map.t } [@@deriving show]
type global_context = { global_decls : global_decl GlobalDeclId.Map.t }
[@@deriving show]
+(** Evaluation context *)
type eval_ctx = {
type_context : type_context;
fun_context : fun_context;
@@ -229,7 +230,6 @@ type eval_ctx = {
ended_regions : RegionId.Set.t;
}
[@@deriving show]
-(** Evaluation context *)
let lookup_type_var (ctx : eval_ctx) (vid : TypeVarId.id) : type_var =
TypeVarId.nth ctx.type_vars vid
@@ -366,11 +366,11 @@ let ctx_read_first_dummy_var (ctx : eval_ctx) : typed_value =
in
read_var ctx.env
-(** Push an uninitialized variable (which thus maps to [Bottom]) *)
+(** Push an uninitialized variable (which thus maps to {!Values.Bottom}) *)
let ctx_push_uninitialized_var (ctx : eval_ctx) (var : var) : eval_ctx =
ctx_push_var ctx var (mk_bottom var.var_ty)
-(** Push a list of uninitialized variables (which thus map to [Bottom]) *)
+(** Push a list of uninitialized variables (which thus map to {!Values.Bottom}) *)
let ctx_push_uninitialized_vars (ctx : eval_ctx) (vars : var list) : eval_ctx =
let vars = List.map (fun v -> (v, mk_bottom v.var_ty)) vars in
ctx_push_vars ctx vars