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

Skip to content

Commit 9c7b861

Browse files
committed
New argument passing mechanism.
1 parent c02e15c commit 9c7b861

1 file changed

Lines changed: 109 additions & 35 deletions

File tree

Python/ceval.c

Lines changed: 109 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static object *xor();
5959
static object *or();
6060
static object *call_builtin();
6161
static object *call_function();
62+
object *call_object();
6263
static object *apply_subscript();
6364
static object *loop_subscript();
6465
static object *apply_slice();
@@ -272,10 +273,7 @@ eval_code(co, globals, locals, arg)
272273

273274
case UNARY_CALL:
274275
v = POP();
275-
if (is_instancemethodobject(v) || is_funcobject(v))
276-
x = call_function(v, (object *)NULL);
277-
else
278-
x = call_builtin(v, (object *)NULL);
276+
x = call_object(v, (object *)NULL);
279277
DECREF(v);
280278
PUSH(x);
281279
break;
@@ -344,10 +342,7 @@ eval_code(co, globals, locals, arg)
344342
case BINARY_CALL:
345343
w = POP();
346344
v = POP();
347-
if (is_instancemethodobject(v) || is_funcobject(v))
348-
x = call_function(v, w);
349-
else
350-
x = call_builtin(v, w);
345+
x = call_object(v, w);
351346
DECREF(v);
352347
DECREF(w);
353348
PUSH(x);
@@ -550,22 +545,6 @@ eval_code(co, globals, locals, arg)
550545
why = WHY_RETURN;
551546
break;
552547

553-
case REQUIRE_ARGS:
554-
if (EMPTY()) {
555-
err_setstr(TypeError,
556-
"function expects argument(s)");
557-
why = WHY_EXCEPTION;
558-
}
559-
break;
560-
561-
case REFUSE_ARGS:
562-
if (!EMPTY()) {
563-
err_setstr(TypeError,
564-
"function expects no argument(s)");
565-
why = WHY_EXCEPTION;
566-
}
567-
break;
568-
569548
case BUILD_FUNCTION:
570549
v = POP();
571550
x = newfuncobject(v, f->f_globals);
@@ -629,6 +608,79 @@ eval_code(co, globals, locals, arg)
629608
err_setstr(NameError, getstringvalue(w));
630609
break;
631610

611+
case UNPACK_ARG:
612+
/* Implement various compatibility hacks:
613+
(a) f(a,b,...) should accept f((1,2,...))
614+
(b) f((a,b,...)) should accept f(1,2,...)
615+
(c) f(self,(a,b,...)) should accept f(x,1,2,...)
616+
*/
617+
{
618+
int n;
619+
if (EMPTY()) {
620+
err_setstr(TypeError,
621+
"no argument list");
622+
why = WHY_EXCEPTION;
623+
break;
624+
}
625+
v = POP();
626+
if (!is_tupleobject(v)) {
627+
err_setstr(TypeError,
628+
"bad argument list");
629+
why = WHY_EXCEPTION;
630+
break;
631+
}
632+
n = gettuplesize(v);
633+
if (n == 1 && oparg != 1) {
634+
/* Rule (a) */
635+
w = gettupleitem(v, 0);
636+
if (is_tupleobject(w)) {
637+
INCREF(w);
638+
DECREF(v);
639+
v = w;
640+
n = gettuplesize(v);
641+
}
642+
}
643+
else if (n != 1 && oparg == 1) {
644+
/* Rule (b) */
645+
PUSH(v);
646+
break;
647+
/* Don't fall through */
648+
}
649+
else if (n > 2 && oparg == 2) {
650+
/* Rule (c) */
651+
int i;
652+
w = newtupleobject(n-1);
653+
u = newtupleobject(2);
654+
if (u == NULL || w == NULL) {
655+
XDECREF(w);
656+
XDECREF(u);
657+
DECREF(v);
658+
why = WHY_EXCEPTION;
659+
break;
660+
}
661+
t = gettupleitem(v, 0);
662+
INCREF(t);
663+
settupleitem(u, 0, t);
664+
for (i = 1; i < n; i++) {
665+
t = gettupleitem(v, i);
666+
INCREF(t);
667+
settupleitem(w, i-1, t);
668+
}
669+
settupleitem(u, 1, w);
670+
DECREF(v);
671+
v = u;
672+
n = 2;
673+
}
674+
if (n != oparg) {
675+
err_setstr(TypeError,
676+
"arg count mismatch");
677+
why = WHY_EXCEPTION;
678+
DECREF(v);
679+
break;
680+
}
681+
PUSH(v);
682+
}
683+
/* Fall through */
632684
case UNPACK_TUPLE:
633685
v = POP();
634686
if (!is_tupleobject(v)) {
@@ -1346,10 +1398,19 @@ call_builtin(func, arg)
13461398
if (is_methodobject(func)) {
13471399
method meth = getmethod(func);
13481400
object *self = getself(func);
1401+
if (!getvarargs(func) && arg != NULL && is_tupleobject(arg)) {
1402+
int size = gettuplesize(arg);
1403+
if (size == 1)
1404+
arg = gettupleitem(arg, 0);
1405+
else if (size == 0)
1406+
arg = NULL;
1407+
}
13491408
return (*meth)(self, arg);
13501409
}
13511410
if (is_classobject(func)) {
1352-
if (arg != NULL) {
1411+
if (arg != NULL &&
1412+
!(is_tupleobject(arg) &&
1413+
gettuplesize(arg) == 0)) {
13531414
err_setstr(TypeError,
13541415
"classobject() allows no arguments");
13551416
return NULL;
@@ -1370,21 +1431,34 @@ call_function(func, arg)
13701431
object *co, *v;
13711432

13721433
if (is_instancemethodobject(func)) {
1434+
int argcount;
13731435
object *self = instancemethodgetself(func);
13741436
func = instancemethodgetfunc(func);
1375-
if (arg == NULL) {
1376-
arg = self;
1377-
}
1378-
else {
1379-
newarg = newtupleobject(2);
1380-
if (newarg == NULL)
1381-
return NULL;
1382-
INCREF(self);
1437+
if (arg == NULL)
1438+
argcount = 0;
1439+
else if (is_tupleobject(arg))
1440+
argcount = gettuplesize(arg);
1441+
else
1442+
argcount = 1;
1443+
newarg = newtupleobject(argcount + 1);
1444+
if (newarg == NULL)
1445+
return NULL;
1446+
INCREF(self);
1447+
settupleitem(newarg, 0, self);
1448+
if (arg != NULL && !is_tupleobject(arg)) {
13831449
INCREF(arg);
1384-
settupleitem(newarg, 0, self);
13851450
settupleitem(newarg, 1, arg);
1386-
arg = newarg;
13871451
}
1452+
else {
1453+
int i;
1454+
object *v;
1455+
for (i = 0; i < argcount; i++) {
1456+
v = gettupleitem(arg, i);
1457+
XINCREF(v);
1458+
settupleitem(newarg, i+1, v);
1459+
}
1460+
}
1461+
arg = newarg;
13881462
}
13891463
else {
13901464
if (!is_funcobject(func)) {

0 commit comments

Comments
 (0)