Exemple #1
0
static void push_fnc(struct context *context, struct byte_array *program)
{
    uint32_t num_closures = serial_decode_int(program);
    struct map *closures = NULL;

    for (int i=0; i<num_closures; i++) {
        struct byte_array *name = serial_decode_string(program);
        if (context->runtime) {
            if (!closures)
                closures = map_new();
            struct variable *c = find_var(context, name);
            c = variable_copy(context, c);
            map_insert(closures, name, c);
        }
    }

    struct byte_array *body = serial_decode_string(program);

    DEBUGPRINT("FNC %u,%u\n", num_closures, body->length);
    //display_code(context, body);

    if (context->runtime) {
        struct variable *f = variable_new_fnc(context, body, closures);
        variable_push(context, f);
    }
}
Exemple #2
0
void *incoming_connection(void *arg)
{
	char readline[MAXLINE];
    struct thread_argument *ta = (struct thread_argument *)arg;
    struct context *context = context_new(true, true);
    context->find = ta->find;

    for (;;)
    {
        bzero(readline, sizeof(readline));
        int n;
        if (((n = CyaSSL_read(ta->ssl, readline, MAXLINE)) <= 0))
        {
            fprintf(stderr, "client closed connection\n");
            goto free_ssl;
        }

        fprintf(stderr, "%d bytes received: %s\n", n, readline);
        struct byte_array *raw_message = byte_array_new_size(n);
        raw_message->data = (uint8_t*)readline;
        int32_t raw_message_length = serial_decode_int(raw_message);
        assert_message(raw_message_length < MAXLINE, "todo: handle long messages");
        struct variable *message = variable_deserialize(context, raw_message);

        struct variable *listener = (struct variable *)map_get(server_listeners, (void*)(VOID_INT)ta->fd);
        vm_call(context, listener, message);
    }

free_ssl:
	CyaSSL_free(ta->ssl); // Free CYASSL object
    free(ta);
    context_del(context);
	return NULL;
}
Exemple #3
0
static void push_bool(struct context *context, struct byte_array *program)
{
    null_check(program);
    int32_t num = serial_decode_int(program);
    VM_DEBUGPRINT("BOOL %d\n", num);
    struct variable* var = variable_new_bool(context, num);
    variable_push(context, var);
}
Exemple #4
0
void serial_decode(struct byte_array* buf, serial_element se, const void* extra)
{
    while (buf->current < buf->data + buf->length)
    {
        // get key and wire type
        int32_t keyWire = serial_decode_int(buf);
        struct key_value_pair pair = {
            .key = keyWire >> 2,
            .wire_type = (enum serial_type)(keyWire & 0x03)
        };

        // get data
        switch(pair.wire_type) {
            case SERIAL_INT:  /* int */
                pair.value.integer = serial_decode_int(buf);
                break;
            case SERIAL_FLOAT:
                pair.value.floater = serial_decode_float(buf);
            case SERIAL_STRING:  /* bytes */
                pair.value.bytes = serial_decode_string(buf);
                break;
            case SERIAL_ARRAY:
                break;
            default:
                DEBUGPRINT("serial_decode ?\n");
                break;
        }
        if (se(&pair, buf, extra)) {
//            DEBUGPRINT("serial_decode: break\n");
            break;
        }
    }
//    DEBUGPRINT("serial_decode done\n");
}

// assume little endian
struct byte_array *encode_float(struct byte_array *buf, float f)
{
    assert_message(sizeof(float)==4, "bad float size");
    uint8_t *uf = (uint8_t*)&f;
    for (int i=4; i; i--) {
        byte_array_add_byte(buf, *uf);
        uf++;
    }
    return buf;
}
Exemple #5
0
static int32_t iff(struct context *context, struct byte_array *program)
{
    null_check(program);
    int32_t offset = serial_decode_int(program);
    DEBUGPRINT("IF %d\n", offset);
    if (!context->runtime)
        return 0;
    return test_operand(context) ? 0 : (VOID_INT)offset;
}
Exemple #6
0
struct variable *src(struct context *context, enum Opcode op, struct byte_array *program)
{
    int32_t size = serial_decode_int(program);
    DEBUGPRINT("%s %d\n", NUM_TO_STRING(opcodes, op), size);
    if (!context->runtime)
        return NULL;
    struct variable *v = variable_new_src(context, size);
    stack_push(context->operand_stack, v);
    return v;
}
Exemple #7
0
struct byte_array* serial_decode_string(struct byte_array* buf)
{
	null_check(buf);
    int32_t len = serial_decode_int(buf);
	assert_message(len>=0, "negative malloc");
    struct byte_array* ba = byte_array_new_size(len);
    ba->data = ba->current = (uint8_t*)malloc(len);
	null_check(ba->data);
    memcpy(ba->data, buf->current, len);
    buf->current += len;
    return ba;
}
Exemple #8
0
static int32_t jump(struct context *context, struct byte_array *program)
{
    null_check(program);
    uint8_t *start = program->current;
    int32_t offset = serial_decode_int(program);
    DEBUGPRINT("JMP %d\n", offset);
    if (!context->runtime)
        return 0;

    if (offset < 0) // skip over current VM_JMP instruction when going backward
        offset -= (program->current - start) + 1;
    return offset;// - (program->current - start);
}
Exemple #9
0
static void push_map(struct context *context, struct byte_array *program)
{
    int32_t num_items = serial_decode_int(program);
    DEBUGPRINT("MAP %d", num_items);
    if (!context->runtime)
        VM_DEBUGPRINT("\n");
    struct map *map = map_new();
    while (num_items--) {
        struct variable* value = variable_pop(context);
        struct variable* key = variable_pop(context);
        assert_message(key->type==VAR_STR, "non-string map index");
        map_insert(map, key->str, value);
    }
    struct variable *v = variable_new_map(context, map);
    DEBUGPRINT(": %s\n", variable_value_str(context, v));
    variable_push(context, v);
}
Exemple #10
0
static int32_t boolean_op(struct context *context, struct byte_array *program, enum Opcode op)
{
    null_check(program);
    int32_t short_circuit = serial_decode_int(program);

    DEBUGPRINT("%s %d\n", NUM_TO_STRING(opcodes, op), short_circuit);
    if (!context->runtime)
        return 0;
    struct variable *v = variable_pop(context);
    null_check(v);
    bool indeed_quite_so;
    switch (v->type) {
        case VAR_BOOL:  indeed_quite_so = v->boolean;   break;
        case VAR_FLT:   indeed_quite_so = v->floater;   break;
        case VAR_INT:   indeed_quite_so = v->integer;   break;
        case VAR_NIL:   return 0;
        default:        indeed_quite_so = true;         break;
    }
    if (indeed_quite_so ^ (op == VM_AND)) {
        stack_push(context->operand_stack, v);
        return short_circuit;
    }
    return 0;
}
Exemple #11
0
static void push_list(struct context *context, struct byte_array *program)
{
    int32_t num_items = serial_decode_int(program);
    DEBUGPRINT("LST %d", num_items);
    if (!context->runtime)
        VM_DEBUGPRINT("\n");
    struct array *items = array_new();

    struct map *map = NULL;
    while (num_items--) {
        struct variable* v = variable_pop(context);
        if (v->type == VAR_MAP) {
            if (!map)
                map = map_new(context, NULL);
            map_update(map, v->map); // mapped values are stored in the map, not list
        }
        else
            array_insert(items, 0, v);
    }
    struct variable *list = variable_new_list(context, items);
    list->map = map;
    DEBUGPRINT(": %s\n", variable_value_str(context, list));
    variable_push(context, list);
}