Exemple #1
0
Object* vm_push_pair_obj(object *obj){
    Object* o = newObject(global_vm, OBJ_PAIR);
    o->pvalue=obj;
    o->free=delete_obj;

    o->tail = vm_pop(global_vm);
    o->head = vm_pop(global_vm);

    push(global_vm, o);
    return o;
}
Exemple #2
0
/* cons the top two objects on the stack */
void op_cons(vm_internal_type *vm) {
    object_type *car = 0;
    object_type *cdr = 0;

    vm->reg1 = car = vm_pop(vm);
    vm->reg2 = cdr = vm_pop(vm);

    cons(vm, car, cdr, &vm->reg3);

    vm_push(vm, vm->reg3);
}
Exemple #3
0
/* extract the car from a given pair */
void op_set_cdr(vm_internal_type *vm) {
    object_type *pair = 0;
    object_type *obj = 0;

    vm->reg1 = obj = vm_pop(vm);
    vm->reg2 = pair = vm_pop(vm);

    if(obj && pair && pair->type == PAIR) {

        pair->value.pair.cdr = obj;
        vm_push(vm, pair);

    } else {

        throw(vm, "Attempt to set the cdr of a non-pair or set cdr to non-object", 2, obj, pair);
    }
}
Exemple #4
0
/* call a function off a given library */
void op_call_ext(vm_internal_type *vm) {
    object_type *obj = 0;
    object_type *lib = 0;
    ext_call_type func_ptr = 0;

    vm_int func = 0;
    vm_int depth = 0;

    gc_register_root(vm->gc, (void **)&obj);
    gc_register_root(vm->gc, (void **)&lib);

    obj = vm_pop(vm);
    lib = vm_pop(vm);

    depth = vm->depth; /* Save depth before call */

    if(!obj || !lib || obj->type != FIXNUM || lib->type != LIBRARY) {
        throw(vm, "Invalid arguments to call_ext", 2, obj, lib);
    } else {

        func = obj->value.integer;

        if(func > lib->value.library.func_count) {
            throw(vm, "Invalid function number", 2, obj, lib);
        } else {

            /* call the function */
            func_ptr = ((binding_type *)lib->value.library.functions)[func].func;
            (*func_ptr)(vm, vm->gc);
        }
    }

    /* Make sure that something was returned */
    if (vm->depth != depth) {
      throw(vm, "Stack uneven after call_ext", 0 );
    }

    gc_unregister_root(vm->gc, (void **)&lib);
    gc_unregister_root(vm->gc, (void **)&obj);
}
Exemple #5
0
void
math_module_init(void)
{
  vm_push(0);
  
  MODULE(module_cur)->consts  = (obj_t *) &math_consts;
  MODULE(module_cur)->nconsts = sizeof(math_consts) / sizeof(obj_t);
  
  init_strs(math_init_str_tbl, ARRAY_SIZE(math_init_str_tbl));
  
  init_inst_methods(math_init_inst_method_tbl, ARRAY_SIZE(math_init_inst_method_tbl));
  
  vm_pop(0);
}
Exemple #6
0
/* extract the car from a given pair */
void op_cdr(vm_internal_type *vm) {
    object_type *obj = 0;
    
    vm->reg1 = obj = vm_pop(vm);

    if(obj && obj->type == PAIR) {

        vm->reg1 = obj = obj->value.pair.cdr;
        vm_push(vm,obj);

    } else {

        throw(vm, "Attempt to read the cdr of a non-pair", 1, obj);
    }
}
Exemple #7
0
/* assemble a string on the stack into a proc */
void op_asm(vm_internal_type *vm) {
    object_type *obj = 0;
    object_type *closure =0;
    env_type *env = 0;

    uint8_t *code_ref = 0;
    size_t written = 0;

    gc_register_root(vm->gc, (void **)&obj);
    gc_register_root(vm->gc, (void **)&closure);
    gc_register_root(vm->gc, (void **)&code_ref);
    gc_register_root(vm->gc, (void **)&env);

    obj = vm_pop(vm);

    if(!obj || obj->type != STRING) {
        throw(vm, "Attempt to assemble non-string", 1, obj);

    } else {
        /* assemble the string */
        written = asm_string(vm->gc, obj->value.string.bytes, &code_ref);

        /* clone the current environment in a
           closure */
        clone_env(vm, (env_type **)&env, vm->env, false);

        /* point to the entry point of our
           assembled code_ref */
        env->code_ref = code_ref;
        env->ip = 0;
        env->length = written;

        closure = vm_alloc(vm, CLOSURE);
        /* save the new closure onto our stack */
        closure->value.closure = env;

        vm_push(vm, closure);
    }

    gc_unregister_root(vm->gc, (void **)&env);
    gc_unregister_root(vm->gc, (void **)&code_ref);
    gc_unregister_root(vm->gc, (void **)&closure);
    gc_unregister_root(vm->gc, (void **)&obj);

}
Exemple #8
0
/* do a dlopen on a dll */
void op_import(vm_internal_type *vm) {
    object_type *obj = 0;
    object_type *obj2 = 0;
    object_type *lib = 0;
    object_type *binding_alist = 0;
    char *path = 0;
    vm_int length = 0;
    void *handle = 0;
    binding_type **export_list = 0;
    char *symbol = 0;
    vm_int func_count = 0;
    char *msg = 0;

    gc_register_root(vm->gc, (void **)&obj);
    gc_register_root(vm->gc, (void **)&obj2);
    gc_register_root(vm->gc, (void **)&lib);
    gc_register_root(vm->gc, (void **)&binding_alist);
    gc_register_root(vm->gc, (void **)&path);

    obj = vm_pop(vm);

    if(!obj || obj->type != STRING) {
        throw(vm, "Attempt to import with non-string filename", 1, obj);
    } else {

        /* allocate a string long enough to include the either .so or .dylib */
        length = obj->value.string.length + LIB_EXT_LEN + 1;
        gc_alloc(vm->gc, 0, length, (void **)&path);

        strncpy(path, obj->value.string.bytes, length);
        strncat(path, LIB_EXT, length);

        /* if we have already imported this library,
           return the existing library object */
        if(hash_get(vm->import_table, path, (void**)&lib)) {
            vm_push(vm, lib);
        } else {
            /* check if the library has been loaded */
            handle = dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_NOLOAD);

            /* load the library if it has not been loaded */
            if(!handle) {
                /* handle = dlopen(obj->value.string.bytes, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); */
                /* RTLD_DEEPBIND is not defined on osx ... */
                handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
            }

            /* check to make sure we did not run into an error */
            if(!handle) {
                throw(vm, dlerror(), 1, obj);
            } else {
                lib = vm_alloc(vm, LIBRARY);

                dlerror(); /* Clear error states */
                export_list = (binding_type **)dlsym(handle, "export_list");

                if((msg = dlerror())) {
                    throw(vm, msg, 1, obj);
                } else {

                    func_count = 0;

                    while(((binding_type *)export_list)[func_count].func) {
                        func_count++;
                    }

                    lib->value.library.handle = handle;
                    lib->value.library.functions = export_list;
                    lib->value.library.func_count = func_count;

                    /* save this library off into the import table. */
                    hash_set(vm->import_table, path, lib);

                    vm_push(vm, lib);
                }
            }
        }

        /* if lib is still 0, we couldn't load it. */
        if (lib != 0) {
            /* setup a binding alist so we can bind the exported
             * symbols to function call values
             */

            binding_alist = vm->empty;
            export_list = lib->value.library.functions;
            func_count = 0;

            /* count the number of functions */
            while(((binding_type *)export_list)[func_count].func) {

                symbol = ((binding_type *)export_list)[func_count].symbol;
                /* create string object */
                obj = vm_make_string(vm,
                                     symbol,
                                     strlen(symbol));

                /* make our string into a symbol */
                make_symbol(vm, &obj);

                /* convert the func_counter into a number */
                obj2 = vm_alloc(vm, FIXNUM);
                obj2->value.integer = func_count;

                cons(vm, obj, obj2, &(vm->reg1));
                cons(vm, vm->reg1, binding_alist, &(vm->reg2));

                binding_alist = vm->reg2;

                /* increment function count */
                func_count++;
            }
            vm_push(vm, binding_alist);
        }
    }

    gc_unregister_root(vm->gc, (void **)&path);
    gc_unregister_root(vm->gc, (void **)&binding_alist);
    gc_unregister_root(vm->gc, (void **)&lib);
    gc_unregister_root(vm->gc, (void **)&obj2);
    gc_unregister_root(vm->gc, (void **)&obj);
}