Example #1
0
static void push_str(struct context *context, struct byte_array *program)
{
    struct byte_array* str = serial_decode_string(program);
    VM_DEBUGPRINT("STR '%s'\n", byte_array_to_string(str));
    struct variable* v = variable_new_str(context, str);
    variable_push(context, v);
}
Example #2
0
static inline struct variable *cfnc_serialize(struct context *context)
{
    struct variable *args = (struct variable*)stack_pop(context->operand_stack);
    struct variable *indexable = (struct variable*)array_get(args->list.ordered, 0);

    struct byte_array *bits = variable_serialize(context, NULL, indexable);
    byte_array_reset(bits);
    struct variable *result = variable_new_str(context, bits);
    byte_array_del(bits);
    return result;
}
Example #3
0
struct variable *sys_send(struct context *context)
{
    struct variable *arguments = (struct variable*)stack_pop(context->operand_stack);
    struct variable *sender = (struct variable*)array_get(arguments->list, 1);
    const char *message = param_str(arguments, 2);

    assert_message(sender->type == VAR_INT, "non int fd");
    int32_t fd = sender->integer;
    struct thread_argument *ta = (struct thread_argument*)map_get(socket_listeners, (void*)(VOID_INT)fd);

    printf("send on ssl=%p\n", ta->ssl);
    if (CyaSSL_write(ta->ssl, message, strlen(message)) != strlen(message))
        context->vm_exception = variable_new_str(context, byte_array_from_string("CyaSSL_write error"));

    return NULL;
}
Example #4
0
//    a                b        c
// <sought> <replacement> [<start>]
// <start> <length> <replacement>
static inline struct variable *cfnc_replace(struct context *context)
{
    struct variable *args = (struct variable*)stack_pop(context->operand_stack);
    struct variable *self = (struct variable*)array_get(args->list.ordered, 0);
    struct variable *a = (struct variable*)array_get(args->list.ordered, 1);
    struct variable *b = (struct variable*)array_get(args->list.ordered, 2);
    struct variable *c = args->list.ordered->length > 3 ?
        (struct variable*)array_get(args->list.ordered, 3) : NULL;

    null_check(self);
    null_check(b);
    assert_message(self->type == VAR_STR, "searching in a non-string");

    struct byte_array *replaced = NULL;

    if (a->type == VAR_STR) { // find a, replace with b

        assert_message(b->type == VAR_STR, "non-string replacement");
        int32_t where = 0;

        if (c) { // replace first match after index c

            assert_message(c->type == VAR_INT, "non-integer index");
            if (((where = byte_array_find(self->str, a->str, c->integer)) >= 0))
                replaced = byte_array_replace(self->str, b->str, where, b->str->length);

        } else {

            replaced = byte_array_replace_all(self->str, a->str, b->str);
        }

    } else if (a->type == VAR_INT ) { // replace at index a, length b, insert c

        assert_message(a || a->type == VAR_INT, "non-integer count");
        assert_message(b || b->type == VAR_INT, "non-integer start");
        replaced = byte_array_replace(self->str, c->str, a->integer, b->integer);

    } else exit_message("replacement is not a string");

    null_check(replaced);
    struct variable *result = variable_new_str(context, replaced);
    byte_array_del(replaced);

    return result;
}
Example #5
0
static struct variable *binary_op_str(struct context *context,
                                      enum Opcode op,
                                      struct variable *u,
                                      struct variable *v)
{
    struct variable *w = NULL;
    struct byte_array *ustr = u->type == VAR_STR ? u->str : variable_value(context, u);
    struct byte_array *vstr = v->type == VAR_STR ? v->str : variable_value(context, v);

    switch (op) {
        case VM_ADD:
            w = variable_new_str(context, byte_array_concatenate(2, vstr, ustr));
            break;
        case VM_EQU:    w = variable_new_int(context, byte_array_equals(ustr, vstr));            break;
        default:
            return (struct variable*)vm_exit_message(context, "unknown string operation");
    }
    return w;
}
Example #6
0
// returns contents and modification time of file
struct variable *sys_read(struct context *context)
{
    struct variable *args = (struct variable*)stack_pop(context->operand_stack);
    struct variable *path = param_var(args, 1);
    uint32_t offset = param_int(args, 2);
    uint32_t length = param_int(args, 3);

    struct byte_array *bytes = read_file(path->str, offset, length);
    DEBUGPRINT("read %d bytes\n", bytes ? bytes->length : 0);

    struct variable *content = NULL;
    if (NULL != bytes)
    {
        content = variable_new_str(context, bytes);
        byte_array_del(bytes);
    }
    else
    {
        context->error = variable_new_str_chars(context, "could not load file");
        content = variable_new_nil(context);
    }
    return content;
}
Example #7
0
static struct variable *list_get_int(struct context *context,
                                     const struct variable *indexable,
                                     uint32_t index)
{
    null_check(indexable);

    enum VarType it = (enum VarType)indexable->type;
    switch (it) {
        case VAR_INT: return variable_new_int(context, index);
        case VAR_LST:
            if (index < indexable->list->length)
                return (struct variable*)array_get(indexable->list, index);
            return variable_new_nil(context);
        case VAR_STR: {
            vm_assert(context, index < indexable->str->length, "index out of bounds");
            char *str = (char*)malloc(2);
            sprintf(str, "%c", indexable->str->data[index]);
            return variable_new_str(context, byte_array_from_string(str));
        }
        default:
            vm_exit_message(context, "indexing non-indexable");
            return NULL;
    }
}
Example #8
0
struct variable *builtin_method(struct context *context,
                                struct variable *indexable,
                                const struct variable *index)
{
    enum VarType it = indexable->type;
    char *idxstr = byte_array_to_string(index->str);
    struct variable *result = NULL;

    if (!strcmp(idxstr, FNC_LENGTH)) {
        int n;
        switch (indexable->type) {
            case VAR_LST: n = indexable->list.ordered->length;  break;
            case VAR_STR: n = indexable->str->length;           break;
            case VAR_NIL: n = 0;                                break;
            default:
                free(idxstr);
                exit_message("no length for non-indexable");
                return NULL;
        }
        result = variable_new_int(context, n);
    }
    else if (!strcmp(idxstr, FNC_TYPE)) {
        const char *typestr = var_type_str(it);
        result = variable_new_str_chars(context, typestr);
    }

    else if (!strcmp(idxstr, FNC_STRING)) {
        switch (indexable->type) {
            case VAR_STR:
            case VAR_BYT:
            case VAR_FNC:
                result = variable_copy(context, indexable);
                break;
            default: {
                struct byte_array *vv = variable_value(context, indexable);
                result = variable_new_str(context, vv);
                byte_array_del(vv);
                break;
            }
        }
    }

    else if (!strcmp(idxstr, FNC_LIST))
        result = variable_new_list(context, indexable->list.ordered);

    else if (!strcmp(idxstr, FNC_KEY)) {
        if (indexable->type == VAR_KVP)
            result = indexable->kvp.key;
        else
            result = variable_new_nil(context);
    }

    else if (!strcmp(idxstr, FNC_VAL)) {
        if (indexable->type == VAR_KVP)
            result = indexable->kvp.val;
        else
            result = variable_new_nil(context);
    }

    else if (!strcmp(idxstr, FNC_KEYS))
        result = variable_map_list(context, indexable, &map_keys);

    else if (!strcmp(idxstr, FNC_VALS))
        result = variable_map_list(context, indexable, &map_vals);

    else if (!strcmp(idxstr, FNC_PACK))
        result = variable_new_cfnc(context, &cfnc_pack);

    else if (!strcmp(idxstr, FNC_SERIALIZE))
        result = variable_new_cfnc(context, &cfnc_serialize);
    
    else if (!strcmp(idxstr, FNC_DESERIALIZE))
        result = variable_new_cfnc(context, &cfnc_deserialize);

    else if (!strcmp(idxstr, FNC_SORT)) {
        assert_message(indexable->type == VAR_LST, "sorting non-list");
        result = variable_new_cfnc(context, &cfnc_sort);
    }

    else if (!strcmp(idxstr, FNC_CHAR))
        result = variable_new_cfnc(context, &cfnc_char);

    else if (!strcmp(idxstr, FNC_HAS))
        result = variable_new_cfnc(context, &cfnc_has);

    else if (!strcmp(idxstr, FNC_FIND))
        result = variable_new_cfnc(context, &cfnc_find);

    else if (!strcmp(idxstr, FNC_PART))
        result = variable_new_cfnc(context, &cfnc_part);

    else if (!strcmp(idxstr, FNC_REMOVE))
        result = variable_new_cfnc(context, &cfnc_remove);

    else if (!strcmp(idxstr, FNC_INSERT))
        result = variable_new_cfnc(context, &cfnc_insert);

    else if (!strcmp(idxstr, FNC_REPLACE))
        result = variable_new_cfnc(context, &cfnc_replace);

    free(idxstr);
    return result;
}
Example #9
0
struct variable *sys_connect(struct context *context)
{
    struct variable *arguments = (struct variable*)stack_pop(context->operand_stack);
    const char *serveraddr = param_str(arguments, 1);
    const int32_t serverport = param_int(arguments, 2);
    struct variable *listener = ((struct variable*)array_get(arguments->list, 2));

	int sockfd;
	struct sockaddr_in servaddr;
	CYASSL_CTX* ctx;
	CYASSL* ssl;

	node_init();

	// Create and initialize CYASSL_CTX structure
	if ( (ctx = CyaSSL_CTX_new(CyaTLSv1_client_method())) == NULL)
	{
        context->vm_exception = variable_new_str(context, byte_array_from_string("SSL_CTX_new error"));
        CyaSSL_Cleanup();
        return NULL;
	}

	// Load CA certificates into CYASSL_CTX
	if (CyaSSL_CTX_load_verify_locations(ctx, "./conf/ca-cert.pem", 0) != SSL_SUCCESS)
	{
        context->vm_exception = variable_new_str(context, byte_array_from_string("Error loading ca-cert.pem, please check the file.\n"));
        CyaSSL_CTX_free(ctx);
        CyaSSL_Cleanup();
        return NULL;
	}

	// Create Socket file descriptor
	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(serverport);
	inet_pton(AF_INET, serveraddr, &servaddr.sin_addr);

	// Blocking Connect to socket file descriptor
	connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

	// Create CYASSL object
	if ((ssl = CyaSSL_new(ctx)) == NULL)
	{
        context->vm_exception = variable_new_str(context, byte_array_from_string("CyaSSL_new error"));
        CyaSSL_CTX_free(ctx);
        CyaSSL_Cleanup();
        return NULL;
	}

	CyaSSL_set_fd(ssl, sockfd);
	fprintf(stderr, "Connected on %d -- %p\n", sockfd, ssl);

    struct thread_argument *ta = (struct thread_argument *)malloc(sizeof(struct thread_argument));
    ta->find = context->find;
    ta->listener = listener;
    ta->ssl = ssl;
    ta->fd = sockfd;
    ta->cya = ctx;

    if (socket_listeners == NULL)
        socket_listeners = map_new_ex(NULL, &int_compare, &int_hash, &int_copy, &int_del);
    map_insert(socket_listeners, (void*)(VOID_INT)sockfd, (void*)(VOID_INT)ta);

    return variable_new_int(context, sockfd);
}