Skip to content

Commit

Permalink
[inferpython][end of 3.10 upgrade] adding ROT_N opcode
Browse files Browse the repository at this point in the history
Summary: this is also a good excuse to factor a bit other opcodes

Reviewed By: skcho

Differential Revision:
D65051170

Privacy Context Container: L1208441

fbshipit-source-id: bf7d9085e66f0225accf437041eab57f010e2da1
  • Loading branch information
davidpichardie authored and facebook-github-bot committed Oct 29, 2024
1 parent 1490782 commit 76e1f26
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 20 deletions.
39 changes: 21 additions & 18 deletions infer/src/python/PyIR.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,20 @@ module State = struct
(exps, st)


let rot_n st n =
let {loc; stack} = st in
if n <= 0 then L.die InternalError "rot_n need a positive argument"
else if List.length stack < n then
let msg = F.asprintf "rot_n with n = %d is impossible" n in
Error (L.InternalError, loc, Error.EmptyStack msg)
else
let top_n, rest = List.split_n stack n in
let top = List.hd_exn top_n in
let top_1_n = List.tl_exn top_n in
let stack = top_1_n @ [top] @ rest in
Ok {st with stack}


(* TODO: use the [exn_handlers] info to mark statement that can possibly raise * something *)
let push_stmt ({stmts; loc} as st) stmt = {st with stmts= (loc, stmt) :: stmts}

Expand Down Expand Up @@ -1899,28 +1913,16 @@ let parse_bytecode st ({FFI.Code.co_consts; co_names; co_varnames} as code)
| "POP_BLOCK" ->
Ok (st, None)
| "ROT_TWO" ->
let* tos0, st = State.pop st in
let* tos1, st = State.pop st in
let st = State.push_symbol st tos0 in
let st = State.push_symbol st tos1 in
let* st = State.rot_n st 2 in
Ok (st, None)
| "ROT_THREE" ->
let* tos0, st = State.pop st in
let* tos1, st = State.pop st in
let* tos2, st = State.pop st in
let st = State.push_symbol st tos0 in
let st = State.push_symbol st tos2 in
let st = State.push_symbol st tos1 in
let* st = State.rot_n st 3 in
Ok (st, None)
| "ROT_FOUR" ->
let* tos0, st = State.pop st in
let* tos1, st = State.pop st in
let* tos2, st = State.pop st in
let* tos3, st = State.pop st in
let st = State.push_symbol st tos0 in
let st = State.push_symbol st tos3 in
let st = State.push_symbol st tos2 in
let st = State.push_symbol st tos1 in
let* st = State.rot_n st 4 in
Ok (st, None)
| "ROT_N" ->
let* st = State.rot_n st arg in
Ok (st, None)
| "SETUP_WITH" ->
let* context_manager, st = State.pop_and_cast st in
Expand Down Expand Up @@ -2236,6 +2238,7 @@ let get_successors_offset {FFI.Instruction.opname; arg} =
| "ROT_TWO"
| "ROT_THREE"
| "ROT_FOUR"
| "ROT_N"
| "SETUP_WITH"
| "SETUP_FINALLY"
| "POP_FINALLY"
Expand Down
65 changes: 63 additions & 2 deletions infer/src/python/unit/PyIRTestMatch.ml
Original file line number Diff line number Diff line change
Expand Up @@ -721,5 +721,66 @@ def main():
|}
in
PyIR.test source ;
[%expect {|
IR error: Unsupported opcode: ROT_N |}]
[%expect
{|
module dummy:

function toplevel():
b0:
n0 <- $MakeFunction["main", "dummy.main", None, None, None, None]
TOPLEVEL[main] <- n0
return None


function dummy.main(a, b, c):
b0:
n0 <- GLOBAL[o]
if $MatchSequence(n0) then jmp b1 else jmp b9(n0)

b1:
n1 <- $Compare.eq($GetLen(n0), 1, None)
if n1 then jmp b2 else jmp b9(n0)

b2:
n2 <- GLOBAL[ast]
n3 <- n2.Cons1
n4 <- $MatchClass(n0[0], n3, 2, $BuildTuple())
if $BoolOfMatchClass(n4) then jmp b3 else jmp b9($AttributesOfMatchClass(n4))

b3:
n5 <- $AttributesOfMatchClass(n4)[1]
n6 <- GLOBAL[ast]
n7 <- n6.Const2
n8 <- $MatchClass(n5, n7, 1, $BuildTuple())
if $BoolOfMatchClass(n8) then jmp b4 else jmp b8

b4:
n9 <- $AttributesOfMatchClass(n8)[0]
if $MatchSequence(n9) then jmp b5 else jmp b7

b5:
n10 <- $Compare.eq($GetLen(n9), 3, None)
if n10 then jmp b6 else jmp b7

b6:
n13 <- $AttributesOfMatchClass(n8)
n14 <- $AttributesOfMatchClass(n4)
LOCAL[a] <- n9[0]
LOCAL[b] <- n9[1]
LOCAL[c] <- n9[2]
n15 <- GLOBAL[action]
n16 <- LOCAL[a]
n17 <- LOCAL[b]
n18 <- LOCAL[c]
n19 <- $Call(n15, n16, n17, n18, None)
return None

b7:
jmp b8

b8:
n11 <- $AttributesOfMatchClass(n8)
jmp b9($AttributesOfMatchClass(n4))

b9(n12):
return None |}]

0 comments on commit 76e1f26

Please sign in to comment.