CPython 3.2 SourceCodeReading

1,888 views
1,760 views

Published on

eval を追う

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,888
On SlideShare
0
From Embeds
0
Number of Embeds
11
Actions
Shares
0
Downloads
24
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

CPython 3.2 SourceCodeReading

  1. 1. CPython 3.2 eval Shinya Kawanaka (@mayahjp)Sunday, March 27, 2011
  2. 2. • : (Shinya Kawanaka) • : mayah (or MAYAH) • twitter: @mayahjp • Python: ( )Sunday, March 27, 2011
  3. 3. • CPython eval •Sunday, March 27, 2011
  4. 4. eval Γ⊦e→f Γ ⊦ e1 → v1, ..., Γ ⊦ en → vn Γ ⊦ f(v1, ..., vn) → v Γ ⊦ e(e1, ..., en) → v ( )Sunday, March 27, 2011
  5. 5. AST • AST eval • …… PythonSunday, March 27, 2011
  6. 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. 7. AST • AST • PyEvalCode PyCodeObject AST • • PyObject • PyObject • • PyEvalCode PyObject* globals locals mapSunday, March 27, 2011
  8. 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. 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. 10. opcode grep • • → • ceval.c eval switch case • ASTSunday, March 27, 2011
  11. 11. AST • PyCodeObject • co_code opcode • co_consts AST • ASTSunday, March 27, 2011
  12. 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. 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. 14. • • _typeobject (PyTypeObject) tp_dict • PyObject • primitive primitive PyObject • intSunday, March 27, 2011
  15. 15. PyLongObject (longobject.h) • Py Object PyIntObject • → grep • PyLongObject • 64bit long ...Sunday, March 27, 2011
  16. 16. PyLongObject (contd.) • _longobject • • digit ( ) uint32 • 64bit struct _longobject { PyObject_VAR_HEAD digit ob_digit[1]; };Sunday, March 27, 2011
  17. 17. • PyObject • PyObject • • primitive primitive PyObject • PyLongObjectSunday, March 27, 2011
  18. 18. ... • map • PyObject dict • eval • evalSunday, March 27, 2011
  19. 19. • eval •Sunday, March 27, 2011
  20. 20. PyEval_EvalCodeEx (ceval.c) • • +α (PyFrameObject) (PyFrame_New()) • • PyFrameObject PyEval_EvalFrameEx • PyEval_EvalFrameEx AST evalSunday, March 27, 2011
  21. 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
  22. 22. PyFrame_New (frameobject.c) • • • • code • • mallocSunday, March 27, 2011
  23. 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
  24. 24. PyEval_EvalCodeEx (contd.) • • PyEval_EvalFrameEx • goto fail • fail __del__ • C stackSunday, March 27, 2011
  25. 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
  26. 26. fast_function (ceval.c) • eval • • eval call_function •Sunday, March 27, 2011
  27. 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
  28. 28. PyEval_EvalFrameEx (contd.) • Main switch on opcode • operation x NULL err 0 why WHY_NOT operationSunday, March 27, 2011
  29. 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_opcodeSunday, March 27, 2011
  30. 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. 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. 32. • stack machine • if • if compare & branch • • python AST compileSunday, March 27, 2011
  33. 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. 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_codeSunday, March 27, 2011
  35. 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. 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. 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. 38. TIME UP •Sunday, March 27, 2011

×