示例#1
0
文件: ops.c 项目: Arcterus/MoarVM
/* returns the codepoint (could be a negative synthetic) at a given index of the string */
MVMint64 MVM_string_get_codepoint_at(MVMThreadContext *tc, MVMString *a, MVMint64 index) {
    MVMStringIndex agraphs;

    if (!IS_CONCRETE((MVMObject *)a)) {
        MVM_exception_throw_adhoc(tc, "codepoint_at needs a concrete string");
    }

    agraphs = NUM_GRAPHS(a);

    if (index < 0 || index >= agraphs)
        MVM_exception_throw_adhoc(tc, "Invalid string index: max %lld, got %lld",
            agraphs - 1, index);
    return (MVMint64)MVM_string_get_codepoint_at_nocheck(tc, a, index);
}
示例#2
0
文件: ops.c 项目: bingos/MoarVM
/* Returns a substring of the given string */
MVMString * MVM_string_substring(MVMThreadContext *tc, MVMString *a, MVMint64 start, MVMint64 length) {
    MVMString *result;
    MVMStrand *strands;
    MVMStringIndex agraphs = NUM_GRAPHS(a);
    
    if (start < 0) {
        start += agraphs;
        if (start < 0)
            start = 0;
    }
    
    if (!IS_CONCRETE((MVMObject *)a)) {
        MVM_exception_throw_adhoc(tc, "Substring needs a concrete string");
    }
    
    if (start > agraphs)
        start = agraphs;
        
    if (length == -1) /* -1 signifies go to the end of the string */
        length = agraphs - start;
    
    if (length < 0)
        MVM_exception_throw_adhoc(tc, "Substring length (%lld) cannot be negative", length);
    
    if (start + length > agraphs)
        length = agraphs - start;
    
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&a);
    result = (MVMString *)REPR(a)->allocate(tc, STABLE(a));
    MVM_gc_root_temp_pop(tc);
    
    strands = result->body.strands = calloc(sizeof(MVMStrand), 2);
    /* if we're substringing a substring, substring the same one */
    if (IS_ONE_STRING_ROPE(a)) {
        strands->string_offset = (MVMStringIndex)start + a->body.strands->string_offset;
        strands->string = a->body.strands->string;
    }
    else {
        strands->string_offset = (MVMStringIndex)start;
        strands->string = a;
    }
    /* result->body.codes  = 0; /* Populate this lazily. */
    result->body.flags = MVM_STRING_TYPE_ROPE;
    result->body.num_strands = 1;
    strands[1].graphs = length;
    _STRAND_DEPTH(result) = STRAND_DEPTH(strands->string) + 1;
    
    return result;
}
示例#3
0
文件: str.c 项目: tokuhirom/kiji
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);
}
示例#4
0
文件: ops.c 项目: bingos/MoarVM
/* Compares two strings for equality. */
MVMint64 MVM_string_equal(MVMThreadContext *tc, MVMString *a, MVMString *b) {
    if (NUM_GRAPHS(a) != NUM_GRAPHS(b))
        return 0;
    return MVM_string_equal_at(tc, a, b, 0);
}
示例#5
0
/* Set the line separator. */
void MVM_io_syncstream_set_separator(MVMThreadContext *tc, MVMOSHandle *h, MVMString *sep) {
    /* For now, take last character. */
    MVMIOSyncStreamData *data = (MVMIOSyncStreamData *)h->body.data;
    data->sep = (MVMCodepoint32)MVM_string_get_codepoint_at(tc, sep, NUM_GRAPHS(sep) - 1);
}
示例#6
0
文件: ascii.c 项目: dagurval/MoarVM
/* Encodes the specified string to ASCII.  */
MVMuint8 * MVM_string_ascii_encode(MVMThreadContext *tc, MVMString *str, MVMuint64 *output_size) {
    return MVM_string_ascii_encode_substr(tc, str, output_size, 0, NUM_GRAPHS(str));
}
示例#7
0
void MVM_coerce_istrue(MVMThreadContext *tc, MVMObject *obj, MVMRegister *res_reg,
                       MVMuint8 *true_addr, MVMuint8 *false_addr, MVMuint8 flip) {
    MVMint64 result;
    if (obj == NULL) {
        result = 0;
    }
    else {
        MVMBoolificationSpec *bs = obj->st->boolification_spec;
        switch (bs == NULL ? MVM_BOOL_MODE_NOT_TYPE_OBJECT : bs->mode) {
        case MVM_BOOL_MODE_CALL_METHOD:
            if (res_reg) {
                /* We need to do the invocation, and set this register
                 * the result. Then we just do the call. For the flip
                 * case, just set up special return handler to flip
                 * the register. */
                MVMObject *code = MVM_frame_find_invokee(tc, bs->method);
                tc->cur_frame->return_value   = res_reg;
                tc->cur_frame->return_type    = MVM_RETURN_INT;
                tc->cur_frame->return_address = *(tc->interp_cur_op);
                tc->cur_frame->args[0].o = obj;
                if (flip) {
                    tc->cur_frame->special_return      = flip_return;
                    tc->cur_frame->special_return_data = res_reg;
                }
                STABLE(code)->invoke(tc, code, get_inv_callsite(), tc->cur_frame->args);
            }
            else {
                /* Need to set up special return hook. */
                MVMObject *code = MVM_frame_find_invokee(tc, bs->method);
                BoolMethReturnData *data = malloc(sizeof(BoolMethReturnData));
                data->true_addr  = true_addr;
                data->false_addr = false_addr;
                data->flip       = flip;
                tc->cur_frame->special_return      = boolify_return;
                tc->cur_frame->special_return_data = data;
                tc->cur_frame->return_value        = &data->res_reg;
                tc->cur_frame->return_type         = MVM_RETURN_INT;
                tc->cur_frame->return_address      = *(tc->interp_cur_op);
                tc->cur_frame->args[0].o = obj;
                STABLE(code)->invoke(tc, code, get_inv_callsite(), tc->cur_frame->args);
                return;
            }
            break;
        case MVM_BOOL_MODE_UNBOX_INT:
            result = !IS_CONCRETE(obj) || REPR(obj)->box_funcs->get_int(tc, STABLE(obj), obj, OBJECT_BODY(obj)) == 0 ? 0 : 1;
            break;
        case MVM_BOOL_MODE_UNBOX_NUM:
            result = !IS_CONCRETE(obj) || REPR(obj)->box_funcs->get_num(tc, STABLE(obj), obj, OBJECT_BODY(obj)) == 0.0 ? 0 : 1;
            break;
        case MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY:
            result = !IS_CONCRETE(obj) || NUM_GRAPHS(REPR(obj)->box_funcs->get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj))) == 0 ? 0 : 1;
            break;
        case MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY_OR_ZERO: {
            MVMString *str;
            if (!IS_CONCRETE(obj)) {
                result = 0;
                break;
            }
            str = REPR(obj)->box_funcs->get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj));
            result = MVM_coerce_istrue_s(tc, str);
            break;
        }
        case MVM_BOOL_MODE_NOT_TYPE_OBJECT:
            result = !IS_CONCRETE(obj) ? 0 : 1;
            break;
        case MVM_BOOL_MODE_ITER:
            result = IS_CONCRETE(obj) ? MVM_iter_istrue(tc, (MVMIter *)obj) : 0;
            break;
        case MVM_BOOL_MODE_HAS_ELEMS:
            result = IS_CONCRETE(obj) ? MVM_repr_elems(tc, obj) != 0 : 0;
            break;
        default:
            MVM_exception_throw_adhoc(tc, "Invalid boolification spec mode used");
        }
    }

    if (flip)
        result = result ? 0 : 1;

    if (res_reg) {
        res_reg->i64 = result;
    }
    else {
        if (result)
            *(tc->interp_cur_op) = true_addr;
        else
            *(tc->interp_cur_op) = false_addr;
    }
}
示例#8
0
MVMint64 MVM_coerce_istrue_s(MVMThreadContext *tc, MVMString *str) {
    return str == NULL || !IS_CONCRETE(str) || NUM_GRAPHS(str) == 0 || (NUM_GRAPHS(str) == 1 && MVM_string_get_codepoint_at_nocheck(tc, str, 0) == 48) ? 0 : 1;
}