Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge reprapi2 into nom.
  • Loading branch information
jnthn committed Nov 1, 2011
2 parents 8780040 + 6daf5d1 commit 95135c3
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 92 deletions.
12 changes: 12 additions & 0 deletions src/Perl6/Metamodel/ContainerDescriptor.pm
Expand Up @@ -10,6 +10,18 @@ class Perl6::Metamodel::ContainerDescriptor {
method set_of($of) { $!of := $of }
method set_rw($rw) { $!rw := $rw }

method new(:$of, :$rw, :$name) {
my $cd := nqp::create(self);
$cd.BUILD($of, $rw, $name);
}

method BUILD($of, $rw, $name) {
$!of := $of;
$!rw := $rw;
$!name := $name;
self
}

method is_generic() {
$!of.HOW.archetypes.generic
}
Expand Down
26 changes: 13 additions & 13 deletions src/binder/bind.c
Expand Up @@ -89,16 +89,16 @@ box_type(Rakudo_BindVal bv) {
static PMC *
create_box(PARROT_INTERP, Rakudo_BindVal bv) {
PMC *box_type_obj = box_type(bv);
PMC *boxed = REPR(box_type_obj)->instance_of(interp, box_type_obj);
PMC *boxed = REPR(box_type_obj)->allocate(interp, STABLE(box_type_obj));
switch (bv.type) {
case BIND_VAL_INT:
REPR(boxed)->set_int(interp, boxed, bv.val.i);
REPR(boxed)->set_int(interp, STABLE(boxed), OBJECT_BODY(boxed), bv.val.i);
break;
case BIND_VAL_NUM:
REPR(boxed)->set_num(interp, boxed, bv.val.n);
REPR(boxed)->set_num(interp, STABLE(boxed), OBJECT_BODY(boxed), bv.val.n);
break;
case BIND_VAL_STR:
REPR(boxed)->set_str(interp, boxed, bv.val.s);
REPR(boxed)->set_str(interp, STABLE(boxed), OBJECT_BODY(boxed), bv.val.s);
break;
}
return boxed;
Expand All @@ -110,7 +110,7 @@ create_box(PARROT_INTERP, Rakudo_BindVal bv) {
PMC *
Rakudo_binding_parcel_from_rpa(PARROT_INTERP, PMC *rpa, PMC *fill) {
PMC *type = Rakudo_types_parcel_get();
PMC *parcel = REPR(type)->instance_of(interp, type);
PMC *parcel = REPR(type)->allocate(interp, STABLE(type));
VTABLE_set_attr_keyed(interp, parcel, type, STORAGE_str, rpa);

if (!PMC_IS_NULL(fill)) {
Expand All @@ -131,7 +131,7 @@ Rakudo_binding_parcel_from_rpa(PARROT_INTERP, PMC *rpa, PMC *fill) {
PMC *
Rakudo_binding_iter_from_rpa(PARROT_INTERP, PMC *rpa, PMC *list) {
PMC *type = Rakudo_types_listiter_get();
PMC *iter = REPR(type)->instance_of(interp, type);
PMC *iter = REPR(type)->allocate(interp, STABLE(type));
VTABLE_set_attr_keyed(interp, iter, type, REST_str, rpa);
VTABLE_set_attr_keyed(interp, iter, type, LIST_str, list);
return iter;
Expand All @@ -142,7 +142,7 @@ Rakudo_binding_iter_from_rpa(PARROT_INTERP, PMC *rpa, PMC *list) {
/* This function gets shared with perl6.ops for the perl6_list_from_rpa op. */
PMC *
Rakudo_binding_list_from_rpa(PARROT_INTERP, PMC *rpa, PMC *type, PMC *flattens) {
PMC *list = REPR(type)->instance_of(interp, type);
PMC *list = REPR(type)->allocate(interp, STABLE(type));
PMC *List = Rakudo_types_list_get();
if (!PMC_IS_NULL(rpa))
VTABLE_set_attr_keyed(interp, list, List, NEXTITER_str,
Expand Down Expand Up @@ -172,7 +172,7 @@ Rakudo_binding_create_lol(PARROT_INTERP, PMC *rpa) {
static PMC *
Rakudo_binding_create_hash(PARROT_INTERP, PMC *storage) {
PMC *type = Rakudo_types_hash_get();
PMC *hash = REPR(type)->instance_of(interp, type);
PMC *hash = REPR(type)->allocate(interp, STABLE(type));
VTABLE_set_attr_keyed(interp, hash, Rakudo_types_enummap_get(), STORAGE_str, storage);
return hash;
}
Expand Down Expand Up @@ -320,7 +320,7 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, Rakudo_Signature *sign
case SIG_ELEM_NATIVE_INT_VALUE:
if (spec.can_box & STORAGE_SPEC_CAN_BOX_INT) {
bv.type = BIND_VAL_INT;
bv.val.i = REPR(decont_value)->get_int(interp, decont_value);
bv.val.i = REPR(decont_value)->get_int(interp, STABLE(decont_value), OBJECT_BODY(decont_value));
}
else {
if (error)
Expand All @@ -332,7 +332,7 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, Rakudo_Signature *sign
case SIG_ELEM_NATIVE_NUM_VALUE:
if (spec.can_box & STORAGE_SPEC_CAN_BOX_NUM) {
bv.type = BIND_VAL_NUM;
bv.val.n = REPR(decont_value)->get_num(interp, decont_value);
bv.val.n = REPR(decont_value)->get_num(interp, STABLE(decont_value), OBJECT_BODY(decont_value));
}
else {
if (error)
Expand All @@ -344,7 +344,7 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, Rakudo_Signature *sign
case SIG_ELEM_NATIVE_STR_VALUE:
if (spec.can_box & STORAGE_SPEC_CAN_BOX_STR) {
bv.type = BIND_VAL_STR;
bv.val.s = REPR(decont_value)->get_str(interp, decont_value);
bv.val.s = REPR(decont_value)->get_str(interp, STABLE(decont_value), OBJECT_BODY(decont_value));
}
else {
if (error)
Expand Down Expand Up @@ -425,7 +425,7 @@ Rakudo_binding_bind_one_param(PARROT_INTERP, PMC *lexpad, Rakudo_Signature *sign

/* Also enforce definedness constraints. */
if (param->flags & SIG_ELEM_DEFINEDNES_CHECK) {
INTVAL defined = REPR(decont_value)->defined(interp, decont_value);
INTVAL defined = IS_CONCRETE(decont_value);
if (defined && param->flags & SIG_ELEM_UNDEFINED_ONLY) {
if (error)
*error = Parrot_sprintf_c(interp,
Expand Down Expand Up @@ -807,7 +807,7 @@ Rakudo_binding_bind(PARROT_INTERP, PMC *lexpad, PMC *sig_pmc, PMC *capture,
}
else {
PMC *captype = Rakudo_types_capture_get();
PMC *capsnap = REPR(captype)->instance_of(interp, captype);
PMC *capsnap = REPR(captype)->allocate(interp, STABLE(captype));
PMC *pos_args = pmc_new(interp, enum_class_ResizablePMCArray);
PMC *named_args = pmc_new(interp, enum_class_Hash);
INTVAL k;
Expand Down
11 changes: 7 additions & 4 deletions src/binder/container.c
Expand Up @@ -15,7 +15,7 @@ PMC *Rakudo_cont_decontainerize(PARROT_INTERP, PMC *var) {
ContainerSpec *spec;

/* Fast path for Perl 6 Scalar containers. */
if (STABLE(var)->WHAT == scalar_type && REPR(var)->defined(interp, var))
if (STABLE(var)->WHAT == scalar_type && IS_CONCRETE(var))
return ((Rakudo_Scalar *)PMC_data(var))->value;

/* Otherwise, fall back to the usual API. */
Expand Down Expand Up @@ -140,7 +140,8 @@ INTVAL Rakudo_cont_is_rw_scalar(PARROT_INTERP, PMC *check) {
/* Creates a new Scalar container with the associated container
* descriptor. */
PMC * Rakudo_cont_scalar_from_descriptor(PARROT_INTERP, PMC *descriptor) {
PMC *new_scalar = REPR(scalar_type)->instance_of(interp, scalar_type);
PMC *new_scalar = REPR(scalar_type)->allocate(interp, STABLE(scalar_type));
REPR(new_scalar)->initialize(interp, STABLE(new_scalar), OBJECT_BODY(new_scalar));
((Rakudo_Scalar *)PMC_data(new_scalar))->descriptor = descriptor;
PARROT_GC_WRITE_BARRIER(interp, new_scalar);
return new_scalar;
Expand All @@ -149,16 +150,18 @@ PMC * Rakudo_cont_scalar_from_descriptor(PARROT_INTERP, PMC *descriptor) {
/* Creates a new Scalar container with the associated container
* descriptor. */
PMC * Rakudo_cont_scalar_with_value_no_descriptor(PARROT_INTERP, PMC *value) {
PMC *new_scalar = REPR(scalar_type)->instance_of(interp, scalar_type);
PMC *new_scalar = REPR(scalar_type)->allocate(interp, STABLE(scalar_type));
REPR(new_scalar)->initialize(interp, STABLE(new_scalar), OBJECT_BODY(new_scalar));
((Rakudo_Scalar *)PMC_data(new_scalar))->value = value;
PARROT_GC_WRITE_BARRIER(interp, new_scalar);
return new_scalar;
}

/* Creates and populates a new container descriptor. */
PMC * Rakudo_create_container_descriptor(PARROT_INTERP, PMC *type, PMC *of, INTVAL rw, STRING *name) {
PMC *result = REPR(type)->instance_of(interp, type);
PMC *result = REPR(type)->allocate(interp, STABLE(type));
Rakudo_ContainerDescriptor *desc = (Rakudo_ContainerDescriptor *)PMC_data(result);
REPR(result)->initialize(interp, STABLE(result), OBJECT_BODY(result));
desc->of = of;
desc->rw = rw;
desc->name = name;
Expand Down
10 changes: 5 additions & 5 deletions src/binder/multidispatch.c
Expand Up @@ -353,7 +353,7 @@ find_in_cache(PARROT_INTERP, Rakudo_md_cache *cache, PMC *capture, INTVAL num_ar
for (i = 0; i < num_args; i++) {
if (pc_positionals[i].type == BIND_VAL_OBJ) {
PMC *arg = Rakudo_cont_decontainerize(interp, pc_positionals[i].u.p);
arg_tup[i] = STABLE(arg)->type_cache_id | (REPR(arg)->defined(interp, arg) ? 1 : 0);
arg_tup[i] = STABLE(arg)->type_cache_id | (IS_CONCRETE(arg) ? 1 : 0);
}
else {
arg_tup[i] = (pc_positionals[i].type << 1) | 1;
Expand Down Expand Up @@ -415,7 +415,7 @@ add_to_cache(PARROT_INTERP, Rakudo_md_cache *cache, PMC *capture, INTVAL num_arg
for (i = 0; i < num_args; i++) {
if (pc_positionals[i].type == BIND_VAL_OBJ) {
PMC *arg = Rakudo_cont_decontainerize(interp, pc_positionals[i].u.p);
arg_tup[i] = STABLE(arg)->type_cache_id | (REPR(arg)->defined(interp, arg) ? 1 : 0);
arg_tup[i] = STABLE(arg)->type_cache_id | (IS_CONCRETE(arg) ? 1 : 0);
}
else {
arg_tup[i] = (pc_positionals[i].type << 1) | 1;
Expand Down Expand Up @@ -482,7 +482,7 @@ static STRING* dump_signature(PARROT_INTERP, STRING *so_far, PMC *sub) {
perl_meth = VTABLE_find_method(interp, sig_obj, perl_name);
Parrot_ext_call(interp, perl_meth, "Pi->P", sig_obj, &sig_perl);
so_far = Parrot_str_concat(interp, so_far,
REPR(sig_perl)->get_str(interp, sig_perl));
REPR(sig_perl)->get_str(interp, STABLE(sig_perl), OBJECT_BODY(sig_perl)));
so_far = Parrot_str_concat(interp, so_far, newline);
return so_far;
}
Expand Down Expand Up @@ -540,7 +540,7 @@ static PMC* find_best_candidate(PARROT_INTERP, Rakudo_md_candidate_info **candid
INTVAL i;

for (i = 0; i < possibles_count; i++) {
interp->current_cont = NEED_CONTINUATION;
interp->current_cont = (PMC *)NEED_CONTINUATION;
Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), NULL);

/* First, if there's a required named parameter and it was
Expand Down Expand Up @@ -682,7 +682,7 @@ static PMC* find_best_candidate(PARROT_INTERP, Rakudo_md_candidate_info **candid
break;
}
else if ((*cur_candidate)->type_flags[i] & DEFCON_MASK) {
INTVAL defined = got_prim != BIND_VAL_OBJ || REPR(param)->defined(interp, param);
INTVAL defined = got_prim != BIND_VAL_OBJ || IS_CONCRETE(param);
INTVAL desired = (*cur_candidate)->type_flags[i] & DEFCON_MASK;
if ((defined && desired == DEFCON_UNDEFINED) ||
(!defined && desired == DEFCON_DEFINED)) {
Expand Down
119 changes: 73 additions & 46 deletions src/binder/sixmodelobject.h
Expand Up @@ -14,6 +14,13 @@ typedef struct {
PMC *sc; /* Serialization context. */
} SixModelObjectCommonalities;

/* An example object, mostly used to compute the offset of the data part of
* a 6model object. */
typedef struct {
SixModelObjectCommonalities common;
void *data;
} SixModelObjectStooge;

/* This is used to identify an attribute for various types of cache. */
typedef struct {
PMC *class_handle; /* Class handle */
Expand Down Expand Up @@ -46,7 +53,7 @@ typedef struct {
* a type check cache we treat it as definitive. However, it's possible to
* declare that in the case the type check cache has no entry we should fall
* back to asking the .HOW.type_check method (set TYPE_CHECK_CACHE_THEN_METHOD).
* While a normal type check asks a value if it suppots another type, the
* While a normal type check asks a value if it supports another type, the
* TYPE_CHECK_NEEDS_ACCEPTS flag results in a call to .accepts_type on the
* HOW of the thing we're checking the value against, giving it a chance to
* decide answer. */
Expand Down Expand Up @@ -125,6 +132,9 @@ typedef struct {

/* Parrot-specific set of v-table to object method mappings. */
AttributeIdentifier *parrot_vtable_handler_mapping;

/* The PMC that wraps this s-table. */
PMC *stable_pmc;
} STable;

/* A representation is what controls the layout of an object and storage of
Expand All @@ -143,85 +153,97 @@ struct SixModel_REPROps {
* representation instance if needed. */
PMC * (*type_object_for) (PARROT_INTERP, PMC *HOW);

/* Creates a new instance based on the type object. */
PMC * (*instance_of) (PARROT_INTERP, PMC *WHAT);

/* Checks if a given object is defined (from the point of
* view of the representation). */
INTVAL (*defined) (PARROT_INTERP, PMC *Obj);

/* Gets the current value for an object attribute. */
PMC * (*get_attribute) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint);

/* Gets the current value for a native int attribute. */
INTVAL (*get_attribute_int) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint);

/* Gets the current value for a native num attribute. */
FLOATVAL (*get_attribute_num) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint);

/* Gets the current value for a native str attribute. */
STRING * (*get_attribute_str) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint);
/* Allocates a new, but uninitialized object, based on the
* specified s-table. */
PMC * (*allocate) (PARROT_INTERP, STable *st);

/* Binds the given object value to the specified attribute. */
void (*bind_attribute) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint, PMC *Value);

/* Binds the given int value to the specified attribute. */
void (*bind_attribute_int) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint, INTVAL Value);

/* Binds the given num value to the specified attribute. */
void (*bind_attribute_num) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint, FLOATVAL Value);

/* Binds the given str value to the specified attribute. */
void (*bind_attribute_str) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint, STRING *Value);
/* Used to initialize the body of an object representing the type
* describe by the specified s-table. DATA points to the body. It
* may recursively call initialize for any flattened objects. */
void (*initialize) (PARROT_INTERP, STable *st, void *data);

/* For the given type, copies the object data from the source memory
* location to the destination one. Note that it may actually be more
* involved than a straightforward bit of copying; what's important is
* that the representation knows about that. Note that it may have to
* call copy_to recursively on representations of any flattened objects
* within its body. */
void (*copy_to) (PARROT_INTERP, STable *st, void *src, void *dest);

/* Gets the current value for an object attribute. For non-flattened
* objects - that is, reference types - this just returns the object
* stored in the attribute. For the flattened case, this will auto-box. */
PMC * (*get_attribute_boxed) (PARROT_INTERP, STable *st, void *data,
PMC *class_handle, STRING *name, INTVAL hint);

/* Gets a reference to the memory location of an attribute. Note
* that this is only valid so long as the object itself is alive. */
void * (*get_attribute_ref) (PARROT_INTERP, STable *st, void *data,
PMC *class_handle, STRING *name, INTVAL hint);

/* Binds the given object value to the specified attribute. If it's
* a reference type attribute, this just simply sets the value in
* place. If instead it's some other flattened in representation, then
* the value should be a boxed form of the data to store.*/
void (*bind_attribute_boxed) (PARROT_INTERP, STable *st, void *data,
PMC *class_handle, STRING *name, INTVAL hint, PMC *value);

/* Binds a flattened in attribute to the value at the passed reference.
* Like with the get_attribute_ref function, presumably the thing calling
* this knows about the type of the attribute it is supplying data for.
* copy_to will be used to copy the data in to place. */
void (*bind_attribute_ref) (PARROT_INTERP, STable *st, void *data,
PMC *class_handle, STRING *name, INTVAL hint, void *value);

/* Gets the hint for the given attribute ID. */
INTVAL (*hint_for) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name);
INTVAL (*hint_for) (PARROT_INTERP, STable *st, PMC *class_handle, STRING *name);

/* Clones the object, optionally cloning any containers in its
* attributes. */
PMC * (*clone) (PARROT_INTERP, PMC *to_clone);

/* Used with boxing. Sets an integer value, for representations that
* can hold one. */
void (*set_int) (PARROT_INTERP, PMC *Object, INTVAL Value);
void (*set_int) (PARROT_INTERP, STable *st, void *data, INTVAL value);

/* Used with boxing. Gets an integer value, for representations that
* can hold one. */
INTVAL (*get_int) (PARROT_INTERP, PMC *Object);
INTVAL (*get_int) (PARROT_INTERP, STable *st, void *data);

/* Used with boxing. Sets a floating point value, for representations that
* can hold one. */
void (*set_num) (PARROT_INTERP, PMC *Object, FLOATVAL Value);
void (*set_num) (PARROT_INTERP, STable *st, void *data, FLOATVAL value);

/* Used with boxing. Gets a floating point value, for representations that
* can hold one. */
FLOATVAL (*get_num) (PARROT_INTERP, PMC *Object);
FLOATVAL (*get_num) (PARROT_INTERP, STable *st, void *data);

/* Used with boxing. Sets a string value, for representations that
* can hold one. */
void (*set_str) (PARROT_INTERP, PMC *Object, STRING *Value);
void (*set_str) (PARROT_INTERP, STable *st, void *data, STRING *value);

/* Used with boxing. Gets a string value, for representations that
* can hold one. */
STRING * (*get_str) (PARROT_INTERP, PMC *Object);
STRING * (*get_str) (PARROT_INTERP, STable *st, void *data);

/* This Parrot-specific addition to the API is used to mark an object. */
void (*gc_mark) (PARROT_INTERP, PMC *Object);
void (*gc_mark) (PARROT_INTERP, STable *st, void *data);

/* This Parrot-specific addition to the API is used to free an object. */
void (*gc_free) (PARROT_INTERP, PMC *Object);
void (*gc_free) (PARROT_INTERP, PMC *object);

/* This is called to do any cleanup of resources when an object gets
* embedded inside another one. Never called on a top-level object. */
void (*gc_cleanup) (PARROT_INTERP, STable *st, void *data);

/* This Parrot-specific addition to the API is used to mark a REPR instance. */
void (*gc_mark_repr) (PARROT_INTERP, STable *st);
void (*gc_mark_repr_data) (PARROT_INTERP, STable *st);

/* This Parrot-specific addition to the API is used to free a REPR instance. */
void (*gc_free_repr) (PARROT_INTERP, STable *st);
void (*gc_free_repr_data) (PARROT_INTERP, STable *st);

/* Gets the storage specification for this representation. */
storage_spec (*get_storage_spec) (PARROT_INTERP, STable *st);

/* Checks if an attribute has been initialized. */
INTVAL (*is_attribute_initialized) (PARROT_INTERP, PMC *Object, PMC *ClassHandle, STRING *Name, INTVAL Hint);
INTVAL (*is_attribute_initialized) (PARROT_INTERP, STable *st, void *data,
PMC *class_handle, STRING *name, INTVAL hint);

/* Handles an object changing its type. The representation is responsible
* for doing any changes to the underlying data structure, and may reject
Expand All @@ -243,6 +265,11 @@ struct SixModel_REPROps {
#define SC_PMC(o) (((SixModelObjectCommonalities *)PMC_data(o))->sc)
#define STABLE_STRUCT(p) ((STable *)PMC_data(p))
#define REPR(o) (STABLE(o)->REPR)
#define OBJECT_BODY(o) (&(((SixModelObjectStooge *)PMC_data(o))->data))

/* Macro for getting/setting type-objectness. */
#define IS_CONCRETE(o) (!PObj_flag_TEST(private0, (o)))
#define MARK_AS_TYPE_OBJECT(o) PObj_flag_SET(private0, (o))

/* Object model initialization. */
void SixModelObject_initialize(PARROT_INTERP, PMC **knowhow, PMC **knowhow_attribute);
Expand Down

0 comments on commit 95135c3

Please sign in to comment.