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
First cut of a P6bigint REPR, plus bigint library initialization code…
…. With this, we can declare a type with repr('bigint') and have it box/unbox native ints; it's allocating the libtommath big integer under the hood.- Loading branch information
Showing
4 changed files
with
246 additions
and
3 deletions.
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,217 @@ | ||
| /* This is the implementation of the P6bigint representation, which holds a | ||
| * libtommath big integer. */ | ||
|
|
||
| #define PARROT_IN_EXTENSION | ||
| #include "parrot/parrot.h" | ||
| #include "parrot/extend.h" | ||
| #include "../sixmodelobject.h" | ||
| #include "P6bigint.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. */ | ||
| P6bigintInstance *obj = mem_allocate_zeroed_typed(P6bigintInstance); | ||
|
|
||
| /* 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. */ | ||
| PObj_flag_SET(private0, st->WHAT); | ||
|
|
||
| return st->WHAT; | ||
| } | ||
|
|
||
| /* Creates a new instance based on the type object. */ | ||
| static PMC * instance_of(PARROT_INTERP, PMC *WHAT) { | ||
| P6bigintInstance *obj = mem_allocate_zeroed_typed(P6bigintInstance); | ||
| obj->common.stable = STABLE_PMC(WHAT); | ||
| mp_init(&obj->i); | ||
| mp_zero(&obj->i); | ||
| return wrap_object_func(interp, obj); | ||
| } | ||
|
|
||
| /* Checks if a given object is defined (from the point of view of the | ||
| * representation). */ | ||
| static INTVAL defined(PARROT_INTERP, PMC *obj) { | ||
| return !PObj_flag_TEST(private0, obj); | ||
| } | ||
|
|
||
| /* 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, | ||
| "P6bigint representation does not support attribute storage"); | ||
| } | ||
|
|
||
| /* Gets the current value for an attribute. */ | ||
| static PMC * get_attribute(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { | ||
| die_no_attrs(interp); | ||
| return PMCNULL; | ||
| } | ||
| static INTVAL get_attribute_int(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { | ||
| die_no_attrs(interp); | ||
| return 0; | ||
| } | ||
| static FLOATVAL get_attribute_num(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { | ||
| die_no_attrs(interp); | ||
| return 0.0; | ||
| } | ||
| static STRING * get_attribute_str(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { | ||
| die_no_attrs(interp); | ||
| return NULL; | ||
| } | ||
| static void * get_attribute_ref(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { | ||
| die_no_attrs(interp); | ||
| return NULL; | ||
| } | ||
|
|
||
| /* Binds the given value to the specified attribute. */ | ||
| static void bind_attribute(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) { | ||
| die_no_attrs(interp); | ||
| } | ||
| static void bind_attribute_int(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, INTVAL value) { | ||
| die_no_attrs(interp); | ||
| } | ||
| static void bind_attribute_num(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, FLOATVAL value) { | ||
| die_no_attrs(interp); | ||
| } | ||
| static void bind_attribute_str(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, STRING *value) { | ||
| die_no_attrs(interp); | ||
| } | ||
|
|
||
| /* Gets the hint for the given attribute ID. */ | ||
| static INTVAL hint_for(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name) { | ||
| return NO_HINT; | ||
| } | ||
|
|
||
| /* Clones the current object; simply copies the value. */ | ||
| static PMC * repr_clone(PARROT_INTERP, PMC *to_clone) { | ||
| P6bigintInstance *obj = mem_allocate_zeroed_typed(P6bigintInstance); | ||
| obj->common.stable = STABLE_PMC(to_clone); | ||
| mp_init_copy(&obj->i, &((P6bigintInstance *)PMC_data(to_clone))->i); | ||
| return wrap_object_func(interp, obj); | ||
| } | ||
|
|
||
| /* Used with boxing. Sets an integer value, for representations that can hold | ||
| * one. */ | ||
| static void set_int(PARROT_INTERP, PMC *obj, INTVAL value) { | ||
| mp_set_int(&((P6bigintInstance *)PMC_data(obj))->i, value); | ||
| } | ||
|
|
||
| /* Used with boxing. Gets an integer value, for representations that can | ||
| * hold one. */ | ||
| static INTVAL get_int(PARROT_INTERP, PMC *obj) { | ||
| return mp_get_int(&((P6bigintInstance *)PMC_data(obj))->i); | ||
| } | ||
|
|
||
| /* Used with boxing. Sets a floating point value, for representations that can | ||
| * hold one. */ | ||
| static void set_num(PARROT_INTERP, PMC *obj, FLOATVAL value) { | ||
| Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, | ||
| "P6bigint 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, PMC *obj) { | ||
| Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, | ||
| "P6bigint 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, PMC *obj, STRING *value) { | ||
| Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, | ||
| "P6bigint cannot box a native string"); | ||
| } | ||
|
|
||
| /* Used with boxing. Gets a string value, for representations that can hold | ||
| * one. */ | ||
| static STRING * get_str(PARROT_INTERP, PMC *obj) { | ||
| Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, | ||
| "P6bigint cannot unbox to a native string"); | ||
| } | ||
|
|
||
| /* This Parrot-specific addition to the API is used to mark an object. */ | ||
| static void gc_mark(PARROT_INTERP, PMC *obj) { | ||
| P6bigintInstance *instance = (P6bigintInstance *)PMC_data(obj); | ||
| if (!PMC_IS_NULL(instance->common.stable)) | ||
| Parrot_gc_mark_PMC_alive(interp, instance->common.stable); | ||
| if (!PMC_IS_NULL(instance->common.sc)) | ||
| Parrot_gc_mark_PMC_alive(interp, instance->common.sc); | ||
| } | ||
|
|
||
| /* This Parrot-specific addition to the API is used to free an object. */ | ||
| static void gc_free(PARROT_INTERP, PMC *obj) { | ||
| mp_clear(&((P6bigintInstance *)PMC_data(obj))->i); | ||
| 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_INLINED; | ||
| spec.bits = sizeof(mp_int) * 8; | ||
| spec.boxed_primitive = STORAGE_SPEC_BP_INT; | ||
| spec.can_box = STORAGE_SPEC_CAN_BOX_INT; | ||
| return spec; | ||
| } | ||
|
|
||
| /* Checks if an attribute has been initialized. */ | ||
| static INTVAL is_attribute_initialized(PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint) { | ||
| die_no_attrs(interp); | ||
| } | ||
|
|
||
| /* Initializes the P6bigint representation. */ | ||
| REPROps * P6bigint_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->instance_of = instance_of; | ||
| this_repr->defined = defined; | ||
| this_repr->get_attribute = get_attribute; | ||
| this_repr->get_attribute_int = get_attribute_int; | ||
| this_repr->get_attribute_num = get_attribute_num; | ||
| this_repr->get_attribute_str = get_attribute_str; | ||
| this_repr->get_attribute_ref = get_attribute_ref; | ||
| this_repr->bind_attribute = bind_attribute; | ||
| this_repr->bind_attribute_int = bind_attribute_int; | ||
| this_repr->bind_attribute_num = bind_attribute_num; | ||
| this_repr->bind_attribute_str = bind_attribute_str; | ||
| this_repr->hint_for = hint_for; | ||
| this_repr->clone = repr_clone; | ||
| 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->gc_mark = gc_mark; | ||
| this_repr->gc_free = gc_free; | ||
| this_repr->gc_mark_repr = NULL; | ||
| this_repr->gc_free_repr = 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,20 @@ | ||
| #ifndef P6BIGINT_H_GUARD | ||
| #define P6BIGINT_H_GUARD | ||
|
|
||
| #include "tommath.h" | ||
|
|
||
| /* This is how an instance with the P6bigint representation looks. */ | ||
| typedef struct { | ||
| /* The commonalities all objects have. */ | ||
| SixModelObjectCommonalities common; | ||
|
|
||
| /* Big integer storage slot. */ | ||
| mp_int i; | ||
| } P6bigintInstance; | ||
|
|
||
| /* Initializes the P6bigint REPR. */ | ||
| REPROps * P6bigint_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
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