- match jkind, dir with
- | NIL, _ -> _nop
- | NODE, DIR_LEFT -> FIRST_CHILD s
- | STAR, DIR_LEFT -> FIRST_ELEMENT s
- | NODE, DIR_RIGHT -> NEXT_SIBLING s
- | STAR, DIR_RIGHT -> NEXT_ELEMENT s
- | JUMP_ONE t, _ ->
- let l_one, l_many, tagged_one, select_one, any, any_notext =
- if dir = DIR_LEFT then
- child, desc, _tagged_child, _select_child,_first_child, _first_element
- else
- sib, fol, _tagged_following_sibling, _select_following_sibling,
- _next_sibling, _next_element
- in
- let labels = Ptset.Int.inter l_one t in
- let c = Ptset.Int.cardinal labels in
- if c == 0 then _nop
- else if Ptset.Int.for_all (fun lab -> not (Ptset.Int.mem lab l_many)) labels
- then translate_jump tree tag (JUMP_MANY(labels)) dir s
- else if c == 1 then tagged_one s (Ptset.Int.choose labels)
- else if c > 5 then if has_text labels then any s else any_notext s
- else select_one s labels
-
- | JUMP_MANY t, _ ->
- let l_many, tagged_many, select_many, any, any_notext =
- if dir == DIR_LEFT then
- desc, _tagged_descendant, _select_descendant,_first_child, _first_element
- else
- fol, _tagged_following, _select_following, _next_sibling, _next_element
- in
- let labels = Ptset.Int.inter l_many t in
- let c = Ptset.Int.cardinal labels in
- if c == 0 then _nop
- else if c == 1 then tagged_many s (Ptset.Int.choose labels)
- else if c > 5 then if has_text labels then any s else any_notext s
- else select_many s labels
-
- | CAPTURE_MANY (t), DIR_LEFT ->
- if Ptset.Int.is_singleton t then TAGGED_SUBTREE(s, Ptset.Int.choose t)
- else if t == Tree.element_tags tree then ELEMENT_SUBTREE s
- else assert false
- | _ -> assert false
+ let not_elements =
+ Ptset.Int.add Tag.pcdata
+ (Ptset.Int.add Tag.attribute
+ (Ptset.Int.add Tag.attribute_data
+ (Tree.attribute_tags tree)))
+ in
+ match jkind, dir with
+ | NIL, _ -> _nop
+ | NODE, DIR_LEFT -> FIRST_CHILD s
+ | STAR, DIR_LEFT -> FIRST_ELEMENT s
+ | NODE, DIR_RIGHT -> NEXT_SIBLING s
+ | STAR, DIR_RIGHT -> NEXT_ELEMENT s
+ | JUMP_ONE t, _ ->
+ let l_one, l_many, tagged_one, select_one, any, any_notext =
+ if dir = DIR_LEFT then
+ child, desc, _tagged_child, _select_child,_first_child, _first_element
+ else
+ sib, fol, _tagged_following_sibling, _select_following_sibling,
+ _next_sibling, _next_element
+ in
+ let labels = Ptset.Int.inter l_one t in
+ let c = Ptset.Int.cardinal labels in
+ if c == 0 then _nop
+ else if Ptset.Int.for_all (fun lab -> not (Ptset.Int.mem lab l_many)) labels then
+ translate_jump tree tag (JUMP_MANY(labels)) dir s
+ else if c == 1 then tagged_one s (Ptset.Int.choose labels)
+ else if c > 5 then if has_text labels then any s else any_notext s
+ else select_one s labels
+
+ | JUMP_MANY t, _ ->
+ let l_many, tagged_many, select_many, any, any_notext =
+ if dir == DIR_LEFT then
+ desc, _tagged_descendant, _select_descendant,_first_child, _first_element
+ else
+ fol, _tagged_following, _select_following, _next_sibling, _next_element
+ in
+ let labels = Ptset.Int.inter l_many t in
+ let c = Ptset.Int.cardinal labels in
+ if c == 0 then _nop
+ else
+ let not_t = Ptset.Int.diff l_many labels in
+ let () =
+ LOG(__ "level2-jit" 3 "Would jump for tag %s to labels %a, not relevant tags: %a"
+ (Tag.to_string tag)
+ TagSet.print (TagSet.inj_positive labels)
+ TagSet.print (TagSet.inj_positive not_t))
+ in
+ if Ptset.Int.subset not_t not_elements then
+ if has_text labels then any s else any_notext s
+ else if c == 1 then tagged_many s (Ptset.Int.choose labels)
+ else
+ if c >= 5 then
+ if has_text labels then any s else any_notext s
+ else select_many s labels
+
+ | CAPTURE_MANY (t), DIR_LEFT ->
+ if Ptset.Int.is_singleton t then TAGGED_SUBTREE(s, Ptset.Int.choose t)
+ else if t == Tree.element_tags tree then ELEMENT_SUBTREE s
+ else assert false
+ | _ -> assert false