diff options
| author | Graydon Hoare <[email protected]> | 2010-11-02 11:11:58 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-11-02 11:11:58 -0700 |
| commit | da13c508d83032ca13679e1e122e96d25ac23283 (patch) | |
| tree | 51c3d466dfedf3ad8e21b56c4769325561b3d650 /src/boot | |
| parent | Un-XFAIL self tests on Darwin (diff) | |
| download | rust-da13c508d83032ca13679e1e122e96d25ac23283.tar.xz rust-da13c508d83032ca13679e1e122e96d25ac23283.zip | |
First pass on splitting stratum and opacity off of effects. WIP.
Diffstat (limited to 'src/boot')
| -rw-r--r-- | src/boot/fe/ast.ml | 80 | ||||
| -rw-r--r-- | src/boot/fe/cexp.ml | 2 | ||||
| -rw-r--r-- | src/boot/fe/fuzz.ml | 2 | ||||
| -rw-r--r-- | src/boot/fe/item.ml | 35 | ||||
| -rw-r--r-- | src/boot/fe/lexer.mll | 6 | ||||
| -rw-r--r-- | src/boot/fe/pexp.ml | 22 | ||||
| -rw-r--r-- | src/boot/fe/token.ml | 20 | ||||
| -rw-r--r-- | src/boot/me/dwarf.ml | 15 | ||||
| -rw-r--r-- | src/boot/me/effect.ml | 14 | ||||
| -rw-r--r-- | src/boot/me/semant.ml | 49 | ||||
| -rw-r--r-- | src/boot/me/typestate.ml | 3 |
11 files changed, 168 insertions, 80 deletions
diff --git a/src/boot/fe/ast.ml b/src/boot/fe/ast.ml index f81f614f..b72c4935 100644 --- a/src/boot/fe/ast.ml +++ b/src/boot/fe/ast.ml @@ -29,10 +29,20 @@ type slot_key = *) type effect = - PURE - | IO - | STATE - | UNSAFE + EFF_pure + | EFF_impure + | EFF_unsafe +;; + +type stratum = + STRAT_value + | STRAT_state + | STRAT_gc +;; + +type opacity = + OPA_transparent + | OPA_abstract ;; type mutability = @@ -702,10 +712,48 @@ and fmt_effect (effect:effect) : unit = match effect with - PURE -> () - | IO -> fmt ff "io" - | STATE -> fmt ff "state" - | UNSAFE -> fmt ff "unsafe" + EFF_pure -> () + | EFF_impure -> fmt ff "impure" + | EFF_unsafe -> fmt ff "unsafe" + +and fmt_effect_qual + (ff:Format.formatter) + (e:effect) + : unit = + fmt_effect ff e; + if e <> EFF_pure then fmt ff " "; + +and fmt_stratum + (ff:Format.formatter) + (strat:stratum) + : unit = + match strat with + STRAT_value -> () + | STRAT_state -> fmt ff "state" + | STRAT_gc -> fmt ff "gc" + +and fmt_stratum_qual + (ff:Format.formatter) + (s:stratum) + : unit = + fmt_stratum ff s; + if s <> STRAT_value then fmt ff " "; + +and fmt_opacity + (ff:Format.formatter) + (opa:opacity) + : unit = + match opa with + OPA_transparent -> () + | OPA_abstract -> fmt ff "abs" + +and fmt_opacity_qual + (ff:Format.formatter) + (op:opacity) + : unit = + fmt_opacity ff op; + if op <> OPA_transparent then fmt ff " "; + and fmt_ty_fn (ff:Format.formatter) @@ -713,8 +761,7 @@ and fmt_ty_fn (tf:ty_fn) : unit = let (tsig, ta) = tf in - fmt_effect ff ta.fn_effect; - if ta.fn_effect <> PURE then fmt ff " "; + fmt_effect_qual ff ta.fn_effect; fmt ff "%s" (if ta.fn_is_iter then "iter" else "fn"); begin match ident_and_params with @@ -763,8 +810,7 @@ and fmt_ty (ff:Format.formatter) (t:ty) : unit = fmt_ident_tys ff entries; fmt ff "@]" - | TY_param (i, e) -> (fmt_effect ff e; - if e <> PURE then fmt ff " "; + | TY_param (i, e) -> (fmt_effect_qual ff e; fmt ff "<p#%d>" i) | TY_native oid -> fmt ff "<native#%d>" (int_of_opaque oid) | TY_named n -> fmt_name ff n @@ -789,8 +835,7 @@ and fmt_ty (ff:Format.formatter) (t:ty) : unit = | TY_obj (effect, fns) -> fmt_obox ff; - fmt_effect ff effect; - if effect <> PURE then fmt ff " "; + fmt_effect_qual ff effect; fmt ff "obj "; fmt_obr ff; Hashtbl.iter @@ -1584,8 +1629,7 @@ and fmt_slice (ff:Format.formatter) (slice:slice) : unit = and fmt_decl_param (ff:Format.formatter) (param:ty_param) : unit = let (ident, (i, e)) = param in - fmt_effect ff e; - if e <> PURE then fmt ff " "; + fmt_effect_qual ff e; fmt_ident ff ident; fmt ff "=<p#%d>" i @@ -1608,10 +1652,6 @@ and fmt_ident_and_params fmt_ident ff id; fmt_decl_params ff params -and fmt_effect_qual (ff:Format.formatter) (e:effect) : unit = - fmt_effect ff e; - if e <> PURE then fmt ff " "; - and fmt_fn (ff:Format.formatter) (id:ident) diff --git a/src/boot/fe/cexp.ml b/src/boot/fe/cexp.ml index 6828689f..3ca4ded7 100644 --- a/src/boot/fe/cexp.ml +++ b/src/boot/fe/cexp.ml @@ -181,7 +181,7 @@ and parse_cexp (ps:pstate) : cexp = fun (ident, item) -> htab_put items ident item end - (Item.parse_mod_item_from_signature ps) + (Item.parse_native_mod_item_from_signature ps) in ignore (bracketed_zero_or_more LBRACE RBRACE None get_item ps); diff --git a/src/boot/fe/fuzz.ml b/src/boot/fe/fuzz.ml index 47a708dc..e8db9f39 100644 --- a/src/boot/fe/fuzz.ml +++ b/src/boot/fe/fuzz.ml @@ -104,7 +104,7 @@ let rec generate_mod_item (mis:mod_items) (cx:ctxt) : unit = match Random.int 2 with 0 -> let ty = generate_ty cx in - let eff = PURE in + let eff = Ast.EFF_pure in decl (MOD_ITEM_type (eff, ty)) | _ -> let mis' = Hashtbl.create 0 in diff --git a/src/boot/fe/item.ml b/src/boot/fe/item.ml index c1746cc2..4c9bd556 100644 --- a/src/boot/fe/item.ml +++ b/src/boot/fe/item.ml @@ -154,8 +154,6 @@ and parse_stmts (ps:pstate) : Ast.stmt array = if (Array.length arr) == 0 then raise (err "statement does nothing" ps); arr - - (* * We have no way to parse a single Ast.stmt; any incoming syntactic statement @@ -605,7 +603,11 @@ and parse_stmts_including_none (ps:pstate) : Ast.stmt array = expect ps SEMI; spans ps stmts apos (Ast.STMT_join lval) - | IO | STATE | UNSAFE | MOD | OBJ | TAG | TYPE | FN | USE | NATIVE -> + + | STATE | GC + | IMPURE | UNSAFE + | ABS | NATIVE + | MOD | OBJ | TAG | TYPE | FN | USE -> let items = ctxt "stmt: decl" parse_mod_item ps in let bpos = lexpos ps in Array.map @@ -689,6 +691,8 @@ and parse_stmts_including_none (ps:pstate) : Ast.stmt array = and parse_ty_param (iref:int ref) (ps:pstate) : Ast.ty_param identified = let apos = lexpos ps in + let _ = Pexp.parse_opacity ps in + let _ = Pexp.parse_stratum ps in let e = Pexp.parse_effect ps in let ident = Pexp.parse_ident ps in let i = !iref in @@ -851,7 +855,7 @@ and parse_obj_item do let apos = lexpos ps in match peek ps with - IO | STATE | UNSAFE | FN | ITER -> + IMPURE | UNSAFE | FN | ITER -> let effect = Pexp.parse_effect ps in let is_iter = (peek ps) = ITER in bump ps; @@ -986,7 +990,10 @@ and parse_mod_item (ps:pstate) match peek ps with - IO | STATE | UNSAFE | TYPE | OBJ | TAG | FN | ITER -> + STATE | GC | IMPURE | UNSAFE | ABS + | TYPE | OBJ | TAG | FN | ITER -> + let _ = Pexp.parse_opacity ps in + let _ = Pexp.parse_stratum ps in let effect = Pexp.parse_effect ps in begin match peek ps with @@ -1044,7 +1051,7 @@ and parse_mod_item (ps:pstate) expect ps MOD; let ident = Pexp.parse_ident ps in let path = parse_lib_name ident in - let items = parse_mod_items_from_signature ps in + let items = parse_native_mod_items_from_signature ps in let bpos = lexpos ps in let rlib = REQUIRED_LIB_c { required_libname = path; required_prefix = ps.pstate_depth } @@ -1056,7 +1063,7 @@ and parse_mod_item (ps:pstate) end | _ -> raise (unexpected ps) -and parse_mod_items_header_from_signature (ps:pstate) : Ast.mod_view = +and parse_native_mod_header_from_signature (ps:pstate) : Ast.mod_view = let exports = Hashtbl.create 0 in while (peek ps = EXPORT) do @@ -1068,11 +1075,11 @@ and parse_mod_items_header_from_signature (ps:pstate) : Ast.mod_view = then htab_put exports Ast.EXPORT_all_decls (); {empty_view with Ast.view_exports = exports} -and parse_mod_items_from_signature +and parse_native_mod_items_from_signature (ps:pstate) : (Ast.mod_view * Ast.mod_items) = expect ps LBRACE; - let view = parse_mod_items_header_from_signature ps in + let view = parse_native_mod_header_from_signature ps in let items = Hashtbl.create 0 in while not (peek ps = RBRACE) do @@ -1080,24 +1087,24 @@ and parse_mod_items_from_signature (fun (ident, item) -> htab_put items ident item) (ctxt "mod items from sig: mod item" - parse_mod_item_from_signature ps) + parse_native_mod_item_from_signature ps) done; expect ps RBRACE; (view,items) -and parse_mod_item_from_signature (ps:pstate) +and parse_native_mod_item_from_signature (ps:pstate) : (Ast.ident * Ast.mod_item) array = let apos = lexpos ps in match peek ps with MOD -> bump ps; let (ident, params) = parse_ident_and_params ps "mod signature" in - let items = parse_mod_items_from_signature ps in + let items = parse_native_mod_items_from_signature ps in let bpos = lexpos ps in [| (ident, span ps apos bpos (decl params (Ast.MOD_ITEM_mod items))) |] - | IO | STATE | UNSAFE | FN | ITER -> + | IMPURE | UNSAFE | FN | ITER -> let effect = Pexp.parse_effect ps in let is_iter = (peek ps) = ITER in bump ps; @@ -1142,7 +1149,7 @@ and parse_mod_item_from_signature (ps:pstate) expect ps SEMI; let bpos = lexpos ps in [| (ident, span ps apos bpos - (decl params (Ast.MOD_ITEM_type (Ast.UNSAFE, t)))) |] + (decl params (Ast.MOD_ITEM_type (Ast.EFF_unsafe, t)))) |] | _ -> raise (unexpected ps) diff --git a/src/boot/fe/lexer.mll b/src/boot/fe/lexer.mll index 151af827..84aeb9ab 100644 --- a/src/boot/fe/lexer.mll +++ b/src/boot/fe/lexer.mll @@ -95,8 +95,12 @@ ("claim", CLAIM); ("prove", PROVE); - ("io", IO); + ("abs", ABS); + ("state", STATE); + ("gc", GC); + + ("impure", IMPURE); ("unsafe", UNSAFE); ("native", NATIVE); diff --git a/src/boot/fe/pexp.ml b/src/boot/fe/pexp.ml index 85eb32c4..59cfaf75 100644 --- a/src/boot/fe/pexp.ml +++ b/src/boot/fe/pexp.ml @@ -140,12 +140,22 @@ and parse_optional_trailing_constrs (ps:pstate) : Ast.constrs = COLON -> (bump ps; parse_constrs ps) | _ -> [| |] +and parse_opacity (ps:pstate) : Ast.opacity = + match peek ps with + ABS -> bump ps; Ast.OPA_abstract + | _ -> Ast.OPA_transparent + +and parse_stratum (ps:pstate) : Ast.stratum = + match peek ps with + STATE -> bump ps; Ast.STRAT_state + | GC -> bump ps; Ast.STRAT_gc + | _ -> Ast.STRAT_value + and parse_effect (ps:pstate) : Ast.effect = match peek ps with - IO -> bump ps; Ast.IO - | STATE -> bump ps; Ast.STATE - | UNSAFE -> bump ps; Ast.UNSAFE - | _ -> Ast.PURE + IMPURE -> bump ps; Ast.EFF_impure + | UNSAFE -> bump ps; Ast.EFF_unsafe + | _ -> Ast.EFF_pure and parse_mutability (ps:pstate) : Ast.mutability = match peek ps with @@ -263,7 +273,9 @@ and parse_atomic_ty (ps:pstate) : Ast.ty = bump ps; Ast.TY_mach m - | IO | STATE | UNSAFE | OBJ | FN | ITER -> + | ABS | STATE | GC | IMPURE | UNSAFE | OBJ | FN | ITER -> + let _ = parse_opacity ps in + let _ = parse_stratum ps in let effect = parse_effect ps in begin match peek ps with diff --git a/src/boot/fe/token.ml b/src/boot/fe/token.ml index cd41ec2f..6c2282de 100644 --- a/src/boot/fe/token.ml +++ b/src/boot/fe/token.ml @@ -80,9 +80,15 @@ type token = | CLAIM | PROVE - (* Effect keywords *) - | IO + (* Opacity keywords *) + | ABS + + (* Stratum keywords *) | STATE + | GC + + (* Effect keywords *) + | IMPURE | UNSAFE (* Type qualifiers *) @@ -237,9 +243,15 @@ let rec string_of_tok t = | CLAIM -> "claim" | PROVE -> "prove" - (* Effect keywords *) - | IO -> "io" + (* Opacity keywords *) + | ABS -> "abs" + + (* Stratum keywords *) | STATE -> "state" + | GC -> "gc" + + (* Effect keywords *) + | IMPURE -> "impure" | UNSAFE -> "unsafe" (* Type qualifiers *) diff --git a/src/boot/me/dwarf.ml b/src/boot/me/dwarf.ml index 08f8c347..86a0c8a6 100644 --- a/src/boot/me/dwarf.ml +++ b/src/boot/me/dwarf.ml @@ -1527,10 +1527,9 @@ let dwarf_visitor (* Note: weird encoding: mutable+pure = unsafe. *) let mut_byte, pure_byte = match eff with - Ast.UNSAFE -> (1,1) - | Ast.STATE -> (1,0) - | Ast.IO -> (0,0) - | Ast.PURE -> (0,1) + Ast.EFF_unsafe -> (1,1) + | Ast.EFF_impure -> (0,0) + | Ast.EFF_pure -> (0,1) in SEQ [| (* DW_AT_mutable: DW_FORM_flag *) @@ -2888,10 +2887,10 @@ let rec extract_mod_items let get_effect die = match (get_flag die DW_AT_mutable, get_flag die DW_AT_pure) with (* Note: weird encoding: mutable+pure = unsafe. *) - (true, true) -> Ast.UNSAFE - | (true, false) -> Ast.STATE - | (false, false) -> Ast.IO - | (false, true) -> Ast.PURE + (true, true) -> Ast.EFF_unsafe + | (false, false) -> Ast.EFF_impure + | (false, true) -> Ast.EFF_pure + | _ -> failwith "bad effect encoding" in let get_name die = get_str die DW_AT_name in diff --git a/src/boot/me/effect.ml b/src/boot/me/effect.ml index 8a8292d9..3bb761ef 100644 --- a/src/boot/me/effect.ml +++ b/src/boot/me/effect.ml @@ -92,7 +92,7 @@ let function_effect_propagation_visitor * This visitor calculates the effect of each function according to * its statements: * - * - Communication lowers to 'io' + * - Communication statements lower to 'impure' * - Native calls lower to 'unsafe' * - Calling a function with effect e lowers to e. *) @@ -138,7 +138,7 @@ let function_effect_propagation_visitor let fn_id = Stack.top curr_fn in let e = match htab_search item_effect fn_id with - None -> Ast.PURE + None -> Ast.EFF_pure | Some e -> e in let ne = lower_effect_of ne e in @@ -163,7 +163,7 @@ let function_effect_propagation_visitor begin match s.node with Ast.STMT_send _ - | Ast.STMT_recv _ -> lower_to s Ast.IO + | Ast.STMT_recv _ -> lower_to s Ast.EFF_impure | Ast.STMT_call (_, fn, _) -> let lower_to_callee_ty t = @@ -183,7 +183,7 @@ let function_effect_propagation_visitor match htab_search cx.ctxt_required_items item.id with None -> () | Some (REQUIRED_LIB_rust _, _) -> () - | Some _ -> lower_to s Ast.UNSAFE + | Some _ -> lower_to s Ast.EFF_unsafe end | _ -> () end; @@ -232,7 +232,7 @@ let effect_checking_visitor | Some e -> let curr = if Stack.is_empty auth_stack - then Ast.PURE + then Ast.EFF_pure else Stack.top auth_stack in let next = lower_effect_of e curr in @@ -253,7 +253,7 @@ let effect_checking_visitor Ast.MOD_ITEM_fn f -> let e = match htab_search item_effect i.id with - None -> Ast.PURE + None -> Ast.EFF_pure | Some e -> e in let fe = f.Ast.fn_aux.Ast.fn_effect in @@ -291,7 +291,7 @@ let effect_checking_visitor let curr = Stack.pop auth_stack in let next = if Stack.is_empty auth_stack - then Ast.PURE + then Ast.EFF_pure else Stack.top auth_stack in iflog cx diff --git a/src/boot/me/semant.ml b/src/boot/me/semant.ml index 1eb88ab1..1b65c0db 100644 --- a/src/boot/me/semant.ml +++ b/src/boot/me/semant.ml @@ -191,7 +191,7 @@ type ctxt = ctxt_rty_cache: (Ast.ty,Il.referent_ty) Hashtbl.t; - ctxt_type_effect_cache: (Ast.ty,Ast.effect) Hashtbl.t; + ctxt_type_stratum_cache: (Ast.ty,Ast.stratum) Hashtbl.t; ctxt_type_points_to_heap_cache: (Ast.ty,bool) Hashtbl.t; ctxt_type_is_structured_cache: (Ast.ty,bool) Hashtbl.t; ctxt_type_contains_chan_cache: (Ast.ty,bool) Hashtbl.t; @@ -296,7 +296,7 @@ let new_ctxt sess abi crate = ctxt_curr_path = Stack.create (); ctxt_rty_cache = Hashtbl.create 0; - ctxt_type_effect_cache = Hashtbl.create 0; + ctxt_type_stratum_cache = Hashtbl.create 0; ctxt_type_points_to_heap_cache = Hashtbl.create 0; ctxt_type_is_structured_cache = Hashtbl.create 0; ctxt_type_contains_chan_cache = Hashtbl.create 0; @@ -1227,16 +1227,15 @@ let type_points_to_heap (cx:ctxt) (t:Ast.ty) : bool = (fun _ -> fold_ty cx fold t) ;; -(* Effect analysis. *) + +(* Type qualifier analysis. *) + let effect_le x y = match (x,y) with - (Ast.UNSAFE, _) -> true - | (Ast.STATE, Ast.PURE) -> true - | (Ast.STATE, Ast.IO) -> true - | (Ast.STATE, Ast.STATE) -> true - | (Ast.IO, Ast.PURE) -> true - | (Ast.IO, Ast.IO) -> true - | (Ast.PURE, Ast.PURE) -> true + (Ast.EFF_unsafe, _) -> true + | (Ast.EFF_impure, Ast.EFF_pure) -> true + | (Ast.EFF_impure, Ast.EFF_impure) -> true + | (Ast.EFF_pure, Ast.EFF_pure) -> true | _ -> false ;; @@ -1244,16 +1243,30 @@ let lower_effect_of x y = if effect_le x y then x else y ;; -let type_effect (cx:ctxt) (t:Ast.ty) : Ast.effect = - let fold_mutable _ = Ast.STATE in - let fold = associative_binary_op_ty_fold Ast.PURE lower_effect_of in +let stratum_le x y = + match (x,y) with + (Ast.STRAT_gc, _) -> true + | (Ast.STRAT_state, Ast.STRAT_value) -> true + | (Ast.STRAT_state, Ast.STRAT_state) -> true + | (Ast.STRAT_value, Ast.STRAT_value) -> true + | _ -> false +;; + +let lower_stratum_of x y = + if stratum_le x y then x else y +;; + +let type_stratum (cx:ctxt) (t:Ast.ty) : Ast.stratum = + let fold_mutable _ = Ast.STRAT_state in + let fold = associative_binary_op_ty_fold Ast.STRAT_value lower_stratum_of in let fold = { fold with ty_fold_mutable = fold_mutable } in - htab_search_or_add cx.ctxt_type_effect_cache t + htab_search_or_add cx.ctxt_type_stratum_cache t (fun _ -> fold_ty cx fold t) ;; + let type_has_state (cx:ctxt) (t:Ast.ty) : bool = - effect_le (type_effect cx t) Ast.STATE + stratum_le (type_stratum cx t) Ast.STRAT_state ;; @@ -1627,7 +1640,7 @@ let ty_of_mod_item (item:Ast.mod_item) : Ast.ty = | Ast.MOD_ITEM_mod _ -> bug () "Semant.ty_of_mod_item on mod" | Ast.MOD_ITEM_const (ty, _) -> ty | Ast.MOD_ITEM_obj ob -> - let taux = { Ast.fn_effect = Ast.PURE; + let taux = { Ast.fn_effect = Ast.EFF_pure; Ast.fn_is_iter = false } in let tobj = Ast.TY_obj (ty_obj_of_obj ob) in @@ -1650,7 +1663,7 @@ let ty_of_mod_item (item:Ast.mod_item) : Ast.ty = if Array.length hdr = 0 then Ast.TY_tag ttag else - let taux = { Ast.fn_effect = Ast.PURE; + let taux = { Ast.fn_effect = Ast.EFF_pure; Ast.fn_is_iter = false } in let inputs = Array.map (fun (s, _) -> s.node) hdr in @@ -2561,7 +2574,7 @@ let mk_ty_fn_or_iter (is_iter:bool) : Ast.ty = (* In some cases we don't care what aux or constrs are. *) - let taux = { Ast.fn_effect = Ast.PURE; + let taux = { Ast.fn_effect = Ast.EFF_pure; Ast.fn_is_iter = is_iter; } in let tsig = { Ast.sig_input_slots = arg_slots; diff --git a/src/boot/me/typestate.ml b/src/boot/me/typestate.ml index 00629886..0579775f 100644 --- a/src/boot/me/typestate.ml +++ b/src/boot/me/typestate.ml @@ -126,7 +126,7 @@ let determine_constr_key match Hashtbl.find cx.ctxt_all_item_types cid with Ast.TY_fn (_, taux) -> begin - if taux.Ast.fn_effect = Ast.PURE + if taux.Ast.fn_effect = Ast.EFF_pure then cid else err (Some cid) "impure function used in constraint" end @@ -989,6 +989,7 @@ let graph_special_block_structure_building_visitor Hashtbl.replace graph cond_id [then_id; else_id]; Hashtbl.replace graph then_end_id succ; Hashtbl.replace graph else_end_id succ; + (* Kill residual messed-up block wiring.*) remove_flow_edges graph then_end_id [then_id]; remove_flow_edges graph else_id [then_id]; |