Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: f35b03c947
Fetching contributors…

Cannot retrieve contributors at this time

387 lines (266 sloc) 8.105 kB
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
$Id$
=head1 NAME
classes/pyclass.pmc - Python Class
=head1 DESCRIPTION
These are the vtable functions for the Python Class base class (i.e.,
methods you would expect to see on python objects).
=head2 Methods
=over 4
=cut
*/
#include "parrot/parrot.h"
/* cache of classes referenced */
static INTVAL dynclass_PyType;
static STRING *CLASS;
static STRING *CMP;
static STRING *INT;
static STRING *ITER;
static STRING *NAME;
static STRING *REPR;
static STRING *STR;
struct parrot_regs_t *
Parrot_PyClass_runops_fromc(Parrot_Interp interpreter, PMC *sub);
struct parrot_regs_t *
Parrot_PyClass_runops_fromc(Parrot_Interp interpreter, PMC *sub)
{
opcode_t offset, *dest;
struct parrot_regs_t *bp_save, *bp_new;
bp_save = interpreter->ctx.bp;
dest = VTABLE_invoke(interpreter, sub, NULL);
bp_new = interpreter->ctx.bp;
if (dest) {
/* we need one return continuation with a NULL offset */
interpreter->ctx.current_cont = REG_PMC(1) =
new_ret_continuation_pmc(interpreter, NULL);
#if GC_VERBOSE
PObj_report_SET(REG_PMC(1)); /* s. also dod.c */
#endif
if (bp_new != bp_save) copy_regs(interpreter, bp_save);
interpreter->ctx.current_sub = sub;
offset = dest - interpreter->code->byte_code;
runops(interpreter, offset);
}
interpreter->ctx.bp = bp_save;
return bp_new;
}
static PMC *
Parrot_PyClass_run_meth_fromc_P(Parrot_Interp interpreter, PMC *sub,
PMC *obj, STRING *meth)
{
/* TODO: optimize for func->vtable->base_type == enum_class_NCI */
struct parrot_regs_t *bp;
struct Parrot_Context ctx;
PMC *ret;
save_context(interpreter, &ctx);
REG_STR(0) = meth;
REG_INT(0) = REG_INT(3) = 1;
REG_INT(1) = REG_INT(2) = 0;
REG_PMC(5) = obj;
interpreter->ctx.current_object = REG_PMC(2) = obj;
bp = Parrot_PyClass_runops_fromc(interpreter, sub);
ret = BP_REG_PMC(bp,5);
restore_context(interpreter, &ctx);
return ret;
}
static PMC *
Parrot_PyClass_run_meth_fromc_P_P(Parrot_Interp interpreter, PMC *sub,
PMC *obj, STRING *meth, PMC* arg1)
{
/* TODO: optimize for func->vtable->base_type == enum_class_NCI */
struct parrot_regs_t *bp;
struct Parrot_Context ctx;
PMC *ret;
save_context(interpreter, &ctx);
REG_STR(0) = meth;
REG_INT(0) = 1;
REG_INT(1) = REG_INT(2) = 0;
REG_INT(3) = 2;
REG_PMC(5) = obj;
REG_PMC(6) = arg1;
interpreter->ctx.current_object = REG_PMC(2) = obj;
bp = Parrot_PyClass_runops_fromc(interpreter, sub);
ret = BP_REG_PMC(bp,5);
restore_context(interpreter, &ctx);
return ret;
}
pmclass PyClass dynpmc group python_group {
/*
=item C<void class_init()>
Class initialization. Caches the type id of various PMCs because
they will be used frequently here.
=cut
*/
void class_init() {
if (pass) {
dynclass_PyType = Parrot_PMC_typenum(INTERP, "PyType");
CLASS = const_string(INTERP, "__class__");
CMP = const_string(INTERP, "__cmp__");
INT = const_string(INTERP, "__int__");
ITER = const_string(INTERP, "__iter__");
NAME = const_string(INTERP, "__name__");
REPR = const_string(INTERP, "__repr__");
STR = const_string(INTERP, "__str__");
}
}
/*
=item C<void destroy()>
Destroys the object.
=cut
*/
void destroy () {
}
/*
=item C<PMC *find_method(STRING *method_name)>
Looks up the method for C<*method_name> and returns it.
=cut
*/
PMC* find_method(STRING* method_name) {
PMC *class;
PMC *method = VTABLE_getprop(INTERP, SELF, method_name);
if (method && VTABLE_defined(INTERP, method)) return method;
class = VTABLE_getprop(INTERP, SELF, CLASS);
if (class) {
return VTABLE_find_method(INTERP, class, method_name);
}
return 0;
}
/*
=item C<PMC* get_attr_str(STRING *name)>
Return attribute named C<name>.
=cut
*/
PMC* get_attr_str(STRING* idx) {
PMC *class;
PMC *attr = VTABLE_getprop(INTERP, SELF, idx);
if (attr && VTABLE_defined(INTERP, attr)) return attr;
class = VTABLE_getprop(INTERP, SELF, CLASS);
if (class) {
attr = VTABLE_get_attr_str(INTERP, class, idx);
}
if (!attr || !VTABLE_defined(INTERP, attr)) {
STRING *message;
message = Parrot_sprintf_c(INTERP, "AttributeError: %s",
string_to_cstring(INTERP, idx));
real_exception(INTERP, NULL, E_AttributeError,
string_to_cstring(INTERP, message));
}
return attr;
}
/*
=item C<PMC *get_class()>
Return the class of this object.
=cut
*/
PMC* get_class() {
PMC *ret = VTABLE_getprop(INTERP, SELF, CLASS);
return ret;
}
/*
=item C<INTVAL cmp(PMC *value)>
Returns the result of comparing the integer with C<*value>.
=cut
TODO: optimize for NCI, PyProxyClass
*/
INTVAL cmp(PMC* value) {
PMC *cmpsub, *ret;
if (SELF == value) return 0;
cmpsub = VTABLE_find_method(INTERP, SELF, CMP);
if (!cmpsub || !VTABLE_defined(INTERP, cmpsub))
return -1;
ret = Parrot_PyClass_run_meth_fromc_P_P(INTERP, cmpsub,
SELF, CMP, value);
return VTABLE_get_integer(INTERP, ret);
}
/*
=item C<INTVAL get_integer()>
Returns the integer value of the object.
=cut
*/
INTVAL get_integer () {
PMC *getint = VTABLE_find_method(INTERP, SELF, INT);
PMC *ret;
if (!getint || !VTABLE_defined(INTERP, getint))
real_exception(INTERP, NULL, E_TypeError,
"TypeError: int() argument must be a string or a number");
ret = Parrot_PyClass_run_meth_fromc_P(INTERP, getint, SELF, INT);
return VTABLE_get_integer(INTERP, ret);
}
/*
=item C<PMC *get_iter()>
Return an iterator for this object.
=cut
*/
PMC* get_iter() {
PMC *iter = VTABLE_find_method(INTERP, SELF, ITER);
if (!iter || !VTABLE_defined(INTERP, iter))
real_exception(INTERP, NULL, E_TypeError,
"TypeError: iteration over non-sequence");
return Parrot_PyClass_run_meth_fromc_P(INTERP, iter, SELF, ITER);
}
/*
=item C<STRING *get_repr()>
Return the representation of this object.
=cut
*/
STRING* get_repr() {
PMC *repr = VTABLE_find_method(INTERP, SELF, REPR);
if (repr) {
PMC *temp;
STRING *ret;
temp = Parrot_PyClass_run_meth_fromc_P(INTERP, repr, SELF, REPR);
ret = VTABLE_get_string(INTERP, temp);
return ret;
}
else {
STRING *res;
res = string_from_cstring(INTERP, "<", 0);
res = string_append(INTERP, res,
VTABLE_name(INTERP, VTABLE_get_class(INTERP, SELF)), 0);
res = string_append(INTERP, res,
const_string(INTERP, " instance at "), 0);
res = string_append(INTERP, res,
Parrot_sprintf_c(INTERP, "%#x", (INTVAL) SELF), 0);
res = string_append(INTERP, res,
const_string(INTERP, ">"), 0);
return res;
}
}
/*
=item C<STRING *get_string()>
Return the object in string form.
=cut
*/
STRING* get_string() {
PMC *str = VTABLE_find_method(INTERP, SELF, STR);
if (str) {
PMC *ret;
ret = Parrot_PyClass_run_meth_fromc_P(INTERP, str, SELF, STR);
return VTABLE_get_string(INTERP, ret);
}
else {
return VTABLE_get_repr(INTERP, SELF);
}
}
/*
=item C<STRING *name()>
Returns the name of this class.
*/
STRING* name() {
return VTABLE_name(INTERP, VTABLE_get_class(INTERP, SELF));
}
/*
=back
=cut
*/
}
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: expandtab shiftwidth=4:
*/
Jump to Line
Something went wrong with that request. Please try again.