Clean up trans_alt_tag to use slots, not assume interior words. Also remove record-based destructuring (hard on eyes). Add execution parts to generic-tag-alt.rs and un-XFAIL it.

This commit is contained in:
Graydon Hoare 2010-06-24 11:15:22 -07:00
parent 25eb1fd3c9
commit 0364a801bb
3 changed files with 50 additions and 47 deletions

View file

@ -322,7 +322,6 @@ TEST_XFAILS_X86 := test/run-pass/mlist-cycle.rs \
test/run-pass/generic-fn-infer.rs \ test/run-pass/generic-fn-infer.rs \
test/run-pass/generic-recursive-tag.rs \ test/run-pass/generic-recursive-tag.rs \
test/run-pass/generic-tag.rs \ test/run-pass/generic-tag.rs \
test/run-pass/generic-tag-alt.rs \
test/run-pass/bind-obj-ctor.rs \ test/run-pass/bind-obj-ctor.rs \
test/run-pass/task-comm.rs \ test/run-pass/task-comm.rs \
test/compile-fail/rec-missing-fields.rs \ test/compile-fail/rec-missing-fields.rs \

View file

@ -3737,30 +3737,21 @@ let trans_visitor
drop_slot_in_current_frame (cell_of_block_slot slot_id) slot None drop_slot_in_current_frame (cell_of_block_slot slot_id) slot None
and trans_alt_tag { Ast.alt_tag_lval = lval; Ast.alt_tag_arms = arms } = and trans_alt_tag (at:Ast.stmt_alt_tag) : unit =
let ((lval_cell:Il.cell), { Ast.slot_ty = ty_opt }) = trans_lval lval in
let lval_ty =
match ty_opt with
Some ty -> ty
| None -> bug cx "expected lval type"
in
let trans_arm { node = (pat, block) } : quad_idx = let trans_arm arm : quad_idx =
(* Translates the pattern and returns the addresses of the branch let (pat, block) = arm.node in
* instructions, which are taken if the match fails. *) (* Translates the pattern and returns the addresses of the branch
let rec trans_pat pat cell (ty:Ast.ty) = * instructions, which are taken if the match fails. *)
let rec trans_pat pat src_cell src_slot =
match pat with match pat with
Ast.PAT_lit lit -> Ast.PAT_lit lit ->
let operand = trans_lit lit in trans_compare Il.JNE (trans_lit lit) (Il.Cell src_cell)
emit (Il.cmp (Il.Cell cell) operand);
let next_jump = mark() in
emit (Il.jmp Il.JNE Il.CodeNone);
[ next_jump ]
| Ast.PAT_tag (tag_namei, pats) -> | Ast.PAT_tag (tag_namei, pats) ->
let tag_name = tag_namei.node in let tag_name = tag_namei.node in
let ty_tag = let ty_tag =
match ty with match slot_ty src_slot with
Ast.TY_tag tag_ty -> tag_ty Ast.TY_tag tag_ty -> tag_ty
| Ast.TY_iso ti -> (ti.Ast.iso_group).(ti.Ast.iso_index) | Ast.TY_iso ti -> (ti.Ast.iso_group).(ti.Ast.iso_index)
| _ -> bug cx "expected tag type" | _ -> bug cx "expected tag type"
@ -3769,14 +3760,19 @@ let trans_visitor
let tag_number = arr_idx tag_keys tag_name in let tag_number = arr_idx tag_keys tag_name in
let ty_tup = Hashtbl.find ty_tag tag_name in let ty_tup = Hashtbl.find ty_tag tag_name in
let tag_cell:Il.cell = get_element_ptr cell 0 in (* NB: follow any exterior pointer as we go. *)
let union_cell = get_element_ptr_dyn_in_current_frame cell 1 in let src_cell = deref_slot false src_cell src_slot in
emit (Il.cmp (* NB: follow any exterior pointer as we go. *)
(Il.Cell tag_cell) let tag_cell:Il.cell = get_element_ptr src_cell 0 in
(imm (Int64.of_int tag_number))); let union_cell =
let next_jump = mark() in get_element_ptr_dyn_in_current_frame src_cell 1
emit (Il.jmp Il.JNE Il.CodeNone); in
let next_jumps =
trans_compare Il.JNE
(Il.Cell tag_cell) (imm (Int64.of_int tag_number))
in
let tup_cell:Il.cell = get_variant_ptr union_cell tag_number in let tup_cell:Il.cell = get_variant_ptr union_cell tag_number in
@ -3784,35 +3780,36 @@ let trans_visitor
let elem_cell = let elem_cell =
get_element_ptr_dyn_in_current_frame tup_cell i get_element_ptr_dyn_in_current_frame tup_cell i
in in
let elem_ty = let elem_slot = ty_tup.(i) in
match ty_tup.(i).Ast.slot_ty with trans_pat elem_pat elem_cell elem_slot
Some ty -> ty
| None -> bug cx "expected element type"
in
trans_pat elem_pat elem_cell elem_ty
in in
let elem_jumps = Array.mapi trans_elem_pat pats in let elem_jumps = Array.mapi trans_elem_pat pats in
next_jump::(List.concat (Array.to_list elem_jumps)) next_jumps @ (List.concat (Array.to_list elem_jumps))
| Ast.PAT_slot ({ node = dst_slot; id = dst_id }, _) -> | Ast.PAT_slot (dst, _) ->
let dst_cell = cell_of_block_slot dst_id in let dst_slot = get_slot cx dst.id in
let src_cell = Il.Cell cell in let dst_cell = cell_of_block_slot dst.id in
mov (deref_slot true dst_cell dst_slot) src_cell; trans_copy_slot
[] (* irrefutable *) (get_ty_params_of_current_frame()) true
dst_cell dst_slot
src_cell src_slot
None;
[] (* irrefutable *)
| Ast.PAT_wild -> [] (* irrefutable *) | Ast.PAT_wild -> [] (* irrefutable *)
in in
let next_jumps = trans_pat pat lval_cell lval_ty in let (lval_cell, lval_slot) = trans_lval at.Ast.alt_tag_lval in
trans_block block; let next_jumps = trans_pat pat lval_cell lval_slot in
let last_jump = mark() in trans_block block;
emit (Il.jmp Il.JMP Il.CodeNone); let last_jump = mark() in
List.iter patch next_jumps; emit (Il.jmp Il.JMP Il.CodeNone);
last_jump List.iter patch next_jumps;
last_jump
in in
let last_jumps = Array.map trans_arm arms in let last_jumps = Array.map trans_arm at.Ast.alt_tag_arms in
Array.iter patch last_jumps Array.iter patch last_jumps
and drop_slots_at_curr_stmt _ : unit = and drop_slots_at_curr_stmt _ : unit =
let stmt = Stack.top curr_stmt in let stmt = Stack.top curr_stmt in

View file

@ -1,9 +1,16 @@
type foo[T] = tag(arm(T)); type foo[T] = tag(arm(T));
fn altfoo[T](foo[T] f) { fn altfoo[T](foo[T] f) {
auto hit = false;
alt (f) { alt (f) {
case (arm(x)) {} case (arm(x)) {
log "in arm";
hit = true;
}
} }
check (hit);
} }
fn main() {} fn main() {
altfoo[int](arm[int](10));
}