Contenu connexe Similaire à CPython 3.2 SourceCodeReading (15) CPython 3.2 SourceCodeReading1. CPython 3.2
eval
Shinya Kawanaka (@mayahjp)
Sunday, March 27, 2011
2. • : (Shinya Kawanaka)
• : mayah (or MAYAH)
• twitter: @mayahjp
• Python: ( )
Sunday, March 27, 2011
4. eval
Γ⊦e→f
Γ ⊦ e1 → v1, ..., Γ ⊦ en → vn
Γ ⊦ f(v1, ..., vn) → v
Γ ⊦ e(e1, ..., en) → v
( )
Sunday, March 27, 2011
5. AST
• AST
eval
• …… Python
Sunday, March 27, 2011
6. Python
→ ALMOST YES
• ceval.c
PyEval_EvalCode co code (AST)
globals locals
PyObject *
PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
{
return PyEval_EvalCodeEx(co,
globals, locals,
(PyObject **)NULL, 0,
(PyObject **)NULL, 0,
(PyObject **)NULL, 0,
NULL, NULL);
}
Sunday, March 27, 2011
7. AST
• AST
• PyEvalCode PyCodeObject
AST
•
• PyObject
• PyObject
•
• PyEvalCode PyObject* globals locals
map
Sunday, March 27, 2011
8. AST / PyCodeObject (code.h)
• PyCodeObject code.h
• opcode
... PyObject
typedef struct {
PyObject_HEAD
... <snip /> ...
PyObject *co_code; /* instruction opcodes */
PyObject *co_consts; /* list (constants used) */
PyObject *co_names; /* list of strings (names used) */
PyObject *co_varnames; /* tuple of strings (local variable names) */
PyObject *co_freevars; /* tuple of strings (free variable names) */
PyObject *co_cellvars; /* tuple of strings (cell variable names) */
... <snip /> ...
} PyCodeObject;
Sunday, March 27, 2011
9. opcode (opcode.h)
• opcode.h opcode
• define
#define MAKE_CLOSURE 134 /* same as MAKE_FUNCTION */
#define LOAD_CLOSURE 135 /* Load free variable from closure */
#define LOAD_DEREF 136 /* Load and dereference from closure cell */
#define STORE_DEREF 137 /* Store into cell */
#define DELETE_DEREF 138 /* Delete closure cell */
Sunday, March 27, 2011
10. opcode
grep
•
• →
• ceval.c eval switch
case
• AST
Sunday, March 27, 2011
11. AST
• PyCodeObject
• co_code opcode
• co_consts AST
• AST
Sunday, March 27, 2011
12. PyObject (object.h)
• GC
• ob_type PyObject
typedef struct _object {
... <snip /> ...
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
typedef struct {
PyObject ob_base;
Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;
Sunday, March 27, 2011
13. _typeobject (object.h)
•
•
typedef struct _typeobject {
PyObject_VAR_HEAD
... <snip /> ...
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
void *tp_reserved; /* formerly known as tp_compare */
reprfunc tp_repr;
Sunday, March 27, 2011
14. •
• _typeobject (PyTypeObject) tp_dict
• PyObject
• primitive
primitive PyObject
• int
Sunday, March 27, 2011
16. PyLongObject (contd.)
• _longobject
•
• digit ( ) uint32
• 64bit
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
Sunday, March 27, 2011
17. • PyObject
• PyObject
•
• primitive
primitive PyObject
• PyLongObject
Sunday, March 27, 2011
18. ...
• map
• PyObject dict
• eval
• eval
Sunday, March 27, 2011
19. • eval
•
Sunday, March 27, 2011
20. PyEval_EvalCodeEx (ceval.c)
•
• +α (PyFrameObject) (PyFrame_New())
•
• PyFrameObject PyEval_EvalFrameEx
• PyEval_EvalFrameEx AST eval
Sunday, March 27, 2011
21. PyFrameObject (frameobject.h)
•
typedef struct _frame {
PyObject_VAR_HEAD
struct _frame *f_back; /* previous frame, or NULL */
PyCodeObject *f_code; /* code segment */
PyObject *f_builtins; /* builtin symbol table (PyDictObject) */
PyObject *f_globals; /* global symbol table (PyDictObject) */
PyObject *f_locals; /* local symbol table (any mapping) */
PyObject **f_valuestack; /* points after the last local */
....
}
Sunday, March 27, 2011
23. • ( )
• local kw (keyword)
• SETLOCAL OK
for (i = 0; i < n; i++) {
x = args[i];
Py_INCREF(x);
SETLOCAL(i, x);
}
Sunday, March 27, 2011
25. PyEval_EvalCode
• pythonrun.c run_mod()
• AST eval
static PyObject * run_mod(mod_ty mod, const char *filename, PyObject
*globals, PyObject *locals, PyCompilerFlags *flags, PyArena *arena)
{
PyCodeObject *co;
PyObject *v;
co = PyAST_Compile(mod, filename, flags, arena);
if (co == NULL) return NULL;
v = PyEval_EvalCode((PyObject*)co, globals, locals);
Py_DECREF(co);
return v;
}
Sunday, March 27, 2011
27. PyEval_EvalFrameEx (ceval.c)
•
•
register int opcode; /* Current opcode */
register int oparg; /* Current opcode argument, if any */
register enum why_code why; /* Reason for block stack unwind */
register int err; /* Error status -- nonzero if error */
register PyObject *x; /* Result object -- NULL if error */
register PyObject *v; /* Temporary objects popped off stack */
register PyObject *w;
register PyObject *u;
register PyObject *t;
Sunday, March 27, 2011
29. PyEval_EvalFrameEx (contd.)
• NOP (No operation)
TARGET(NOP)
FAST_DISPATCH();
•
#define TARGET(op)
case op:
#define DISPATCH() continue
#define FAST_DISPATCH() goto fast_next_opcode
Sunday, March 27, 2011
30. PyEval_EvalFrameEx (contd.)
• NOP LOAD_CONST ( )
x = GETITEM(consts, oparg);
Py_INCREF(x);
PUSH(x);
FAST_DISPATCH();
• PUSH(x) stack machine
#define BASIC_PUSH(v) (*stack_pointer++ = (v))
#define PUSH(v) BASIC_PUSH(v)
Sunday, March 27, 2011
31. stack machine
• stack machine (BINARY_ADD) 2
operands POP → POP → PUSH
•→
TARGET(BINARY_ADD) // only main
w = POP();
v = TOP();
x = PyNumber_Add(v, w);
Py_DECREF(v);
Py_DECREF(w);
SET_TOP(x);
if (x != NULL) DISPATCH();
break;
Sunday, March 27, 2011
32. • stack machine
• if
• if compare & branch
•
• python AST compile
Sunday, March 27, 2011
33. JUMP_IF_TRUE [FALSE]
(_OR_POP)
• stack machine jump
• JUMP_IF_TRUE [FALSE] (_OR_POP)
TARGET(POP_JUMP_IF_TRUE)
w = POP();
if (w == Py_False) {
Py_DECREF(w);
FAST_DISPATCH();
}
if (w == Py_True) {
Py_DECREF(w);
JUMPTO(oparg); // this will set the next instruction!
FAST_DISPATCH();
Sunday, March 27, 2011
34. JUMPTO
• first_instr code
• offset
#define JUMPTO(x) (next_instr = first_instr + (x))
• first_instr
first_instr = (unsigned char*) PyBytes_AS_STRING(co->co_code);
• co_code
Sunday, March 27, 2011
35. CALL_FUNCTION
• stack pointer call_function
TARGET(CALL_FUNCTION) {
PyObject **sp;
PCALL(PCALL_ALL); // for profiling
sp = stack_pointer;
x = call_function(&sp, oparg);
stack_pointer = sp;
PUSH(x);
if (x != NULL) DISPATCH();
break;
}
Sunday, March 27, 2011
36. call_function
• oparg
• 16bit
(
static PyObject *
call_function(PyObject ***pp_stack, int oparg)
{
int na = oparg & 0xff;
int nk = (oparg>>8) & 0xff;
int n = na + 2 * nk;
PyObject **pfunc = (*pp_stack) - n - 1;
PyObject *func = *pfunc;
PyObject *x, *w;
Sunday, March 27, 2011
37. call_function (contd.)
•
• CPyFunction
PyObject *callargs;
callargs = load_args(pp_stack, na);
READ_TIMESTAMP(*pintr0);
C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
READ_TIMESTAMP(*pintr1);
Py_XDECREF(callargs);
Sunday, March 27, 2011
38. TIME UP
•
Sunday, March 27, 2011