Exemple #1
0
/* Introspects the methods. */
static void methods(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *type_obj, *method_table;
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    type_obj = MVM_args_get_pos_obj(tc, &arg_ctx, 1, MVM_ARG_REQUIRED).arg.o;
    MVM_args_proc_cleanup(tc, &arg_ctx);
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");
    method_table = ((MVMKnowHOWREPR *)self)->body.methods;
    MVM_args_set_result_obj(tc, method_table, MVM_RETURN_CURRENT_FRAME);
}
Exemple #2
0
/* Adds a method. */
static void add_method(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *method, *method_table;
    MVMString *name;

    /* Get arguments. */
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    MVM_args_checkarity(tc, &arg_ctx, 4, 4);
    self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    name     = MVM_args_get_pos_str(tc, &arg_ctx, 2, MVM_ARG_REQUIRED).arg.s;
    method   = MVM_args_get_pos_obj(tc, &arg_ctx, 3, MVM_ARG_REQUIRED).arg.o;
    MVM_args_proc_cleanup(tc, &arg_ctx);
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");

    /* Add to method table. */
    method_table = ((MVMKnowHOWREPR *)self)->body.methods;
    MVM_repr_bind_key_o(tc, method_table, name, method);

    /* Return added method as result. */
    MVM_args_set_result_obj(tc, method, MVM_RETURN_CURRENT_FRAME);
}
Exemple #3
0
static void Str_say(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
  MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
  MVM_args_proc_init(tc, &arg_ctx, callsite, args);
  MVMObject* self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
  MVM_args_proc_cleanup(tc, &arg_ctx);

  MVM_gc_root_temp_push(tc, (MVMCollectable **)&self);

  MVMString * self_s = REPR(self)->box_funcs->get_str(tc, STABLE(self), self, OBJECT_BODY(self));
  MVM_string_say(tc, self_s);

  MVM_gc_root_temp_pop_n(tc, 1);
}
Exemple #4
0
/* KnowHOW.new_type method. Creates a new type with this HOW as its meta-object. */
static void new_type(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *HOW, *type_object, *BOOTHash, *stash;
    MVMArgInfo repr_arg, name_arg;
    MVMString *repr_name, *name;
    const MVMREPROps *repr_to_use;
    MVMInstance       *instance = tc->instance;

    /* Get arguments. */
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
    self = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    repr_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.repr, MVM_ARG_OPTIONAL);
    name_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.name, MVM_ARG_OPTIONAL);
    MVM_args_proc_cleanup(tc, &arg_ctx);
    if (REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object with REPR KnowHOWREPR");

    /* See if we have a representation name; if not default to P6opaque. */
    repr_name = repr_arg.exists ? repr_arg.arg.s : instance->str_consts.P6opaque;
    repr_to_use = MVM_repr_get_by_name(tc, repr_name);

    MVM_gc_root_temp_push(tc, (MVMCollectable **)&name_arg);

    /* We first create a new HOW instance. */
    HOW = REPR(self)->allocate(tc, STABLE(self));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&HOW);

    /* Create a new type object of the desired REPR. (Note that we can't
     * default to KnowHOWREPR here, since it doesn't know how to actually
     * store attributes, it's just for bootstrapping knowhow's. */
    type_object = repr_to_use->type_object_for(tc, HOW);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_object);

    /* This may move name_arg.arg.s so do it first: */
    REPR(HOW)->initialize(tc, STABLE(HOW), HOW, OBJECT_BODY(HOW));
    /* See if we were given a name; put it into the meta-object if so. */
    name = name_arg.exists ? name_arg.arg.s : instance->str_consts.anon;
    MVM_ASSIGN_REF(tc, &(HOW->header), ((MVMKnowHOWREPR *)HOW)->body.name, name);

    /* Set .WHO to an empty hash. */
    BOOTHash = tc->instance->boot_types.BOOTHash;
    stash = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&stash);
    MVM_ASSIGN_REF(tc, &(STABLE(type_object)->header), STABLE(type_object)->WHO, stash);

    /* Return the type object. */
    MVM_args_set_result_obj(tc, type_object, MVM_RETURN_CURRENT_FRAME);

    MVM_gc_root_temp_pop_n(tc, 4);
}
Exemple #5
0
static void File_eof(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
  MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
  MVM_args_proc_init(tc, &arg_ctx, callsite, args);
  MVMObject* self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
  MVM_args_proc_cleanup(tc, &arg_ctx);

  MVM_gc_root_temp_push(tc, (MVMCollectable **)&self);

  MVMint64 result = MVM_file_eof(tc, self);

  MVM_args_set_result_int(tc, result, MVM_RETURN_CURRENT_FRAME);

  MVM_gc_root_temp_pop_n(tc, 1);
}
Exemple #6
0
/* Adds an method. */
static void add_attribute(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *attr, *attributes;

    /* Get arguments. */
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    MVM_args_checkarity(tc, &arg_ctx, 3, 3);
    self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    attr     = MVM_args_get_pos_obj(tc, &arg_ctx, 2, MVM_ARG_REQUIRED).arg.o;
    MVM_args_proc_cleanup(tc, &arg_ctx);

    /* Ensure we have the required representations. */
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");
    if (REPR(attr)->ID != MVM_REPR_ID_KnowHOWAttributeREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW attributes must use KnowHOWAttributeREPR");

    /* Add to method table. */
    attributes = ((MVMKnowHOWREPR *)self)->body.attributes;
    MVM_repr_push_o(tc, attributes, attr);

    /* Return added attribute as result. */
    MVM_args_set_result_obj(tc, attr, MVM_RETURN_CURRENT_FRAME);
}
Exemple #7
0
static void Str_length(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
  MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
  MVM_args_proc_init(tc, &arg_ctx, callsite, args);
  MVMObject* self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
  MVM_args_proc_cleanup(tc, &arg_ctx);

  MVM_gc_root_temp_push(tc, (MVMCollectable **)&self);

  MVMString * self_s = REPR(self)->box_funcs->get_str(tc, STABLE(self), self, OBJECT_BODY(self));

  MVMint64 length = NUM_GRAPHS((MVMString*)self_s);

  MVM_args_set_result_int(tc, length, MVM_RETURN_CURRENT_FRAME);

  MVM_gc_root_temp_pop_n(tc, 1);
}
Exemple #8
0
/* Composes the meta-object. */
static void compose(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *type_obj, *method_table, *attributes, *BOOTArray, *BOOTHash,
              *repr_info_hash, *repr_info, *type_info, *attr_info_list, *parent_info;
    MVMuint64   num_attrs, i;
    MVMInstance *instance = tc->instance;

    /* Get arguments. */
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    MVM_args_checkarity(tc, &arg_ctx, 2, 2);
    self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    type_obj = MVM_args_get_pos_obj(tc, &arg_ctx, 1, MVM_ARG_REQUIRED).arg.o;
    MVM_args_proc_cleanup(tc, &arg_ctx);
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");

    /* Fill out STable. */
    method_table = ((MVMKnowHOWREPR *)self)->body.methods;
    MVM_ASSIGN_REF(tc, &(STABLE(type_obj)->header), STABLE(type_obj)->method_cache, method_table);
    STABLE(type_obj)->mode_flags              = MVM_METHOD_CACHE_AUTHORITATIVE;
    STABLE(type_obj)->type_check_cache_length = 1;
    STABLE(type_obj)->type_check_cache        = MVM_malloc(sizeof(MVMObject *));
    MVM_ASSIGN_REF(tc, &(STABLE(type_obj)->header), STABLE(type_obj)->type_check_cache[0], type_obj);
    attributes = ((MVMKnowHOWREPR *)self)->body.attributes;

    /* Next steps will allocate, so make sure we keep hold of the type
     * object and ourself. */
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attributes);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_obj);

    /* Use any attribute information to produce attribute protocol
     * data. The protocol consists of an array... */
    BOOTArray = instance->boot_types.BOOTArray;
    BOOTHash = instance->boot_types.BOOTHash;
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&BOOTArray);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&BOOTHash);
    repr_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&repr_info);

    /* ...which contains an array per MRO entry (just us)... */
    type_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_info);
    MVM_repr_push_o(tc, repr_info, type_info);

    /* ...which in turn contains this type... */
    MVM_repr_push_o(tc, type_info, type_obj);

    /* ...then an array of hashes per attribute... */
    attr_info_list = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_info_list);
    MVM_repr_push_o(tc, type_info, attr_info_list);
    num_attrs = REPR(attributes)->elems(tc, STABLE(attributes),
        attributes, OBJECT_BODY(attributes));
    for (i = 0; i < num_attrs; i++) {
        MVMObject *attr_info = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
        MVMKnowHOWAttributeREPR *attribute = (MVMKnowHOWAttributeREPR *)
            MVM_repr_at_pos_o(tc, attributes, i);
        MVMROOT(tc, attr_info, {
            MVMROOT(tc, attribute, {
                if (REPR((MVMObject *)attribute)->ID != MVM_REPR_ID_KnowHOWAttributeREPR)
                    MVM_exception_throw_adhoc(tc, "KnowHOW attributes must use KnowHOWAttributeREPR");

                MVM_repr_init(tc, attr_info);
                MVM_repr_bind_key_o(tc, attr_info, instance->str_consts.name, (MVMObject *)attribute->body.name);
                MVM_repr_bind_key_o(tc, attr_info, instance->str_consts.type, attribute->body.type);
                if (attribute->body.box_target) {
                    /* Merely having the key serves as a "yes". */
                    MVM_repr_bind_key_o(tc, attr_info, instance->str_consts.box_target, attr_info);
                }

                MVM_repr_push_o(tc, attr_info_list, attr_info);
            });
        });
Exemple #9
0
/* Composes the meta-object. */
static void compose(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *type_obj, *method_table, *attributes, *BOOTArray, *BOOTHash,
              *repr_info_hash, *repr_info, *type_info, *attr_info_list, *parent_info;
    MVMint64   num_attrs, i;
    
    /* Get arguments. */
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    self     = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    type_obj = MVM_args_get_pos_obj(tc, &arg_ctx, 1, MVM_ARG_REQUIRED).arg.o;
    MVM_args_proc_cleanup(tc, &arg_ctx);
    if (!self || !IS_CONCRETE(self) || REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object instance with REPR KnowHOWREPR");
    
    /* Fill out STable. */
    method_table = ((MVMKnowHOWREPR *)self)->body.methods;
    MVM_ASSIGN_REF(tc, STABLE(type_obj), STABLE(type_obj)->method_cache, method_table);
    STABLE(type_obj)->mode_flags              = MVM_METHOD_CACHE_AUTHORITATIVE;
    STABLE(type_obj)->type_check_cache_length = 1;
    STABLE(type_obj)->type_check_cache        = malloc(sizeof(MVMObject *));
    MVM_ASSIGN_REF(tc, STABLE(type_obj), STABLE(type_obj)->type_check_cache[0], type_obj);
    
    /* Next steps will allocate, so make sure we keep hold of the type
     * object and ourself. */
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&self);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_obj);
    
    /* Use any attribute information to produce attribute protocol
     * data. The protocol consists of an array... */
    BOOTArray = tc->instance->boot_types->BOOTArray;
    BOOTHash = tc->instance->boot_types->BOOTHash;
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&BOOTArray);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&BOOTHash);
    repr_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&repr_info);
    REPR(repr_info)->initialize(tc, STABLE(repr_info), repr_info, OBJECT_BODY(repr_info));
    
    /* ...which contains an array per MRO entry (just us)... */
    type_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_info);
    REPR(type_info)->initialize(tc, STABLE(type_info), type_info, OBJECT_BODY(type_info));
    MVM_repr_push_o(tc, repr_info, type_info);
        
    /* ...which in turn contains this type... */
    MVM_repr_push_o(tc, type_info, type_obj);
    
    /* ...then an array of hashes per attribute... */
    attr_info_list = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_info_list);
    REPR(attr_info_list)->initialize(tc, STABLE(attr_info_list), attr_info_list,
        OBJECT_BODY(attr_info_list));
    MVM_repr_push_o(tc, type_info, attr_info_list);
    attributes = ((MVMKnowHOWREPR *)self)->body.attributes;
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attributes);
    num_attrs = REPR(attributes)->elems(tc, STABLE(attributes),
        attributes, OBJECT_BODY(attributes));
    for (i = 0; i < num_attrs; i++) {
        MVMObject *attr_info = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
        MVMKnowHOWAttributeREPR *attribute = (MVMKnowHOWAttributeREPR *)
            MVM_repr_at_pos_o(tc, attributes, i);
        MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_info);
        MVM_gc_root_temp_push(tc, (MVMCollectable **)&attribute);
        if (REPR((MVMObject *)attribute)->ID != MVM_REPR_ID_KnowHOWAttributeREPR)
            MVM_exception_throw_adhoc(tc, "KnowHOW attributes must use KnowHOWAttributeREPR");
        
        REPR(attr_info)->initialize(tc, STABLE(attr_info), attr_info,
            OBJECT_BODY(attr_info));
        REPR(attr_info)->ass_funcs->bind_key_boxed(tc, STABLE(attr_info),
            attr_info, OBJECT_BODY(attr_info), (MVMObject *)str_name, (MVMObject *)attribute->body.name);
        REPR(attr_info)->ass_funcs->bind_key_boxed(tc, STABLE(attr_info),
            attr_info, OBJECT_BODY(attr_info), (MVMObject *)str_type, attribute->body.type);
        if (attribute->body.box_target) {
            /* Merely having the key serves as a "yes". */
            REPR(attr_info)->ass_funcs->bind_key_boxed(tc, STABLE(attr_info),
                attr_info, OBJECT_BODY(attr_info), (MVMObject *)str_box_target, attr_info);
        }
        
        MVM_repr_push_o(tc, attr_info_list, attr_info);
        MVM_gc_root_temp_pop_n(tc, 2);
    }
    
    /* ...followed by a list of parents (none). */
    parent_info = REPR(BOOTArray)->allocate(tc, STABLE(BOOTArray));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&parent_info);
    REPR(parent_info)->initialize(tc, STABLE(parent_info), parent_info,
        OBJECT_BODY(parent_info));
    MVM_repr_push_o(tc, type_info, parent_info);
    
    /* Finally, this all goes in a hash under the key 'attribute'. */
    repr_info_hash = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&repr_info_hash);
    REPR(repr_info_hash)->initialize(tc, STABLE(repr_info_hash), repr_info_hash, OBJECT_BODY(repr_info_hash));
    REPR(repr_info_hash)->ass_funcs->bind_key_boxed(tc, STABLE(repr_info_hash),
            repr_info_hash, OBJECT_BODY(repr_info_hash), (MVMObject *)str_attribute, repr_info);

    /* Compose the representation using it. */
    REPR(type_obj)->compose(tc, STABLE(type_obj), repr_info_hash);
    
    /* Clear temporary roots. */
    MVM_gc_root_temp_pop_n(tc, 10);
    
    /* Return type object. */
    MVM_args_set_result_obj(tc, type_obj, MVM_RETURN_CURRENT_FRAME);
}