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.
...
@@ -957,6 +957,28 @@ All of the following opcodes use their arguments.
value.
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)
.. opcode:: MAKE_FUNCTION (argc)
Pushes a new function object on the stack. From bottom to top, the consumed
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
...
@@ -170,3 +170,10 @@ Changes in the Python API
Assigning to them was deprecated in Python 3.5.
Assigning to them was deprecated in Python 3.5.
Use the :meth:`~http.cookies.Morsel.set` method for setting them.
Use the :meth:`~http.cookies.Morsel.set` method for setting them.
(Contributed by Serhiy Storchaka in :issue:`29192`.)
(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)
...
@@ -3236,81 +3236,73 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
int
meth_found
=
_PyObject_GetMethod
(
obj
,
name
,
&
meth
);
int
meth_found
=
_PyObject_GetMethod
(
obj
,
name
,
&
meth
);
SET_TOP
(
meth
);
/* Replace `obj` on top; OK if NULL. */
if
(
meth
==
NULL
)
{
if
(
meth
==
NULL
)
{
/* Most likely attribute wasn't found. */
/* Most likely attribute wasn't found. */
Py_DECREF
(
obj
);
goto
error
;
goto
error
;
}
}
if
(
meth_found
)
{
if
(
meth_found
)
{
/*
The method object is now on top of the stack
.
/*
We can bypass temporary bound method object
.
Push `obj` back to the stack, so that the stack
meth is unbound method and obj is self.
layout would be:
meth | self | arg1 | ... | argN
method | obj | arg1 | ... | argN
*/
*/
SET_TOP
(
meth
);
PUSH
(
obj
);
PUSH
(
obj
);
// self
}
}
else
{
else
{
/*
Not a method (but a regular attr, or something
/*
meth is not an unbound method (but a regular attr, or
was returned by a descriptor protocol). Push
something was returned by a descriptor protocol). Set
NULL to the top of the stack
, to signal
the second element of the stack to NULL
, to signal
CALL_METHOD that it's not a method call.
CALL_METHOD that it's not a method call.
NULL | meth | arg1 | ... | argN
*/
*/
SET_TOP
(
NULL
);
Py_DECREF
(
obj
);
Py_DECREF
(
obj
);
PUSH
(
NULL
);
PUSH
(
meth
);
}
}
DISPATCH
();
DISPATCH
();
}
}
TARGET
(
CALL_METHOD
)
{
TARGET
(
CALL_METHOD
)
{
/* Designed to work in tamdem with LOAD_METHOD. */
/* Designed to work in tamdem with LOAD_METHOD. */
PyObject
**
sp
,
*
res
,
*
obj
;
PyObject
**
sp
,
*
res
,
*
meth
;
sp
=
stack_pointer
;
sp
=
stack_pointer
;
obj
=
PEEK
(
oparg
+
1
);
meth
=
PEEK
(
oparg
+
2
);
if
(
obj
==
NULL
)
{
if
(
meth
==
NULL
)
{
/* `
obj
` is NULL when LOAD_METHOD thinks that it's not
/* `
meth
` is NULL when LOAD_METHOD thinks that it's not
a method call.
Swap the NULL and callable.
a method call.
Stack layout:
Stack layout:
... | callable | NULL | arg1 | ... | argN
... | NULL | callable | arg1 | ... | argN
^- TOP()
^- TOP()
^- (-oparg)
^- (-oparg)
^- (-oparg-1)
^- (-oparg-1)
^- (-oparg-2)
^- (-oparg-2)
after the next line it will be:
... | callable | callable | arg1 | ... | argN
^- TOP()
^- (-oparg)
^- (-oparg-1)
^- (-oparg-2)
Right side `callable` will be POPed by call_funtion.
`callable` will be POPed by call_funtion.
Left side `callable` will be POPed manually later
NULL will will be POPed manually later.
(one of "callbale" refs on the stack is borrowed.)
*/
*/
SET_VALUE
(
oparg
+
1
,
PEEK
(
oparg
+
2
));
res
=
call_function
(
&
sp
,
oparg
,
NULL
);
res
=
call_function
(
&
sp
,
oparg
,
NULL
);
stack_pointer
=
sp
;
stack_pointer
=
sp
;
(
void
)
POP
();
/* POP the
left side callable
. */
(
void
)
POP
();
/* POP the
NULL
. */
}
}
else
{
else
{
/* This is a method call. Stack layout:
/* This is a method call. Stack layout:
... | method |
obj
| arg1 | ... | argN
... | method |
self
| arg1 | ... | argN
^- TOP()
^- TOP()
^- (-oparg)
^- (-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
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
);
res
=
call_function
(
&
sp
,
oparg
+
1
,
NULL
);
stack_pointer
=
sp
;
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