Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
015bce64
Commit
015bce64
authored
Jan 16, 2017
by
INADA Naoki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #26110: Add document for LOAD_METHOD and CALL_METHOD opcode.
Changed stack layout bit for "easy to explain."
parent
510df6f2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
40 deletions
+61
-40
Doc/library/dis.rst
Doc/library/dis.rst
+22
-0
Doc/whatsnew/3.7.rst
Doc/whatsnew/3.7.rst
+7
-0
Python/ceval.c
Python/ceval.c
+32
-40
No files found.
Doc/library/dis.rst
View file @
015bce64
...
...
@@ -957,6 +957,28 @@ All of the following opcodes use their arguments.
value.
.. opcode:: LOAD_METHOD (namei)
Loads a method named ``co_names[namei]`` from TOS object. TOS is popped and
method and TOS are pushed when interpreter can call unbound method directly.
TOS will be uesd as the first argument (``self``) by :opcode:`CALL_METHOD`.
Otherwise, ``NULL`` and method is pushed (method is bound method or
something else).
.. versionadded:: 3.7
.. opcode:: CALL_METHOD (argc)
Calls a method. *argc* is number of positional arguments.
Keyword arguments are not supported. This opcode is designed to be used
with :opcode:`LOAD_METHOD`. Positional arguments are on top of the stack.
Below them, two items described in :opcode:`LOAD_METHOD` on the stack.
All of them are popped and return value is pushed.
.. versionadded:: 3.7
.. opcode:: MAKE_FUNCTION (argc)
Pushes a new function object on the stack. From bottom to top, the consumed
...
...
Doc/whatsnew/3.7.rst
View file @
015bce64
...
...
@@ -170,3 +170,10 @@ Changes in the Python API
Assigning to them was deprecated in Python 3.5.
Use the :meth:`~http.cookies.Morsel.set` method for setting them.
(Contributed by Serhiy Storchaka in :issue:`29192`.)
CPython bytecode changes
------------------------
* Added two new opcodes: :opcode:`LOAD_METHOD`` and :opcode:`CALL_METHOD`.
(Contributed by Yury Selivanov and INADA Naoki in :issue:`26110`.)
Python/ceval.c
View file @
015bce64
...
...
@@ -3236,81 +3236,73 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
int
meth_found
=
_PyObject_GetMethod
(
obj
,
name
,
&
meth
);
SET_TOP
(
meth
);
/* Replace `obj` on top; OK if NULL. */
if
(
meth
==
NULL
)
{
/* Most likely attribute wasn't found. */
Py_DECREF
(
obj
);
goto
error
;
}
if
(
meth_found
)
{
/*
The method object is now on top of the stack
.
Push `obj` back to the stack, so that the stack
layout would be:
method | obj | arg1 | ... | argN
*/
PUSH
(
obj
);
/*
We can bypass temporary bound method object
.
meth is unbound method and obj is self.
meth | self | arg1 | ... | argN
*/
SET_TOP
(
meth
);
PUSH
(
obj
);
// self
}
else
{
/*
Not a method (but a regular attr, or something
was returned by a descriptor protocol). Push
NULL to the top of the stack
, to signal
/*
meth is not an unbound method (but a regular attr, or
something was returned by a descriptor protocol). Set
the second element of the stack to NULL
, to signal
CALL_METHOD that it's not a method call.
NULL | meth | arg1 | ... | argN
*/
SET_TOP
(
NULL
);
Py_DECREF
(
obj
);
PUSH
(
NULL
);
PUSH
(
meth
);
}
DISPATCH
();
}
TARGET
(
CALL_METHOD
)
{
/* Designed to work in tamdem with LOAD_METHOD. */
PyObject
**
sp
,
*
res
,
*
obj
;
PyObject
**
sp
,
*
res
,
*
meth
;
sp
=
stack_pointer
;
obj
=
PEEK
(
oparg
+
1
);
if
(
obj
==
NULL
)
{
/* `
obj
` is NULL when LOAD_METHOD thinks that it's not
a method call.
Swap the NULL and callable.
meth
=
PEEK
(
oparg
+
2
);
if
(
meth
==
NULL
)
{
/* `
meth
` is NULL when LOAD_METHOD thinks that it's not
a method call.
Stack layout:
... | callable | NULL | arg1 | ... | argN
^- TOP()
^- (-oparg)
^- (-oparg-1)
^- (-oparg-2)
after the next line it will be:
... | callable | callable | arg1 | ... | argN
^- TOP()
^- (-oparg)
^- (-oparg-1)
^- (-oparg-2)
... | NULL | callable | arg1 | ... | argN
^- TOP()
^- (-oparg)
^- (-oparg-1)
^- (-oparg-2)
Right side `callable` will be POPed by call_funtion.
Left side `callable` will be POPed manually later
(one of "callbale" refs on the stack is borrowed.)
`callable` will be POPed by call_funtion.
NULL will will be POPed manually later.
*/
SET_VALUE
(
oparg
+
1
,
PEEK
(
oparg
+
2
));
res
=
call_function
(
&
sp
,
oparg
,
NULL
);
stack_pointer
=
sp
;
(
void
)
POP
();
/* POP the
left side callable
. */
(
void
)
POP
();
/* POP the
NULL
. */
}
else
{
/* This is a method call. Stack layout:
... | method |
obj
| arg1 | ... | argN
... | method |
self
| arg1 | ... | argN
^- TOP()
^- (-oparg)
^- (-oparg-1)
^- (-oparg-1)
^- (-oparg-2)
`
obj
` and `method` will be POPed by call_function.
`
self
` and `method` will be POPed by call_function.
We'll be passing `oparg + 1` to call_function, to
make it accept the `
obj
` as a first argument.
make it accept the `
self
` as a first argument.
*/
res
=
call_function
(
&
sp
,
oparg
+
1
,
NULL
);
stack_pointer
=
sp
;
...
...
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