Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Start to stub in a CStruct REPR.
- Loading branch information
Showing
3 changed files
with
237 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters