Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dd13e4f

Browse files
committed
Replace the run-time 'future-bytecode-stream-inspection' hack to find out
how 'import' was called with a compiletime mechanism: create either a tuple of the import arguments, or None (in the case of a normal import), add it to the code-block constants, and load it onto the stack before calling IMPORT_NAME.
1 parent e868211 commit dd13e4f

3 files changed

Lines changed: 19 additions & 59 deletions

File tree

Python/ceval.c

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ static int import_all_from(PyObject *, PyObject *);
7171
static PyObject *build_class(PyObject *, PyObject *, PyObject *);
7272
static int exec_statement(PyFrameObject *,
7373
PyObject *, PyObject *, PyObject *);
74-
static PyObject *find_from_args(PyFrameObject *, int);
7574
static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
7675
static void reset_exc_info(PyThreadState *);
7776

@@ -1627,11 +1626,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
16271626
"__import__ not found");
16281627
break;
16291628
}
1630-
u = find_from_args(f, INSTR_OFFSET());
1631-
if (u == NULL) {
1632-
x = u;
1633-
break;
1634-
}
1629+
u = POP();
16351630
w = Py_BuildValue("(OOOO)",
16361631
w,
16371632
f->f_globals,
@@ -3068,55 +3063,6 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
30683063
return 0;
30693064
}
30703065

3071-
/* Hack for ni.py */
3072-
static PyObject *
3073-
find_from_args(PyFrameObject *f, int nexti)
3074-
{
3075-
int opcode;
3076-
int oparg;
3077-
PyObject *list, *name;
3078-
unsigned char *next_instr;
3079-
3080-
_PyCode_GETCODEPTR(f->f_code, &next_instr);
3081-
next_instr += nexti;
3082-
3083-
opcode = (*next_instr++);
3084-
if (opcode != IMPORT_FROM && opcode != IMPORT_STAR) {
3085-
Py_INCREF(Py_None);
3086-
return Py_None;
3087-
}
3088-
3089-
list = PyList_New(0);
3090-
if (list == NULL)
3091-
return NULL;
3092-
3093-
if (opcode == IMPORT_STAR) {
3094-
name = PyString_FromString("*");
3095-
if (!name)
3096-
Py_DECREF(list);
3097-
else {
3098-
if (PyList_Append(list, name) < 0) {
3099-
Py_DECREF(list);
3100-
}
3101-
Py_DECREF(name);
3102-
}
3103-
} else {
3104-
do {
3105-
oparg = (next_instr[1]<<8) + next_instr[0];
3106-
/* Jump over our own argument, the next instruction
3107-
(which is a STORE), and its argument.*/
3108-
next_instr += 5;
3109-
name = Getnamev(f, oparg);
3110-
if (PyList_Append(list, name) < 0) {
3111-
Py_DECREF(list);
3112-
break;
3113-
}
3114-
opcode = (*next_instr++);
3115-
} while (opcode == IMPORT_FROM);
3116-
}
3117-
return list;
3118-
}
3119-
31203066

31213067
#ifdef DYNAMIC_EXECUTION_PROFILE
31223068

Python/compile.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,14 +2329,27 @@ static void
23292329
com_import_stmt(struct compiling *c, node *n)
23302330
{
23312331
int i;
2332+
PyObject *tup;
23322333
REQ(n, import_stmt);
23332334
/* 'import' dotted_name (',' dotted_name)* |
23342335
'from' dotted_name 'import' ('*' | NAME (',' NAME)*) */
23352336
if (STR(CHILD(n, 0))[0] == 'f') {
23362337
/* 'from' dotted_name 'import' ... */
23372338
REQ(CHILD(n, 1), dotted_name);
2338-
com_addopname(c, IMPORT_NAME, CHILD(n, 1));
2339+
2340+
if (TYPE(CHILD(n, 3)) == STAR) {
2341+
tup = Py_BuildValue("(s)", "*");
2342+
} else {
2343+
tup = PyTuple_New((NCH(n) - 2)/2);
2344+
for (i = 3; i < NCH(n); i += 2) {
2345+
PyTuple_SET_ITEM(tup, (i-3)/2,
2346+
PyString_FromString(STR(
2347+
CHILD(CHILD(n, i), 0))));
2348+
}
2349+
}
2350+
com_addoparg(c, LOAD_CONST, com_addconst(c, tup));
23392351
com_push(c, 1);
2352+
com_addopname(c, IMPORT_NAME, CHILD(n, 1));
23402353
if (TYPE(CHILD(n, 3)) == STAR)
23412354
com_addbyte(c, IMPORT_STAR);
23422355
else {
@@ -2351,8 +2364,9 @@ com_import_stmt(struct compiling *c, node *n)
23512364
for (i = 1; i < NCH(n); i += 2) {
23522365
node *subn = CHILD(n, i);
23532366
REQ(subn, dotted_as_name);
2354-
com_addopname(c, IMPORT_NAME, CHILD(subn, 0));
2367+
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
23552368
com_push(c, 1);
2369+
com_addopname(c, IMPORT_NAME, CHILD(subn, 0));
23562370
if (NCH(subn) > 1) {
23572371
int j;
23582372
if (strcmp(STR(CHILD(subn, 1)), "as") != 0) {

Python/import.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
6666
/* XXX Perhaps the magic number should be frozen and a version field
6767
added to the .pyc file header? */
6868
/* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */
69-
#define MAGIC (50822 | ((long)'\r'<<16) | ((long)'\n'<<24))
69+
#define MAGIC (50823 | ((long)'\r'<<16) | ((long)'\n'<<24))
7070

7171
/* Magic word as global; note that _PyImport_Init() can change the
7272
value of this global to accommodate for alterations of how the
@@ -1401,7 +1401,7 @@ PyImport_ImportModule(char *name)
14011401
{
14021402
static PyObject *fromlist = NULL;
14031403
if (fromlist == NULL && strchr(name, '.') != NULL) {
1404-
fromlist = Py_BuildValue("[s]", "*");
1404+
fromlist = Py_BuildValue("(s)", "*");
14051405
if (fromlist == NULL)
14061406
return NULL;
14071407
}

0 commit comments

Comments
 (0)