Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Start to stub in a CStruct REPR.
  • Loading branch information
jnthn committed Nov 24, 2011
1 parent 896015d commit 5899327
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 1 deletion.
204 changes: 204 additions & 0 deletions src/6model/reprs/CStruct.c
@@ -0,0 +1,204 @@
#define PARROT_IN_EXTENSION
#include "parrot/parrot.h"
#include "parrot/extend.h"
#include "../sixmodelobject.h"
#include "CStruct.h"

/* This representation's function pointer table. */
static REPROps *this_repr;

/* Some functions we have to get references to. */
static PMC * (* wrap_object_func) (PARROT_INTERP, void *obj);
static PMC * (* create_stable_func) (PARROT_INTERP, REPROps *REPR, PMC *HOW);

/* Creates a new type object of this representation, and associates it with
* the given HOW. */
static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
/* Create new object instance. */
CStructInstance *obj = mem_allocate_zeroed_typed(CStructInstance);

/* Build an STable. */
PMC *st_pmc = create_stable_func(interp, this_repr, HOW);
STable *st = STABLE_STRUCT(st_pmc);

/* Create type object and point it back at the STable. */
obj->common.stable = st_pmc;
st->WHAT = wrap_object_func(interp, obj);
PARROT_GC_WRITE_BARRIER(interp, st_pmc);

/* Flag it as a type object. */
MARK_AS_TYPE_OBJECT(st->WHAT);

return st->WHAT;
}

/* Creates a new instance based on the type object. */
static PMC * allocate(PARROT_INTERP, STable *st) {
CStructInstance *obj = mem_allocate_zeroed_typed(CStructInstance);
obj->common.stable = st->stable_pmc;
return wrap_object_func(interp, obj);
}

/* Initialize a new instance. */
static void initialize(PARROT_INTERP, STable *st, void *data) {
/* Nothing to do here. */
}

/* Copies to the body of one object to another. */
static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) {
CStructBody *src_body = (CStructBody *)src;
CStructBody *dest_body = (CStructBody *)dest;
/* XXX TODO */
}

/* Helper to die because this type doesn't support attributes. */
PARROT_DOES_NOT_RETURN
static void die_no_attrs(PARROT_INTERP) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct representation does not support attribute storage");
}

/* Gets the current value for an attribute. */
static PMC * get_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) {
die_no_attrs(interp);
}
static void * get_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) {
die_no_attrs(interp);
}

/* Binds the given value to the specified attribute. */
static void bind_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) {
die_no_attrs(interp);
}
static void bind_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, void *value) {
die_no_attrs(interp);
}

/* Gets the hint for the given attribute ID. */
static INTVAL hint_for(PARROT_INTERP, STable *st, PMC *class_handle, STRING *name) {
return NO_HINT;
}

/* Used with boxing. Sets an integer value, for representations that can hold
* one. */
static void set_int(PARROT_INTERP, STable *st, void *data, INTVAL value) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot box a native int");
}

/* Used with boxing. Gets an integer value, for representations that can
* hold one. */
static INTVAL get_int(PARROT_INTERP, STable *st, void *data) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot unbox to a native int");
}

/* Used with boxing. Sets a floating point value, for representations that can
* hold one. */
static void set_num(PARROT_INTERP, STable *st, void *data, FLOATVAL value) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot box a native num");
}

/* Used with boxing. Gets a floating point value, for representations that can
* hold one. */
static FLOATVAL get_num(PARROT_INTERP, STable *st, void *data) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot unbox to a native num");
}

/* Used with boxing. Sets a string value, for representations that can hold
* one. */
static void set_str(PARROT_INTERP, STable *st, void *data, STRING *value) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot box a native string");
}

/* Used with boxing. Gets a string value, for representations that can hold
* one. */
static STRING * get_str(PARROT_INTERP, STable *st, void *data) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot unbox to a native string");
}

/* Some objects serve primarily as boxes of others, inlining them. This gets
* gets the reference to such things, using the representation ID to distinguish
* them. */
static void * get_boxed_ref(PARROT_INTERP, STable *st, void *data, INTVAL repr_id) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct cannot box other types");
}

/* This Parrot-specific addition to the API is used to mark an object. */
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
CStructBody *body = (CStructBody *)data;
INTVAL i;
if (body->child_objs)
for (i = 0; i < body->num_child_objs; i++)
Parrot_gc_mark_PMC_alive(interp, body->child_objs[i]);
}

/* This is called to do any cleanup of resources when an object gets
* embedded inside another one. Never called on a top-level object. */
static void gc_cleanup(PARROT_INTERP, STable *st, void *data) {
CStructBody *body = (CStructBody *)data;
if (body->child_objs)
mem_sys_free(body->child_objs);
}

/* This Parrot-specific addition to the API is used to free an object. */
static void gc_free(PARROT_INTERP, PMC *obj) {
gc_cleanup(interp, STABLE(obj), OBJECT_BODY(obj));
mem_sys_free(PMC_data(obj));
PMC_data(obj) = NULL;
}

/* Gets the storage specification for this representation. */
static storage_spec get_storage_spec(PARROT_INTERP, STable *st) {
storage_spec spec;
spec.inlineable = STORAGE_SPEC_REFERENCE;
spec.boxed_primitive = STORAGE_SPEC_BP_NONE;
spec.can_box = 0;
return spec;
}

/* Checks if an attribute has been initialized. */
static INTVAL is_attribute_initialized(PARROT_INTERP, STable *st, void *data, PMC *ClassHandle, STRING *Name, INTVAL Hint) {
die_no_attrs(interp);
}

/* Initializes the CStruct representation. */
REPROps * CStruct_initialize(PARROT_INTERP,
PMC * (* wrap_object_func_ptr) (PARROT_INTERP, void *obj),
PMC * (* create_stable_func_ptr) (PARROT_INTERP, REPROps *REPR, PMC *HOW)) {
/* Stash away functions passed wrapping functions. */
wrap_object_func = wrap_object_func_ptr;
create_stable_func = create_stable_func_ptr;

/* Allocate and populate the representation function table. */
this_repr = mem_allocate_typed(REPROps);
this_repr->type_object_for = type_object_for;
this_repr->allocate = allocate;
this_repr->initialize = initialize;
this_repr->copy_to = copy_to;
this_repr->get_attribute_boxed = get_attribute_boxed;
this_repr->get_attribute_boxed = get_attribute_boxed;
this_repr->bind_attribute_boxed = bind_attribute_boxed;
this_repr->bind_attribute_ref = bind_attribute_ref;
this_repr->hint_for = hint_for;
this_repr->set_int = set_int;
this_repr->get_int = get_int;
this_repr->set_num = set_num;
this_repr->get_num = get_num;
this_repr->set_str = set_str;
this_repr->get_str = get_str;
this_repr->get_boxed_ref = get_boxed_ref;
this_repr->gc_mark = gc_mark;
this_repr->gc_free = gc_free;
this_repr->gc_cleanup = gc_cleanup;
this_repr->gc_mark_repr_data = NULL;
this_repr->gc_free_repr_data = NULL;
this_repr->get_storage_spec = get_storage_spec;
this_repr->is_attribute_initialized = is_attribute_initialized;
return this_repr;
}
31 changes: 31 additions & 0 deletions src/6model/reprs/CStruct.h
@@ -0,0 +1,31 @@
#ifndef CSTRUCT_H_GUARD
#define CSTRUCT_H_GUARD

/* The CStruct representation maintains a chunk of memory that it can
* always pass off to C land. If we in turn embed any strings, pointers
* to other CStruct REPR objects and so forth, we need to both keep the
* C-friendly bit of memory and a copy to the GC-able, 6model objects in
* sync. */
typedef struct {
/* GC-marked objects that our C structure points into. */
PMC **child_objs;
INTVAL num_child_objs;

/* This is not an actual pointer; instead it's just a marker we can
* use to get at the start of the data that we'll actually pass off
* to C land. */
void *cstruct;
} CStructBody;

/* This is how an instance with the CStruct representation looks. */
typedef struct {
SixModelObjectCommonalities common;
CStructBody body;
} CStructInstance;

/* Initializes the CStruct REPR. */
REPROps * CStruct_initialize(PARROT_INTERP,
PMC * (* wrap_object_func_ptr) (PARROT_INTERP, void *obj),
PMC * (* create_stable_func_ptr) (PARROT_INTERP, REPROps *REPR, PMC *HOW));

#endif
3 changes: 2 additions & 1 deletion tools/build/Makefile.in
Expand Up @@ -947,7 +947,8 @@ $(OPS_DIR)/$(DYNCALL_OPS)$(LOAD_EXT): $(OPS_DIR)/$(DYNCALL_OPS_SOURCE) $(DYNCALL
cd $(OPS_DIR) && $(OPS2C) C --dynamic $(DYNCALL_OPS_SOURCE)
cd $(OPS_DIR) && $(CC) -c @cc_o_out@$(DYNCALL_OPS)$(O) $(CINCLUDES) -I../../3rdparty/dyncall-0.6 $(CFLAGS) $(DYNCALL_OPS).c
cd src/6model/reprs && $(CC) -c @cc_o_out@NativeCall$(O) -I../../../$(PMC_DIR) -I../../../3rdparty/dyncall-0.6 $(CINCLUDES) $(CFLAGS) NativeCall.c
cd $(OPS_DIR) && $(LD) @ld_out@$(DYNCALL_OPS)$(LOAD_EXT) $(DYNCALL_OPS)$(O) ../6model/reprs/NativeCall$(O) ../../3rdparty/dyncall-0.6/dyncall/libdyncall_s$(A) ../../3rdparty/dyncall-0.6/dyncallback/libdyncallback_s$(A) ../../3rdparty/dyncall-0.6/dynload/libdynload_s$(A) $(LINKARGS)
cd src/6model/reprs && $(CC) -c @cc_o_out@CStruct$(O) -I../../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) CStruct.c
cd $(OPS_DIR) && $(LD) @ld_out@$(DYNCALL_OPS)$(LOAD_EXT) $(DYNCALL_OPS)$(O) ../6model/reprs/NativeCall$(O) ../6model/reprs/CStruct$(O) ../../3rdparty/dyncall-0.6/dyncall/libdyncall_s$(A) ../../3rdparty/dyncall-0.6/dyncallback/libdyncallback_s$(A) ../../3rdparty/dyncall-0.6/dynload/libdynload_s$(A) $(LINKARGS)

bootstrap-files: $(STAGE2_PBCS) src/stage2/$(CORE_SETTING_NQP)
$(PERL) tools/build/gen-bootstrap.pl src/Regex.pir >src/stage0/Regex-s0.pir
Expand Down

0 comments on commit 5899327

Please sign in to comment.