call_object: print message before abort()
This commit is contained in:
parent
b078ce10d4
commit
e59214ed91
299
Python/ceval.c
299
Python/ceval.c
|
@ -1,5 +1,5 @@
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
|
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
|
||||||
Amsterdam, The Netherlands.
|
Amsterdam, The Netherlands.
|
||||||
|
|
||||||
All Rights Reserved
|
All Rights Reserved
|
||||||
|
@ -40,6 +40,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
extern int suppress_print; /* Declared in pythonrun.c, set in pythonmain.c */
|
||||||
|
|
||||||
/* Turn this on if your compiler chokes on the big switch: */
|
/* Turn this on if your compiler chokes on the big switch: */
|
||||||
/* #define CASE_TOO_BIG 1 /**/
|
/* #define CASE_TOO_BIG 1 /**/
|
||||||
|
|
||||||
|
@ -53,9 +55,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define CHECKEXC 1 /* Double-check exception checking */
|
#define CHECKEXC 1 /* Double-check exception checking */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Global option, may be set by main() */
|
|
||||||
int killprint;
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
|
|
||||||
|
@ -92,18 +91,15 @@ static int cmp_member PROTO((object *, object *));
|
||||||
static object *cmp_outcome PROTO((int, object *, object *));
|
static object *cmp_outcome PROTO((int, object *, object *));
|
||||||
static int import_from PROTO((object *, object *, object *));
|
static int import_from PROTO((object *, object *, object *));
|
||||||
static object *build_class PROTO((object *, object *, object *));
|
static object *build_class PROTO((object *, object *, object *));
|
||||||
static void locals_2_fast PROTO((frameobject *, int));
|
|
||||||
static void fast_2_locals PROTO((frameobject *));
|
|
||||||
static int access_statement PROTO((object *, object *, frameobject *));
|
static int access_statement PROTO((object *, object *, frameobject *));
|
||||||
static int exec_statement PROTO((object *, object *, object *));
|
static int exec_statement PROTO((object *, object *, object *));
|
||||||
static void mergelocals PROTO(());
|
|
||||||
|
|
||||||
|
|
||||||
/* Pointer to current frame, used to link new frames to */
|
/* Pointer to current frame, used to link new frames to */
|
||||||
|
|
||||||
static frameobject *current_frame;
|
static frameobject *current_frame;
|
||||||
|
|
||||||
#ifdef USE_THREAD
|
#ifdef WITH_THREAD
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
@ -128,7 +124,7 @@ init_save_thread()
|
||||||
object *
|
object *
|
||||||
save_thread()
|
save_thread()
|
||||||
{
|
{
|
||||||
#ifdef USE_THREAD
|
#ifdef WITH_THREAD
|
||||||
if (interpreter_lock) {
|
if (interpreter_lock) {
|
||||||
object *res;
|
object *res;
|
||||||
res = (object *)current_frame;
|
res = (object *)current_frame;
|
||||||
|
@ -144,7 +140,7 @@ void
|
||||||
restore_thread(x)
|
restore_thread(x)
|
||||||
object *x;
|
object *x;
|
||||||
{
|
{
|
||||||
#ifdef USE_THREAD
|
#ifdef WITH_THREAD
|
||||||
if (interpreter_lock) {
|
if (interpreter_lock) {
|
||||||
int err;
|
int err;
|
||||||
err = errno;
|
err = errno;
|
||||||
|
@ -190,11 +186,11 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
register object *t;
|
register object *t;
|
||||||
register frameobject *f; /* Current frame */
|
register frameobject *f; /* Current frame */
|
||||||
register listobject *fastlocals = NULL;
|
register listobject *fastlocals = NULL;
|
||||||
object *trace = NULL; /* Trace function or NULL */
|
|
||||||
object *retval; /* Return value iff why == WHY_RETURN */
|
object *retval; /* Return value iff why == WHY_RETURN */
|
||||||
char *name; /* Name used by some instructions */
|
char *name; /* Name used by some instructions */
|
||||||
int needmerge = 0; /* Set if need to merge locals back at end */
|
int needmerge = 0; /* Set if need to merge locals back at end */
|
||||||
int defmode = 0; /* Default access mode for new variables */
|
int defmode = 0; /* Default access mode for new variables */
|
||||||
|
int ticker_count = 10; /* Check for intr every Nth instruction */
|
||||||
#ifdef LLTRACE
|
#ifdef LLTRACE
|
||||||
int lltrace;
|
int lltrace;
|
||||||
#endif
|
#endif
|
||||||
|
@ -276,7 +272,7 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
depends on the situation. The global trace function
|
depends on the situation. The global trace function
|
||||||
(sys.trace) is also called whenever an exception
|
(sys.trace) is also called whenever an exception
|
||||||
is detected. */
|
is detected. */
|
||||||
if (call_trace(&sys_trace, &trace, f, "call", arg)) {
|
if (call_trace(&sys_trace, &f->f_trace, f, "call", arg)) {
|
||||||
/* Trace function raised an error */
|
/* Trace function raised an error */
|
||||||
current_frame = f->f_back;
|
current_frame = f->f_back;
|
||||||
DECREF(f);
|
DECREF(f);
|
||||||
|
@ -294,6 +290,10 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x = sysget("check_interval");
|
||||||
|
if (x != NULL && is_intobject(x))
|
||||||
|
ticker_count = getintvalue(x);
|
||||||
|
|
||||||
next_instr = GETUSTRINGVALUE(f->f_code->co_code);
|
next_instr = GETUSTRINGVALUE(f->f_code->co_code);
|
||||||
stack_pointer = f->f_valuestack;
|
stack_pointer = f->f_valuestack;
|
||||||
|
|
||||||
|
@ -312,17 +312,16 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
/* Do periodic things.
|
/* Do periodic things.
|
||||||
Doing this every time through the loop would add
|
Doing this every time through the loop would add
|
||||||
too much overhead (a function call per instruction).
|
too much overhead (a function call per instruction).
|
||||||
So we do it only every tenth instruction. */
|
So we do it only every Nth instruction. */
|
||||||
|
|
||||||
if (--ticker < 0) {
|
if (--ticker < 0) {
|
||||||
ticker = 10;
|
ticker = ticker_count;
|
||||||
if (intrcheck()) {
|
if (sigcheck()) {
|
||||||
err_set(KeyboardInterrupt);
|
|
||||||
why = WHY_EXCEPTION;
|
why = WHY_EXCEPTION;
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_THREAD
|
#ifdef WITH_THREAD
|
||||||
if (interpreter_lock) {
|
if (interpreter_lock) {
|
||||||
/* Give another thread a chance */
|
/* Give another thread a chance */
|
||||||
|
|
||||||
|
@ -642,17 +641,15 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
case PRINT_EXPR:
|
case PRINT_EXPR:
|
||||||
v = POP();
|
v = POP();
|
||||||
/* Print value except if procedure result */
|
/* Print value except if procedure result */
|
||||||
if (v != None) {
|
/* Before printing, also assign to '_' */
|
||||||
|
if (v != None &&
|
||||||
|
(err = setbuiltin("_", v)) == 0 &&
|
||||||
|
!suppress_print) {
|
||||||
flushline();
|
flushline();
|
||||||
x = sysget("stdout");
|
x = sysget("stdout");
|
||||||
softspace(x, 1);
|
softspace(x, 1);
|
||||||
err = writeobject(v, x, 0);
|
err = writeobject(v, x, 0);
|
||||||
flushline();
|
flushline();
|
||||||
if (killprint) {
|
|
||||||
err_setstr(RuntimeError,
|
|
||||||
"printing expression statement");
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DECREF(v);
|
DECREF(v);
|
||||||
break;
|
break;
|
||||||
|
@ -692,7 +689,7 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
v = POP();
|
v = POP();
|
||||||
w = POP();
|
w = POP();
|
||||||
/* A tuple is equivalent to its first element here */
|
/* A tuple is equivalent to its first element here */
|
||||||
while (is_tupleobject(w)) {
|
while (is_tupleobject(w) && gettuplesize(w) > 0) {
|
||||||
u = w;
|
u = w;
|
||||||
w = gettupleitem(u, 0);
|
w = gettupleitem(u, 0);
|
||||||
DECREF(u);
|
DECREF(u);
|
||||||
|
@ -741,6 +738,14 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
PUSH(x);
|
PUSH(x);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SET_FUNC_ARGS:
|
||||||
|
v = POP(); /* The function */
|
||||||
|
w = POP(); /* The argument list */
|
||||||
|
err = setfuncargstuff(v, oparg, w);
|
||||||
|
PUSH(v);
|
||||||
|
DECREF(w);
|
||||||
|
break;
|
||||||
|
|
||||||
case POP_BLOCK:
|
case POP_BLOCK:
|
||||||
{
|
{
|
||||||
block *b = pop_block(f);
|
block *b = pop_block(f);
|
||||||
|
@ -1109,8 +1114,7 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
x = GETCONST(oparg);
|
x = GETCONST(oparg);
|
||||||
if (x == None)
|
if (x == None)
|
||||||
break;
|
break;
|
||||||
if (x == NULL || !is_dictobject(x)) {
|
if (x == NULL || !is_tupleobject(x)) {
|
||||||
fatal("bad RESERVE_FAST");
|
|
||||||
err_setstr(SystemError, "bad RESERVE_FAST");
|
err_setstr(SystemError, "bad RESERVE_FAST");
|
||||||
x = NULL;
|
x = NULL;
|
||||||
break;
|
break;
|
||||||
|
@ -1119,16 +1123,15 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
XDECREF(f->f_localmap);
|
XDECREF(f->f_localmap);
|
||||||
INCREF(x);
|
INCREF(x);
|
||||||
f->f_localmap = x;
|
f->f_localmap = x;
|
||||||
f->f_fastlocals = x = newlistobject(
|
f->f_fastlocals = x = newlistobject(gettuplesize(x));
|
||||||
x->ob_type->tp_as_mapping->mp_length(x));
|
|
||||||
fastlocals = (listobject *) x;
|
fastlocals = (listobject *) x;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOAD_FAST:
|
case LOAD_FAST:
|
||||||
x = GETLISTITEM(fastlocals, oparg);
|
x = GETLISTITEM(fastlocals, oparg);
|
||||||
if (x == NULL) {
|
if (x == NULL) {
|
||||||
err_setstr(NameError,
|
err_setval(NameError,
|
||||||
"undefined local variable");
|
gettupleitem(f->f_localmap, oparg));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (is_accessobject(x)) {
|
if (is_accessobject(x)) {
|
||||||
|
@ -1156,12 +1159,12 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
case DELETE_FAST:
|
case DELETE_FAST:
|
||||||
x = GETLISTITEM(fastlocals, oparg);
|
x = GETLISTITEM(fastlocals, oparg);
|
||||||
if (x == NULL) {
|
if (x == NULL) {
|
||||||
err_setstr(NameError,
|
err_setval(NameError,
|
||||||
"undefined local variable");
|
gettupleitem(f->f_localmap, oparg));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (w != NULL && is_accessobject(w)) {
|
if (x != NULL && is_accessobject(x)) {
|
||||||
err = setaccessvalue(w, f->f_locals,
|
err = setaccessvalue(x, f->f_locals,
|
||||||
(object *)NULL);
|
(object *)NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1306,10 +1309,10 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
printf("--- Line %d ---\n", oparg);
|
printf("--- Line %d ---\n", oparg);
|
||||||
#endif
|
#endif
|
||||||
f->f_lineno = oparg;
|
f->f_lineno = oparg;
|
||||||
if (trace != NULL) {
|
if (f->f_trace != NULL) {
|
||||||
/* Trace each line of code reached */
|
/* Trace each line of code reached */
|
||||||
f->f_lasti = INSTR_OFFSET();
|
f->f_lasti = INSTR_OFFSET();
|
||||||
err = call_trace(&trace, &trace,
|
err = call_trace(&f->f_trace, &f->f_trace,
|
||||||
f, "line", None);
|
f, "line", None);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1368,8 +1371,8 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
f->f_lasti -= 2;
|
f->f_lasti -= 2;
|
||||||
tb_here(f);
|
tb_here(f);
|
||||||
|
|
||||||
if (trace)
|
if (f->f_trace)
|
||||||
call_exc_trace(&trace, &trace, f);
|
call_exc_trace(&f->f_trace, &f->f_trace, f);
|
||||||
if (sys_profile)
|
if (sys_profile)
|
||||||
call_exc_trace(&sys_profile, (object**)0, f);
|
call_exc_trace(&sys_profile, (object**)0, f);
|
||||||
}
|
}
|
||||||
|
@ -1446,15 +1449,15 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
if (why != WHY_RETURN)
|
if (why != WHY_RETURN)
|
||||||
retval = NULL;
|
retval = NULL;
|
||||||
|
|
||||||
if (trace) {
|
if (f->f_trace) {
|
||||||
if (why == WHY_RETURN) {
|
if (why == WHY_RETURN) {
|
||||||
if (call_trace(&trace, &trace, f, "return", retval)) {
|
if (call_trace(&f->f_trace, &f->f_trace, f,
|
||||||
|
"return", retval)) {
|
||||||
XDECREF(retval);
|
XDECREF(retval);
|
||||||
retval = NULL;
|
retval = NULL;
|
||||||
why = WHY_EXCEPTION;
|
why = WHY_EXCEPTION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XDECREF(trace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sys_profile && why == WHY_RETURN) {
|
if (sys_profile && why == WHY_RETURN) {
|
||||||
|
@ -1466,9 +1469,6 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fastlocals && (f->ob_refcnt > 1 || f->f_locals->ob_refcnt > 2))
|
|
||||||
fast_2_locals(f);
|
|
||||||
|
|
||||||
/* Restore previous frame and release the current one */
|
/* Restore previous frame and release the current one */
|
||||||
|
|
||||||
current_frame = f->f_back;
|
current_frame = f->f_back;
|
||||||
|
@ -1561,7 +1561,7 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
|
||||||
settupleitem(arglist, 2, arg);
|
settupleitem(arglist, 2, arg);
|
||||||
tracing++;
|
tracing++;
|
||||||
fast_2_locals(f);
|
fast_2_locals(f);
|
||||||
res = call_object(*p_trace, arglist);
|
res = call_object(*p_trace, arglist); /* May clear *p_trace! */
|
||||||
locals_2_fast(f, 1);
|
locals_2_fast(f, 1);
|
||||||
tracing--;
|
tracing--;
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -1569,7 +1569,7 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
/* The trace proc raised an exception */
|
/* The trace proc raised an exception */
|
||||||
tb_here(f);
|
tb_here(f);
|
||||||
DECREF(*p_trace);
|
XDECREF(*p_trace);
|
||||||
*p_trace = NULL;
|
*p_trace = NULL;
|
||||||
if (p_newtrace) {
|
if (p_newtrace) {
|
||||||
XDECREF(*p_newtrace);
|
XDECREF(*p_newtrace);
|
||||||
|
@ -1592,91 +1592,6 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
fast_2_locals(f)
|
|
||||||
frameobject *f;
|
|
||||||
{
|
|
||||||
/* Merge f->f_fastlocals into f->f_locals */
|
|
||||||
object *locals, *fast, *map;
|
|
||||||
object *error_type, *error_value;
|
|
||||||
int pos;
|
|
||||||
object *key, *value;
|
|
||||||
if (f == NULL)
|
|
||||||
return;
|
|
||||||
locals = f->f_locals;
|
|
||||||
fast = f->f_fastlocals;
|
|
||||||
map = f->f_localmap;
|
|
||||||
if (locals == NULL || fast == NULL || map == NULL)
|
|
||||||
return;
|
|
||||||
if (!is_dictobject(locals) || !is_listobject(fast) ||
|
|
||||||
!is_dictobject(map))
|
|
||||||
return;
|
|
||||||
err_get(&error_type, &error_value);
|
|
||||||
pos = 0;
|
|
||||||
while (mappinggetnext(map, &pos, &key, &value)) {
|
|
||||||
int j;
|
|
||||||
if (!is_intobject(value))
|
|
||||||
continue;
|
|
||||||
j = getintvalue(value);
|
|
||||||
value = getlistitem(fast, j);
|
|
||||||
if (value == NULL) {
|
|
||||||
err_clear();
|
|
||||||
if (dict2remove(locals, key) != 0)
|
|
||||||
err_clear();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (dict2insert(locals, key, value) != 0)
|
|
||||||
err_clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err_setval(error_type, error_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
locals_2_fast(f, clear)
|
|
||||||
frameobject *f;
|
|
||||||
int clear;
|
|
||||||
{
|
|
||||||
/* Merge f->f_locals into f->f_fastlocals */
|
|
||||||
object *locals, *fast, *map;
|
|
||||||
object *error_type, *error_value;
|
|
||||||
int pos;
|
|
||||||
object *key, *value;
|
|
||||||
if (f == NULL)
|
|
||||||
return;
|
|
||||||
locals = f->f_locals;
|
|
||||||
fast = f->f_fastlocals;
|
|
||||||
map = f->f_localmap;
|
|
||||||
if (locals == NULL || fast == NULL || map == NULL)
|
|
||||||
return;
|
|
||||||
if (!is_dictobject(locals) || !is_listobject(fast) ||
|
|
||||||
!is_dictobject(map))
|
|
||||||
return;
|
|
||||||
err_get(&error_type, &error_value);
|
|
||||||
pos = 0;
|
|
||||||
while (mappinggetnext(map, &pos, &key, &value)) {
|
|
||||||
int j;
|
|
||||||
if (!is_intobject(value))
|
|
||||||
continue;
|
|
||||||
j = getintvalue(value);
|
|
||||||
value = dict2lookup(locals, key);
|
|
||||||
if (value == NULL)
|
|
||||||
err_clear();
|
|
||||||
else
|
|
||||||
INCREF(value);
|
|
||||||
if (value != NULL || clear)
|
|
||||||
if (setlistitem(fast, j, value) != 0)
|
|
||||||
err_clear();
|
|
||||||
}
|
|
||||||
err_setval(error_type, error_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mergelocals()
|
|
||||||
{
|
|
||||||
locals_2_fast(current_frame, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
object *
|
object *
|
||||||
getlocals()
|
getlocals()
|
||||||
{
|
{
|
||||||
|
@ -1704,6 +1619,12 @@ getowner()
|
||||||
return current_frame->f_owner;
|
return current_frame->f_owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object *
|
||||||
|
getframe()
|
||||||
|
{
|
||||||
|
return (object *)current_frame;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
printtraceback(f)
|
printtraceback(f)
|
||||||
object *f;
|
object *f;
|
||||||
|
@ -1999,10 +1920,31 @@ call_object(func, arg)
|
||||||
object *func;
|
object *func;
|
||||||
object *arg;
|
object *arg;
|
||||||
{
|
{
|
||||||
if (is_instancemethodobject(func) || is_funcobject(func))
|
binaryfunc call;
|
||||||
return call_function(func, arg);
|
object *result;
|
||||||
|
|
||||||
|
if (call = func->ob_type->tp_call) {
|
||||||
|
int size = gettuplesize(arg);
|
||||||
|
if (arg) {
|
||||||
|
size = gettuplesize(arg);
|
||||||
|
if (size == 1)
|
||||||
|
arg = gettupleitem(arg, 0);
|
||||||
|
else if (size == 0)
|
||||||
|
arg = NULL;
|
||||||
|
}
|
||||||
|
result = (*call)(func, arg);
|
||||||
|
}
|
||||||
|
else if (is_instancemethodobject(func) || is_funcobject(func))
|
||||||
|
result = call_function(func, arg);
|
||||||
else
|
else
|
||||||
return call_builtin(func, arg);
|
result = call_builtin(func, arg);
|
||||||
|
|
||||||
|
if (result == NULL && !err_occurred()) {
|
||||||
|
fprintf(stderr, "null result without error in call_object\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
|
@ -2025,6 +1967,17 @@ call_builtin(func, arg)
|
||||||
if (is_classobject(func)) {
|
if (is_classobject(func)) {
|
||||||
return newinstanceobject(func, arg);
|
return newinstanceobject(func, arg);
|
||||||
}
|
}
|
||||||
|
if (is_instanceobject(func)) {
|
||||||
|
object *res, *call = getattr(func,"__call__");
|
||||||
|
if (call == NULL) {
|
||||||
|
err_clear();
|
||||||
|
err_setstr(AttributeError, "no __call__ method defined");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
res = call_object(call, arg);
|
||||||
|
DECREF(call);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
err_setstr(TypeError, "call of non-function");
|
err_setstr(TypeError, "call of non-function");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2038,6 +1991,8 @@ call_function(func, arg)
|
||||||
object *newlocals, *newglobals;
|
object *newlocals, *newglobals;
|
||||||
object *class = NULL;
|
object *class = NULL;
|
||||||
object *co, *v;
|
object *co, *v;
|
||||||
|
object *argdefs;
|
||||||
|
int argcount;
|
||||||
|
|
||||||
if (is_instancemethodobject(func)) {
|
if (is_instancemethodobject(func)) {
|
||||||
object *self = instancemethodgetself(func);
|
object *self = instancemethodgetself(func);
|
||||||
|
@ -2065,7 +2020,6 @@ call_function(func, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int argcount;
|
|
||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
argcount = 0;
|
argcount = 0;
|
||||||
else if (is_tupleobject(arg))
|
else if (is_tupleobject(arg))
|
||||||
|
@ -2100,6 +2054,39 @@ call_function(func, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argdefs = getfuncargstuff(func, &argcount);
|
||||||
|
if (argdefs != NULL && arg != NULL && is_tupleobject(arg)) {
|
||||||
|
int actualcount, j;
|
||||||
|
/* Process default arguments */
|
||||||
|
if (argcount & 0x4000)
|
||||||
|
argcount ^= 0x4000;
|
||||||
|
actualcount = gettuplesize(arg);
|
||||||
|
j = gettuplesize(argdefs) - (argcount - actualcount);
|
||||||
|
if (actualcount < argcount && j >= 0) {
|
||||||
|
int i;
|
||||||
|
object *v;
|
||||||
|
if (newarg == NULL)
|
||||||
|
INCREF(arg);
|
||||||
|
newarg = newtupleobject(argcount);
|
||||||
|
if (newarg == NULL) {
|
||||||
|
DECREF(arg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < actualcount; i++) {
|
||||||
|
v = gettupleitem(arg, i);
|
||||||
|
XINCREF(v);
|
||||||
|
settupleitem(newarg, i, v);
|
||||||
|
}
|
||||||
|
for (; i < argcount; i++, j++) {
|
||||||
|
v = gettupleitem(argdefs, j);
|
||||||
|
XINCREF(v);
|
||||||
|
settupleitem(newarg, i, v);
|
||||||
|
}
|
||||||
|
DECREF(arg);
|
||||||
|
arg = newarg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
co = getfunccode(func);
|
co = getfunccode(func);
|
||||||
if (co == NULL) {
|
if (co == NULL) {
|
||||||
XDECREF(newarg);
|
XDECREF(newarg);
|
||||||
|
@ -2162,18 +2149,18 @@ loop_subscript(v, w)
|
||||||
object *v, *w;
|
object *v, *w;
|
||||||
{
|
{
|
||||||
sequence_methods *sq = v->ob_type->tp_as_sequence;
|
sequence_methods *sq = v->ob_type->tp_as_sequence;
|
||||||
int i, n;
|
int i;
|
||||||
if (sq == NULL) {
|
if (sq == NULL) {
|
||||||
err_setstr(TypeError, "loop over non-sequence");
|
err_setstr(TypeError, "loop over non-sequence");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
i = getintvalue(w);
|
i = getintvalue(w);
|
||||||
n = (*sq->sq_length)(v);
|
v = (*sq->sq_item)(v, i);
|
||||||
if (n < 0)
|
if (v)
|
||||||
return NULL; /* Exception */
|
return v;
|
||||||
if (i >= n)
|
if (err_occurred() == IndexError)
|
||||||
return NULL; /* End of loop */
|
err_clear();
|
||||||
return (*sq->sq_item)(v, i);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -2300,7 +2287,7 @@ static int
|
||||||
cmp_member(v, w)
|
cmp_member(v, w)
|
||||||
object *v, *w;
|
object *v, *w;
|
||||||
{
|
{
|
||||||
int i, n, cmp;
|
int i, cmp;
|
||||||
object *x;
|
object *x;
|
||||||
sequence_methods *sq;
|
sequence_methods *sq;
|
||||||
/* Special case for char in string */
|
/* Special case for char in string */
|
||||||
|
@ -2327,11 +2314,15 @@ cmp_member(v, w)
|
||||||
"'in' or 'not in' needs sequence right argument");
|
"'in' or 'not in' needs sequence right argument");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = (*sq->sq_length)(w);
|
for (i = 0; ; i++) {
|
||||||
if (n < 0)
|
|
||||||
return -1;
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
x = (*sq->sq_item)(w, i);
|
x = (*sq->sq_item)(w, i);
|
||||||
|
if (x == NULL) {
|
||||||
|
if (err_occurred() == IndexError) {
|
||||||
|
err_clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
cmp = cmpobject(v, x);
|
cmp = cmpobject(v, x);
|
||||||
XDECREF(x);
|
XDECREF(x);
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
|
@ -2473,17 +2464,13 @@ access_statement(name, vmode, f)
|
||||||
if (f->f_localmap == NULL)
|
if (f->f_localmap == NULL)
|
||||||
value = dict2lookup(f->f_locals, name);
|
value = dict2lookup(f->f_locals, name);
|
||||||
else {
|
else {
|
||||||
value = dict2lookup(f->f_localmap, name);
|
object *map = f->f_localmap;
|
||||||
if (value == NULL || !is_intobject(value))
|
|
||||||
value = NULL;
|
value = NULL;
|
||||||
else {
|
for (fastind = gettuplesize(map); --fastind >= 0; ) {
|
||||||
fastind = getintvalue(value);
|
object *fname = gettupleitem(map, fastind);
|
||||||
if (0 <= fastind &&
|
if (cmpobject(name, fname) == 0) {
|
||||||
fastind < getlistsize(f->f_fastlocals))
|
|
||||||
value = getlistitem(f->f_fastlocals, fastind);
|
value = getlistitem(f->f_fastlocals, fastind);
|
||||||
else {
|
break;
|
||||||
value = NULL;
|
|
||||||
fastind = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue