/* This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef void (*__field_init_ptr)(void *);
static
void gpy_object_classobj_init_decl_attribs (const void * self,
gpy_object_attrib_t ** attribs)
{
int idx;
unsigned char * selfptr = (unsigned char *)self;
for (idx = 0; attribs[idx] != NULL; ++idx)
{
gpy_object_attrib_t * i = attribs[idx];
unsigned char * typeoffs = selfptr + (i->offset);
gpy_object_t ** offs = (gpy_object_t **) typeoffs;
if (i->addr)
{
gpy_object_t * attrib = (gpy_object_t *)i->addr;
*offs = i->addr;
}
else
*offs = NULL;
}
}
static
void gpy_object_classobj_methodattribs_addself (gpy_object_attrib_t ** attribs,
gpy_object_t * self)
{
int idx;
for (idx = 0; attribs[idx] != NULL; ++idx)
{
gpy_object_attrib_t * i = attribs[idx];
if (i->addr)
{
gpy_object_t * att = (gpy_object_t *) i->addr;
gpy_object_classmethod_inherit_self (att, self);
}
}
}
/* Class's internal type is generated by the compiler ...*/
gpy_object_t * gpy_object_classobj_new (gpy_typedef_t * type,
gpy_object_t ** args)
{
gpy_object_t * retval = NULL_OBJECT;
bool check = gpy_args_check_fmt (args, "A,i,s.");
gpy_assert (check);
gpy_object_attrib_t ** attribs = gpy_args_lit_parse_attrib_table (args[0]);
int size = gpy_args_lit_parse_int (args[1]);
char * ident = gpy_args_lit_parse_string (args[2]);
void * self = gpy_malloc (size);
gpy_object_classobj_init_decl_attribs (self, attribs);
gpy_typedef_t * ctype = gpy_malloc (sizeof (gpy_typedef_t));
ctype->identifier = ident;
ctype->state_size = size;
ctype->tp_new = type->tp_new;
ctype->tp_dealloc = type->tp_dealloc;
ctype->tp_print = type->tp_print;
ctype->tp_call = type->tp_call;
ctype->binary_protocol = type->binary_protocol;
ctype->members_defintion = attribs;
retval = gpy_create_object_decl (ctype, self);
/* we need to walk though the field_init here */
unsigned char * __field_init__ = gpy_rr_eval_attrib_reference (retval, "__field_init__");
gpy_object_t * field_init = *((gpy_object_t **) __field_init__);
unsigned char * codeaddr = gpy_object_classmethod_getaddr (field_init);
gpy_assert (codeaddr);
__field_init_ptr c = (__field_init_ptr)codeaddr;
c (self);
return retval;
}
void gpy_object_classobj_dealloc (gpy_object_t * self)
{
gpy_assert (self->T == TYPE_OBJECT_DECL);
gpy_object_state_t * object_state = self->o.object_state;
gpy_free (object_state->state);
object_state->state = NULL;
}
void gpy_object_classobj_print (gpy_object_t * self, FILE *fd, bool newline)
{
switch (self->T)
{
case TYPE_OBJECT_STATE:
fprintf (fd, "class object instance <%p> ", (void *)self);
break;
case TYPE_OBJECT_DECL:
fprintf (fd, "class object decl <%p> ", (void *)self);
break;
default:
fatal ("something went very wrong here!\n");
break;
}
if (newline)
fprintf (fd, "\n");
}
static
gpy_object_t ** gpy_object_classobj_setupargs (gpy_object_t ** args,
gpy_object_t * self)
{
int idx = 0;
gpy_object_t ** ptr;
for (ptr = args; *ptr != NULL; ++ptr)
idx ++;
gpy_object_t ** newargs = calloc (idx+2, sizeof (gpy_object_t *));
*newargs = self;
gpy_object_t ** newargsptr = newargs;
newargsptr++;
for (ptr = args; *ptr != NULL; ++ptr)
{
*newargsptr = *ptr;
newargsptr++;
}
*newargsptr = NULL;
return newargs;
}
gpy_object_t * gpy_object_classobj_call (gpy_object_t * self,
gpy_object_t ** args)
{
gpy_object_t * retval = NULL_OBJECT;
gpy_assert (self->T == TYPE_OBJECT_DECL);
gpy_typedef_t * type = self->o.object_state->definition;
void * oldstate = self->o.object_state->state;
void * newstate = malloc (type->state_size);
memcpy (newstate, oldstate, type->state_size);
retval = gpy_create_object_state (type, newstate);
gpy_assert (retval);
unsigned char * __init__ = gpy_rr_eval_attrib_reference (retval, "__init__");
gpy_object_t * init = *((gpy_object_t **) __init__);
gpy_assert (init->T == TYPE_OBJECT_DECL);
gpy_typedef_t * calltype = init->o.object_state->definition;
if (type->tp_call)
{
gpy_object_t ** arguments = gpy_object_classobj_setupargs (args, retval);
calltype->tp_call (init, arguments);
}
else
fatal ("name is not callable!\n");
return retval;
}
static struct gpy_typedef_t class_obj = {
"classobj",
0,
&gpy_object_classobj_new,
&gpy_object_classobj_dealloc,
&gpy_object_classobj_print,
&gpy_object_classobj_call,
NULL,
NULL
};
void gpy_obj_class_mod_init (gpy_vector_t * const vec)
{
gpy_vec_push (vec, &class_obj);
}