Beispiel #1
0
//---------------------------------------------------------------------------
int Json::parse_node(Value &v)
{
    if (!current_node)
        return -1;

    if (!get_type_node(v))
        return 0;

    if (json_is_object(current_node))
    {
        v.type = Value::CONTAINER_TYPE_OBJECT;

        const char *key = NULL;
        json_t *value = NULL;
        json_object_foreach(current_node, key, value) {
            Value new_node;
            json_t *tmp = current_node;
            current_node = value;

            if (parse_node(new_node))
                return -1;

            v.obj[std::string(key)] = new_node;
            current_node = tmp;
        }
        return 0;
    }
Beispiel #2
0
/* Inserts a guard for the specified types into the tree. */
static MVMint32 try_add_guard(MVMThreadContext *tc, MVMSpeshArgGuard *ag, MVMCallsite *cs,
                              MVMSpeshStatsType *types, MVMuint32 candidate) {
    MVMuint32 current_node = get_callsite_node(tc, ag, cs);
    if (types) {
        /* We're adding a type-based result, and thus for a speculative
         * specialization. Certain specializations come ahead of those, and
         * hang off the callsite node; skip over any such node. */
        MVMuint16 arg_idx = 0;
        MVMuint16 i;
        if (ag->nodes[ag->nodes[current_node].yes].op == MVM_SPESH_GUARD_OP_CERTAIN_RESULT)
            current_node = ag->nodes[current_node].yes;
        for (i = 0; i < cs->flag_count; i++) {
            if (cs->arg_flags[i] & MVM_CALLSITE_ARG_NAMED)
                arg_idx++; /* Skip over name */
            if (cs->arg_flags[i] & MVM_CALLSITE_ARG_OBJ) {
                MVMSpeshStatsType *type = &(types[i]);
                if (type->type)
                    current_node = get_type_node(tc, ag, current_node, type, arg_idx);
            }
            arg_idx++;
        }
        if (ag->nodes[current_node].yes)
            return 0;
        ag->nodes[ag->used_nodes].op = MVM_SPESH_GUARD_OP_RESULT;
        ag->nodes[ag->used_nodes].yes = 0;
        ag->nodes[ag->used_nodes].no = 0;
    }
    else {
        /* We're adding a certain result. If there already is such a node, we
         * already have that specialization. Otherwise, we need to insert it
         * and redirect the current_node's .yes to point to it, and it to
         * point to whatever current_node's .yes used to point to (so it goes
         * in ahead of type guards etc.). */
        if (ag->nodes[ag->nodes[current_node].yes].op == MVM_SPESH_GUARD_OP_CERTAIN_RESULT)
            return 0;
        ag->nodes[ag->used_nodes].op = MVM_SPESH_GUARD_OP_CERTAIN_RESULT;
        ag->nodes[ag->used_nodes].yes = ag->nodes[current_node].yes;
        ag->nodes[ag->used_nodes].no = 0;
    }
    ag->nodes[ag->used_nodes].result = candidate;
    ag->nodes[current_node].yes = ag->used_nodes++;
    return 1;
}