Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
7bdf2826
Unverified
Kaydet (Commit)
7bdf2826
authored
Eyl 18, 2018
tarafından
Serhiy Storchaka
Kaydeden (comit)
GitHub
Eyl 18, 2018
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-32455: Add jump parameter to dis.stack_effect(). (GH-6610)
Add C API function PyCompile_OpcodeStackEffectWithJump().
üst
b042cf10
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
99 additions
and
26 deletions
+99
-26
dis.rst
Doc/library/dis.rst
+10
-1
compile.h
Include/compile.h
+1
-0
test__opcode.py
Lib/test/test__opcode.py
+47
-14
2018-07-08-12-06-18.bpo-32455.KVHlkz.rst
...EWS.d/next/C API/2018-07-08-12-06-18.bpo-32455.KVHlkz.rst
+1
-0
2018-04-26-13-31-10.bpo-32455.KPWg3K.rst
...S.d/next/Library/2018-04-26-13-31-10.bpo-32455.KPWg3K.rst
+1
-0
_opcode.c
Modules/_opcode.c
+21
-3
_opcode.c.h
Modules/clinic/_opcode.c.h
+12
-8
compile.c
Python/compile.c
+6
-0
No files found.
Doc/library/dis.rst
Dosyayı görüntüle @
7bdf2826
...
...
@@ -248,12 +248,21 @@ operation is being performed, so the intermediate analysis object isn't useful:
return a list of these offsets.
.. function:: stack_effect(opcode,
[oparg]
)
.. function:: stack_effect(opcode,
oparg=None, *, jump=None
)
Compute the stack effect of *opcode* with argument *oparg*.
If the code has a jump target and *jump* is ``True``, :func:`~stack_effect`
will return the stack effect of jumping. If *jump* is ``False``,
it will return the stack effect of not jumping. And if *jump* is
``None`` (default), it will return the maximal stack effect of both cases.
.. versionadded:: 3.4
.. versionchanged:: 3.8
Added *jump* parameter.
.. _bytecodes:
Python Bytecode Instructions
...
...
Include/compile.h
Dosyayı görüntüle @
7bdf2826
...
...
@@ -75,6 +75,7 @@ PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
#define PY_INVALID_STACK_EFFECT INT_MAX
PyAPI_FUNC
(
int
)
PyCompile_OpcodeStackEffect
(
int
opcode
,
int
oparg
);
PyAPI_FUNC
(
int
)
PyCompile_OpcodeStackEffectWithJump
(
int
opcode
,
int
oparg
,
int
jump
);
PyAPI_FUNC
(
int
)
_PyAST_Optimize
(
struct
_mod
*
,
PyArena
*
arena
,
int
optimize
);
...
...
Lib/test/test__opcode.py
Dosyayı görüntüle @
7bdf2826
...
...
@@ -3,32 +3,65 @@ from test.support import import_module
import
unittest
_opcode
=
import_module
(
"_opcode"
)
from
_opcode
import
stack_effect
class
OpcodeTests
(
unittest
.
TestCase
):
def
test_stack_effect
(
self
):
self
.
assertEqual
(
_opcode
.
stack_effect
(
dis
.
opmap
[
'POP_TOP'
]),
-
1
)
self
.
assertEqual
(
_opcode
.
stack_effect
(
dis
.
opmap
[
'DUP_TOP_TWO'
]),
2
)
self
.
assertEqual
(
_opcode
.
stack_effect
(
dis
.
opmap
[
'BUILD_SLICE'
],
0
),
-
1
)
self
.
assertEqual
(
_opcode
.
stack_effect
(
dis
.
opmap
[
'BUILD_SLICE'
],
1
),
-
1
)
self
.
assertEqual
(
_opcode
.
stack_effect
(
dis
.
opmap
[
'BUILD_SLICE'
],
3
),
-
2
)
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
30000
)
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
dis
.
opmap
[
'BUILD_SLICE'
])
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
dis
.
opmap
[
'POP_TOP'
],
0
)
self
.
assertEqual
(
stack_effect
(
dis
.
opmap
[
'POP_TOP'
]),
-
1
)
self
.
assertEqual
(
stack_effect
(
dis
.
opmap
[
'DUP_TOP_TWO'
]),
2
)
self
.
assertEqual
(
stack_effect
(
dis
.
opmap
[
'BUILD_SLICE'
],
0
),
-
1
)
self
.
assertEqual
(
stack_effect
(
dis
.
opmap
[
'BUILD_SLICE'
],
1
),
-
1
)
self
.
assertEqual
(
stack_effect
(
dis
.
opmap
[
'BUILD_SLICE'
],
3
),
-
2
)
self
.
assertRaises
(
ValueError
,
stack_effect
,
30000
)
self
.
assertRaises
(
ValueError
,
stack_effect
,
dis
.
opmap
[
'BUILD_SLICE'
])
self
.
assertRaises
(
ValueError
,
stack_effect
,
dis
.
opmap
[
'POP_TOP'
],
0
)
# All defined opcodes
for
name
,
code
in
dis
.
opmap
.
items
():
with
self
.
subTest
(
opname
=
name
):
if
code
<
dis
.
HAVE_ARGUMENT
:
_opcode
.
stack_effect
(
code
)
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
code
,
0
)
stack_effect
(
code
)
self
.
assertRaises
(
ValueError
,
stack_effect
,
code
,
0
)
else
:
_opcode
.
stack_effect
(
code
,
0
)
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
code
)
stack_effect
(
code
,
0
)
self
.
assertRaises
(
ValueError
,
stack_effect
,
code
)
# All not defined opcodes
for
code
in
set
(
range
(
256
))
-
set
(
dis
.
opmap
.
values
()):
with
self
.
subTest
(
opcode
=
code
):
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
code
)
self
.
assertRaises
(
ValueError
,
_opcode
.
stack_effect
,
code
,
0
)
self
.
assertRaises
(
ValueError
,
stack_effect
,
code
)
self
.
assertRaises
(
ValueError
,
stack_effect
,
code
,
0
)
def
test_stack_effect_jump
(
self
):
JUMP_IF_TRUE_OR_POP
=
dis
.
opmap
[
'JUMP_IF_TRUE_OR_POP'
]
self
.
assertEqual
(
stack_effect
(
JUMP_IF_TRUE_OR_POP
,
0
),
0
)
self
.
assertEqual
(
stack_effect
(
JUMP_IF_TRUE_OR_POP
,
0
,
jump
=
True
),
0
)
self
.
assertEqual
(
stack_effect
(
JUMP_IF_TRUE_OR_POP
,
0
,
jump
=
False
),
-
1
)
FOR_ITER
=
dis
.
opmap
[
'FOR_ITER'
]
self
.
assertEqual
(
stack_effect
(
FOR_ITER
,
0
),
1
)
self
.
assertEqual
(
stack_effect
(
FOR_ITER
,
0
,
jump
=
True
),
-
1
)
self
.
assertEqual
(
stack_effect
(
FOR_ITER
,
0
,
jump
=
False
),
1
)
JUMP_FORWARD
=
dis
.
opmap
[
'JUMP_FORWARD'
]
self
.
assertEqual
(
stack_effect
(
JUMP_FORWARD
,
0
),
0
)
self
.
assertEqual
(
stack_effect
(
JUMP_FORWARD
,
0
,
jump
=
True
),
0
)
self
.
assertEqual
(
stack_effect
(
JUMP_FORWARD
,
0
,
jump
=
False
),
0
)
# All defined opcodes
has_jump
=
dis
.
hasjabs
+
dis
.
hasjrel
for
name
,
code
in
dis
.
opmap
.
items
():
with
self
.
subTest
(
opname
=
name
):
if
code
<
dis
.
HAVE_ARGUMENT
:
common
=
stack_effect
(
code
)
jump
=
stack_effect
(
code
,
jump
=
True
)
nojump
=
stack_effect
(
code
,
jump
=
False
)
else
:
common
=
stack_effect
(
code
,
0
)
jump
=
stack_effect
(
code
,
0
,
jump
=
True
)
nojump
=
stack_effect
(
code
,
0
,
jump
=
False
)
if
code
in
has_jump
:
self
.
assertEqual
(
common
,
max
(
jump
,
nojump
))
else
:
self
.
assertEqual
(
jump
,
common
)
self
.
assertEqual
(
nojump
,
common
)
if
__name__
==
"__main__"
:
...
...
Misc/NEWS.d/next/C API/2018-07-08-12-06-18.bpo-32455.KVHlkz.rst
0 → 100644
Dosyayı görüntüle @
7bdf2826
Added :c:func:`PyCompile_OpcodeStackEffectWithJump`.
Misc/NEWS.d/next/Library/2018-04-26-13-31-10.bpo-32455.KPWg3K.rst
0 → 100644
Dosyayı görüntüle @
7bdf2826
Added *jump* parameter to :func:`dis.stack_effect`.
Modules/_opcode.c
Dosyayı görüntüle @
7bdf2826
...
...
@@ -15,16 +15,20 @@ _opcode.stack_effect -> int
opcode: int
oparg: object = None
/
*
jump: object = None
Compute the stack effect of the opcode.
[clinic start generated code]*/
static
int
_opcode_stack_effect_impl
(
PyObject
*
module
,
int
opcode
,
PyObject
*
oparg
)
/*[clinic end generated code: output=ad39467fa3ad22ce input=2d0a9ee53c0418f5]*/
_opcode_stack_effect_impl
(
PyObject
*
module
,
int
opcode
,
PyObject
*
oparg
,
PyObject
*
jump
)
/*[clinic end generated code: output=64a18f2ead954dbb input=461c9d4a44851898]*/
{
int
effect
;
int
oparg_int
=
0
;
int
jump_int
;
if
(
HAS_ARG
(
opcode
))
{
if
(
oparg
==
Py_None
)
{
PyErr_SetString
(
PyExc_ValueError
,
...
...
@@ -40,7 +44,21 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg)
"stack_effect: opcode does not permit oparg but oparg was specified"
);
return
-
1
;
}
effect
=
PyCompile_OpcodeStackEffect
(
opcode
,
oparg_int
);
if
(
jump
==
Py_None
)
{
jump_int
=
-
1
;
}
else
if
(
jump
==
Py_True
)
{
jump_int
=
1
;
}
else
if
(
jump
==
Py_False
)
{
jump_int
=
0
;
}
else
{
PyErr_SetString
(
PyExc_ValueError
,
"stack_effect: jump must be False, True or None"
);
return
-
1
;
}
effect
=
PyCompile_OpcodeStackEffectWithJump
(
opcode
,
oparg_int
,
jump_int
);
if
(
effect
==
PY_INVALID_STACK_EFFECT
)
{
PyErr_SetString
(
PyExc_ValueError
,
"invalid opcode or oparg"
);
...
...
Modules/clinic/_opcode.c.h
Dosyayı görüntüle @
7bdf2826
...
...
@@ -3,30 +3,34 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR
(
_opcode_stack_effect__doc__
,
"stack_effect($module, opcode, oparg=None, /)
\n
"
"stack_effect($module, opcode, oparg=None, /
, *, jump=None
)
\n
"
"--
\n
"
"
\n
"
"Compute the stack effect of the opcode."
);
#define _OPCODE_STACK_EFFECT_METHODDEF \
{"stack_effect", (PyCFunction)_opcode_stack_effect, METH_FASTCALL, _opcode_stack_effect__doc__},
{"stack_effect", (PyCFunction)_opcode_stack_effect, METH_FASTCALL
|METH_KEYWORDS
, _opcode_stack_effect__doc__},
static
int
_opcode_stack_effect_impl
(
PyObject
*
module
,
int
opcode
,
PyObject
*
oparg
);
_opcode_stack_effect_impl
(
PyObject
*
module
,
int
opcode
,
PyObject
*
oparg
,
PyObject
*
jump
);
static
PyObject
*
_opcode_stack_effect
(
PyObject
*
module
,
PyObject
*
const
*
args
,
Py_ssize_t
nargs
)
_opcode_stack_effect
(
PyObject
*
module
,
PyObject
*
const
*
args
,
Py_ssize_t
nargs
,
PyObject
*
kwnames
)
{
PyObject
*
return_value
=
NULL
;
static
const
char
*
const
_keywords
[]
=
{
""
,
""
,
"jump"
,
NULL
};
static
_PyArg_Parser
_parser
=
{
"i|O$O:stack_effect"
,
_keywords
,
0
};
int
opcode
;
PyObject
*
oparg
=
Py_None
;
PyObject
*
jump
=
Py_None
;
int
_return_value
;
if
(
!
_PyArg_ParseStack
(
args
,
nargs
,
"i|O:stack_effect"
,
&
opcode
,
&
oparg
))
{
if
(
!
_PyArg_ParseStack
AndKeywords
(
args
,
nargs
,
kwnames
,
&
_parser
,
&
opcode
,
&
oparg
,
&
jump
))
{
goto
exit
;
}
_return_value
=
_opcode_stack_effect_impl
(
module
,
opcode
,
oparg
);
_return_value
=
_opcode_stack_effect_impl
(
module
,
opcode
,
oparg
,
jump
);
if
((
_return_value
==
-
1
)
&&
PyErr_Occurred
())
{
goto
exit
;
}
...
...
@@ -35,4 +39,4 @@ _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return
return_value
;
}
/*[clinic end generated code: output=
577a91c9aa5559a
9 input=a9049054013a1b77]*/
/*[clinic end generated code: output=
bbf6c4cfc91edc2
9 input=a9049054013a1b77]*/
Python/compile.c
Dosyayı görüntüle @
7bdf2826
...
...
@@ -1116,6 +1116,12 @@ stack_effect(int opcode, int oparg, int jump)
return
PY_INVALID_STACK_EFFECT
;
/* not reachable */
}
int
PyCompile_OpcodeStackEffectWithJump
(
int
opcode
,
int
oparg
,
int
jump
)
{
return
stack_effect
(
opcode
,
oparg
,
jump
);
}
int
PyCompile_OpcodeStackEffect
(
int
opcode
,
int
oparg
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment