summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c213
1 files changed, 151 insertions, 62 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 44239e6..57abda6 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -84,9 +84,10 @@ static int cmp_exception PROTO((object *, object *));
static int cmp_member PROTO((object *, object *));
static object *cmp_outcome PROTO((int, object *, object *));
static int import_from PROTO((object *, object *, object *));
-static object *build_class PROTO((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 *, int, frameobject *));
/* Pointer to current frame, used to link new frames to */
@@ -743,10 +744,12 @@ eval_code(co, globals, locals, arg)
break;
case BUILD_CLASS:
- w = POP();
+ u = POP();
v = POP();
- x = build_class(v, w);
+ w = POP();
+ x = build_class(u, v, w);
PUSH(x);
+ DECREF(u);
DECREF(v);
DECREF(w);
break;
@@ -754,12 +757,24 @@ eval_code(co, globals, locals, arg)
case STORE_NAME:
w = GETNAMEV(oparg);
v = POP();
+ u = dict2lookup(f->f_locals, w);
+ if (u != NULL && is_accessobject(u)) {
+ err = setaccessvalue(u, (object *)NULL, v);
+ DECREF(v);
+ break;
+ }
err = dict2insert(f->f_locals, w, v);
DECREF(v);
break;
case DELETE_NAME:
w = GETNAMEV(oparg);
+ u = dict2lookup(f->f_locals, w);
+ if (u != NULL && is_accessobject(u)) {
+ err = setaccessvalue(u, (object *)NULL,
+ (object *)NULL);
+ break;
+ }
if ((err = dict2remove(f->f_locals, w)) != 0)
err_setstr(NameError, getstringvalue(w));
break;
@@ -952,12 +967,24 @@ eval_code(co, globals, locals, arg)
case STORE_GLOBAL:
w = GETNAMEV(oparg);
v = POP();
+ u = dict2lookup(f->f_locals, w);
+ if (u != NULL && is_accessobject(u)) {
+ err = setaccessvalue(u, (object *)NULL, v);
+ DECREF(v);
+ break;
+ }
err = dict2insert(f->f_globals, w, v);
DECREF(v);
break;
case DELETE_GLOBAL:
w = GETNAMEV(oparg);
+ u = dict2lookup(f->f_locals, w);
+ if (u != NULL && is_accessobject(u)) {
+ err = setaccessvalue(u, (object *)NULL,
+ (object *)NULL);
+ break;
+ }
if ((err = dict2remove(f->f_globals, w)) != 0)
err_setstr(NameError, getstringvalue(w));
break;
@@ -984,6 +1011,11 @@ eval_code(co, globals, locals, arg)
}
}
}
+ if (is_accessobject(x)) {
+ x = getaccessvalue(x, (object *)NULL);
+ if (x == NULL)
+ break;
+ }
INCREF(x);
PUSH(x);
break;
@@ -1000,6 +1032,11 @@ eval_code(co, globals, locals, arg)
break;
}
}
+ if (is_accessobject(x)) {
+ x = getaccessvalue(x, (object *)NULL);
+ if (x == NULL)
+ break;
+ }
INCREF(x);
PUSH(x);
break;
@@ -1011,6 +1048,11 @@ eval_code(co, globals, locals, arg)
err_setstr(NameError, getstringvalue(w));
break;
}
+ if (is_accessobject(x)) {
+ x = getaccessvalue(x, (object *)NULL);
+ if (x == NULL)
+ break;
+ }
INCREF(x);
PUSH(x);
break;
@@ -1041,15 +1083,25 @@ eval_code(co, globals, locals, arg)
"undefined local variable");
break;
}
+ if (is_accessobject(x)) {
+ x = getaccessvalue(x, (object *)NULL);
+ if (x == NULL)
+ break;
+ }
INCREF(x);
PUSH(x);
break;
case STORE_FAST:
+ v = POP();
w = GETLISTITEM(fastlocals, oparg);
+ if (w != NULL && is_accessobject(w)) {
+ err = setaccessvalue(w, (object *)NULL, v);
+ DECREF(v);
+ break;
+ }
XDECREF(w);
- w = POP();
- GETLISTITEM(fastlocals, oparg) = w;
+ GETLISTITEM(fastlocals, oparg) = v;
break;
case DELETE_FAST:
@@ -1059,6 +1111,11 @@ eval_code(co, globals, locals, arg)
"undefined local variable");
break;
}
+ if (w != NULL && is_accessobject(w)) {
+ err = setaccessvalue(w, (object *)NULL,
+ (object *)NULL);
+ break;
+ }
DECREF(x);
GETLISTITEM(fastlocals, oparg) = NULL;
break;
@@ -1124,6 +1181,13 @@ eval_code(co, globals, locals, arg)
err = import_from(f->f_locals, v, w);
locals_2_fast(f, 0);
break;
+
+ case ACCESS_MODE:
+ v = POP();
+ w = GETNAMEV(oparg);
+ err = access_statement(w, (int)getintvalue(v), f);
+ DECREF(v);
+ break;
case JUMP_FORWARD:
JUMPBY(oparg);
@@ -1483,7 +1547,8 @@ fast_2_locals(f)
/* Merge f->f_fastlocals into f->f_locals */
object *locals, *fast, *map;
object *error_type, *error_value;
- int i;
+ int pos;
+ object *key, *value;
if (f == NULL)
return;
locals = f->f_locals;
@@ -1495,16 +1560,10 @@ fast_2_locals(f)
!is_dictobject(map))
return;
err_get(&error_type, &error_value);
- i = getdictsize(map);
- while (--i >= 0) {
- object *key;
- object *value;
+ pos = 0;
+ while (mappinggetnext(map, &pos, &key, &value)) {
int j;
- key = getdict2key(map, i);
- if (key == NULL)
- continue;
- value = dict2lookup(map, key);
- if (value == NULL || !is_intobject(value))
+ if (!is_intobject(value))
continue;
j = getintvalue(value);
value = getlistitem(fast, j);
@@ -1529,7 +1588,8 @@ locals_2_fast(f, clear)
/* Merge f->f_locals into f->f_fastlocals */
object *locals, *fast, *map;
object *error_type, *error_value;
- int i;
+ int pos;
+ object *key, *value;
if (f == NULL)
return;
locals = f->f_locals;
@@ -1541,16 +1601,10 @@ locals_2_fast(f, clear)
!is_dictobject(map))
return;
err_get(&error_type, &error_value);
- i = getdictsize(map);
- while (--i >= 0) {
- object *key;
- object *value;
+ pos = 0;
+ while (mappinggetnext(map, &pos, &key, &value)) {
int j;
- key = getdict2key(map, i);
- if (key == NULL)
- continue;
- value = dict2lookup(map, key);
- if (value == NULL || !is_intobject(value))
+ if (!is_intobject(value))
continue;
j = getintvalue(value);
value = dict2lookup(locals, key);
@@ -1907,14 +1961,7 @@ call_builtin(func, arg)
return (*meth)(self, arg);
}
if (is_classobject(func)) {
- if (arg != NULL &&
- !(is_tupleobject(arg) &&
- gettuplesize(arg) == 0)) {
- err_setstr(TypeError,
- "classobject() allows no arguments");
- return NULL;
- }
- return newinstanceobject(func);
+ return newinstanceobject(func, arg);
}
err_setstr(TypeError, "call of non-function");
return NULL;
@@ -2258,19 +2305,14 @@ import_from(locals, v, name)
object *w, *x;
w = getmoduledict(v);
if (getstringvalue(name)[0] == '*') {
- int i;
- int n = getdictsize(w);
- for (i = 0; i < n; i++) {
- name = getdict2key(w, i);
- if (name == NULL || getstringvalue(name)[0] == '_')
+ int pos;
+ object *name, *value;
+ pos = 0;
+ while (mappinggetnext(w, &pos, &name, &value)) {
+ if (!is_stringobject(name) ||
+ getstringvalue(name)[0] == '_')
continue;
- x = dict2lookup(w, name);
- if (x == NULL) {
- /* XXX can't happen? */
- err_setstr(SystemError, getstringvalue(name));
- return -1;
- }
- if (dict2insert(locals, name, x) != 0)
+ if (dict2insert(locals, name, value) != 0)
return -1;
}
return 0;
@@ -2290,27 +2332,74 @@ import_from(locals, v, name)
}
static object *
-build_class(v, w)
- object *v; /* None or tuple containing base classes */
- object *w; /* dictionary */
+build_class(methods, bases, name)
+ object *methods; /* dictionary */
+ object *bases; /* tuple containing classes */
+ object *name; /* string */
{
- if (is_tupleobject(v)) {
- int i;
- for (i = gettuplesize(v); --i >= 0; ) {
- object *x = gettupleitem(v, i);
- if (!is_classobject(x)) {
- err_setstr(TypeError,
- "base is not a class object");
- return NULL;
- }
+ int i;
+ if (!is_tupleobject(bases)) {
+ err_setstr(SystemError, "build_class with non-tuple bases");
+ return NULL;
+ }
+ if (!is_dictobject(methods)) {
+ err_setstr(SystemError, "build_class with non-dictionary");
+ return NULL;
+ }
+ if (!is_stringobject(name)) {
+ err_setstr(SystemError, "build_class witn non-string name");
+ return NULL;
+ }
+ for (i = gettuplesize(bases); --i >= 0; ) {
+ object *base = gettupleitem(bases, i);
+ if (!is_classobject(base)) {
+ err_setstr(TypeError,
+ "base is not a class object");
+ return NULL;
}
}
+ return newclassobject(bases, methods, name);
+}
+
+static int
+access_statement(name, mode, f)
+ object *name;
+ int mode;
+ frameobject *f;
+{
+ object *value;
+ int i = -1;
+ object *ac;
+ int ret;
+ if (f->f_localmap == NULL)
+ value = dict2lookup(f->f_locals, name);
else {
- v = NULL;
+ value = dict2lookup(f->f_localmap, name);
+ if (value == NULL || !is_intobject(value))
+ value = NULL;
+ else {
+ i = getintvalue(value);
+ if (0 <= i && i < getlistsize(f->f_fastlocals))
+ value = getlistitem(f->f_fastlocals, i);
+ else {
+ value = NULL;
+ i = -1;
+ }
+ }
}
- if (!is_dictobject(w)) {
- err_setstr(SystemError, "build_class with non-dictionary");
- return NULL;
+ if (value && is_accessobject(value)) {
+ err_setstr(AccessError, "can't override access");
+ return -1;
+ }
+ err_clear();
+ ac = newaccessobject(value, (object*)NULL, (typeobject*)NULL, mode);
+ if (ac == NULL)
+ return -1;
+ if (i >= 0)
+ ret = setlistitem(f->f_fastlocals, i, ac);
+ else {
+ ret = dict2insert(f->f_locals, name, ac);
+ DECREF(ac);
}
- return newclassobject(v, w, (object *) NULL);
+ return ret;
}