Beispiel #1
0
static void
emonk_outputv(ErlDrvData handle, ErlIOVec *ev)
{
    unsigned char cmd;
    emonk_drv_t* drv = (emonk_drv_t*) handle;
    ErlDrvBinary* args = ev->binv[1];
    unsigned char* b = args->orig_bytes;
    int l = args->orig_size;
    emonk_req_t* req = read_req_info(drv->vm->cx, &cmd, b, l);

    void* data = NULL;
    int length;
    int resp;
    
    if(cmd == 0)
    {
        data = vm_eval(drv->vm, req, &length);
    }
    else
    {
        data = vm_call(drv->vm, req, &length);
    }
    
    if(data == NULL)
    {
        resp = send_undefined(drv, req);
    }
    else
    {
        resp = send_response(drv, req, data, length);
    }

    if(data != NULL) driver_free(data);
    if(req != NULL) free_req_info(req);
}
Beispiel #2
0
int compar(struct context *context, const void *a, const void *b, struct variable *comparator)
{
    struct variable *av = *(struct variable**)a;
    struct variable *bv = *(struct variable**)b;

    if (comparator) {

        byte_array_reset(comparator->str);
        vm_call(context, comparator, av, bv, NULL);

        struct variable *result = (struct variable*)stack_pop(context->operand_stack);
        if (result->type == VAR_SRC)
            result = array_get(result->list.ordered, 0);
        assert_message(result->type == VAR_INT, "non-integer comparison result");
        return result->integer;

    } else {

        enum VarType at = av->type;
        enum VarType bt = bv->type;

        if (at == VAR_INT && bt == VAR_INT) {
            // DEBUGPRINT("compare %p:%d to %p:%d : %d\n", av, av->integer, bv, bv->integer, av->integer - bv->integer);
            return av->integer - bv->integer;
        } else
            DEBUGPRINT("can't compare %s to %s\n", var_type_str(at), var_type_str(bt));

        vm_exit_message(context, "incompatible types for comparison");
        return 0;
    }
}
Beispiel #3
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;
}
Beispiel #4
0
bool custom_method(struct context *context,
                   const char *method,
                   struct variable *indexable,
                   struct variable *index,
                   struct variable *value)
{
    struct variable *custom;
    struct byte_array *key = byte_array_from_string(method);
    if (indexable->map && (custom = (struct variable*)map_get(indexable->map, key))) {
        DEBUGPRINT("\n");
        vm_call(context, custom, indexable, index, value, NULL);
        return true;
    }
    return false;
}
Beispiel #5
0
static int
emonk_control(ErlDrvData handle, uint ignore, char* b, int l, char **rb, int rl)
{
    unsigned char cmd;
    emonk_drv_t* drv = (emonk_drv_t*) handle;
    emonk_req_t* req = read_req_info(drv->vm->cx, &cmd, (unsigned char*) b, l);

    void* data = NULL;
    int length;
    int resp;
        
    if(req == NULL)
    {
        *rb[0] = 0;
        return 1;
    }
    
    if(cmd == 0)
    {
        data = vm_eval(drv->vm, req, &length);
    }
    else
    {
        data = vm_call(drv->vm, req, &length);
    }
    
    if(data == NULL)
    {
        resp = send_undefined(drv, req);
    }
    else
    {
        resp = send_response(drv, req, data, length);
    }

    if(data != NULL) driver_free(data);
    if(req != NULL) free_req_info(req);
    
    if(resp < 0)
    {
        *rb[0] = 0;
        return 1;
    }
    
    return 0;
}
int32_t net_host_send(char *pg, int len) {
    // LAB 8: Your code here.

    if (pg == NULL)
        pg = (void*) UTOP;

    uint64_t addr = (uint64_t)pg;                                                                                                                                   

    if( (vpml4e[VPML4E(addr)] & PTE_P)   &&   (vpde[VPDPE(addr)] & PTE_P)                                                                                     
            &&  (vpd[VPD(addr)] & PTE_P)  &&  (vpt[VPN(addr)] & PTE_P)  )
    {
        pg = (void *) PTE_ADDR( vpt[VPN(addr)] );
    }

    int ret =  vm_call( VMX_VMCALL_NETSEND, (uint64_t) pg , (uint64_t) len, 0, 0, 0 );
    return ret;
}
Beispiel #7
0
void vm_exec(VM *vm, bool trace)
{
	int a = 0;
	int i = 0;
	bool b1, b2;
	float f,g;
	char* c;
	PVector_ptr vptr,r,l;
	int x, y;
	Activation_Record *frame;

	Function_metadata *const main = vm_function(vm, "main");
	vm_call(vm, main);

	// Define VM registers (C compiler probably ignores 'register' nowadays
	// but it's good documentation in this case. Keep as locals for
	// convenience but write them back to the vm object after each decode/execute.
	register addr32 ip = vm->ip;
	register int sp = vm->sp;
	register int fp = vm->fp;
	const byte *code = vm->code;
	element *stack = vm->stack;

	int opcode = code[ip];

	while (opcode != HALT && ip < vm->code_size ) {
		if (trace) vm_print_instr(vm, ip);
		ip++;
		switch (opcode) {
			case IADD:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].i = x + y;
				break;
			case ISUB:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].i = x - y;
				break;
			case IMUL:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].i = x * y;
				break;
			case IDIV:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				if (y ==0 ) {
					zero_division_error();
					break;
				}
				stack[sp].i = x / y;
				break;
			case FADD:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				g = stack[sp].f;
				stack[sp].f = g + f;
				break;
			case FSUB:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				g = stack[sp].f;
				stack[sp].f = g - f;
				break;
			case FMUL:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				g = stack[sp].f;
				stack[sp].f = g * f;
				break;
			case FDIV:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				g = stack[sp].f;
				if (f == 0) {
					zero_division_error();
					break;
				}
				stack[sp].f = g / f;
				break;
            case VADD:
				validate_stack_address(sp-1);
				r = stack[sp--].vptr;
				l = stack[sp].vptr;
				vptr = Vector_add(l,r);
				stack[sp].vptr = vptr;
                break;
			case VADDI:
				validate_stack_address(sp-1);
				i = stack[sp--].i;
				vptr = stack[sp].vptr;
				vptr = Vector_add(vptr,Vector_from_int(i,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
			case VADDF:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				vptr = stack[sp].vptr;
				vptr = Vector_add(vptr,Vector_from_float(f,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
            case VSUB:
				validate_stack_address(sp-1);
				r = stack[sp--].vptr;
				l = stack[sp].vptr;
				vptr = Vector_sub(l,r);
				stack[sp].vptr = vptr;
                break;
			case VSUBI:
				validate_stack_address(sp-1);
				i = stack[sp--].i;
				vptr = stack[sp].vptr;
				vptr = Vector_sub(vptr,Vector_from_int(i,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
			case VSUBF:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				vptr = stack[sp].vptr;
				vptr = Vector_sub(vptr,Vector_from_float(f,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
            case VMUL:
				validate_stack_address(sp-1);
				r = stack[sp--].vptr;
				l = stack[sp].vptr;
				vptr = Vector_mul(l,r);
				stack[sp].vptr = vptr;
                break;
			case VMULI:
				validate_stack_address(sp-1);
				i = stack[sp--].i;
				vptr = stack[sp].vptr;
				vptr = Vector_mul(vptr,Vector_from_int(i,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
			case VMULF:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				vptr = stack[sp].vptr;
				vptr = Vector_mul(vptr,Vector_from_float(f,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
            case VDIV:
                validate_stack_address(sp-1);
				r = stack[sp--].vptr;
				l = stack[sp].vptr;
                vptr = Vector_div(l,r);
                stack[sp].vptr = vptr;
                break;
			case VDIVI:
				validate_stack_address(sp-1);
				i = stack[sp--].i;
				if (i == 0) {
					zero_division_error();
					break;
				}
				vptr = stack[sp].vptr;
				vptr = Vector_div(vptr,Vector_from_int(i,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
			case VDIVF:
				validate_stack_address(sp-1);
				f = stack[sp--].f;
				if (f == 0) {
					zero_division_error();
					break;
				}
				vptr = stack[sp].vptr;
				vptr = Vector_div(vptr,Vector_from_float(f,vptr.vector->length));
				stack[sp].vptr = vptr;
				break;
            case SADD:
				validate_stack_address(sp-1);
				char * right = stack[sp--].s;
				stack[sp].s = String_add(String_new(stack[sp].s),String_new(right))->str;
                break;
			case OR :
				validate_stack_address(sp-1);
				b2 = stack[sp--].b;
				b1 = stack[sp].b;
				stack[sp].b = b1 || b2;
				break;
			case AND :
				validate_stack_address(sp-1);
				b2 = stack[sp--].b;
				b1 = stack[sp].b;
				stack[sp].b = b1 && b2;
				break;
			case INEG:
				validate_stack_address(sp);
				stack[sp].i = -stack[sp].i;
				break;
			case FNEG:
				validate_stack_address(sp);
				stack[sp].f = -stack[sp].f;
				break;
			case NOT:
				validate_stack_address(sp);
				stack[sp].b = !stack[sp].b;
				break;
			case I2F:
				validate_stack_address(sp);
				stack[sp].f = stack[sp].i;
				break;
			case I2S:
				validate_stack_address(sp);
				stack[sp].s = String_from_int(stack[sp].i)->str;
				break;
			case F2I:
				validate_stack_address(sp);
				stack[sp].i = (int)stack[sp].f;
				break;
            case F2S:
				validate_stack_address(sp);
				stack[sp].s = String_from_float((float)stack[sp].f)->str;
                break;
            case V2S:
				validate_stack_address(sp);
				vptr = stack[sp].vptr;
				stack[sp].s = String_from_vector(vptr)->str;
                break;
			case IEQ:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].b = x == y;
				break;
			case INEQ:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].b = x != y;
				break;
			case ILT:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].b = x < y;
				break;
			case ILE:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].b = x <= y;
				break;
			case IGT:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].b = x > y;
				break;
			case IGE:
				validate_stack_address(sp-1);
				y = stack[sp--].i;
				x = stack[sp].i;
				stack[sp].b = x >= y;
				break;
			case FEQ:
				validate_stack_address(sp-1);
				g = stack[sp--].f;
				f = stack[sp].f;
				stack[sp].b = f == g;
				break;
			case FNEQ:
				validate_stack_address(sp-1);
				g = stack[sp--].f;
				f = stack[sp].f;
				stack[sp].b = f != g;
				break;
			case FLT:
				validate_stack_address(sp-1);
				g = stack[sp--].f;
				f = stack[sp].f;
				stack[sp].b = f < g;
				break;
			case FLE:
				validate_stack_address(sp-1);
				g = stack[sp--].f;
				f = stack[sp].f;
				stack[sp].b = f <= g;
				break;
			case FGT:
				validate_stack_address(sp-1);
				g = stack[sp--].f;
				f = stack[sp].f;
				stack[sp].b = f > g;
				break;
			case FGE:
				validate_stack_address(sp-1);
				g = stack[sp--].f;
				f = stack[sp].f;
				stack[sp].b = f >= g;
				break;
            case SEQ:
				validate_stack_address(sp-1);
				c = stack[sp--].s;
				b1 = String_eq(String_new(stack[sp--].s),String_new(c));
				stack[++sp].b = b1;
                break;
            case SNEQ:
				validate_stack_address(sp-1);
				c = stack[sp--].s;
				b1 = String_neq(String_new(stack[sp--].s),String_new(c));
				stack[++sp].b = b1;
                break;
            case SGT:
				validate_stack_address(sp-1);
				c = stack[sp--].s;
				b1 = String_gt(String_new(stack[sp--].s),String_new(c));
				stack[++sp].b = b1;
                break;
            case SGE:
				validate_stack_address(sp-1);
				c = stack[sp--].s;
				b1 = String_ge(String_new(stack[sp--].s),String_new(c));
				stack[++sp].b = b1;
                break;
            case SLT:
				validate_stack_address(sp-1);
				c = stack[sp--].s;
				b1 = String_lt(String_new(stack[sp--].s),String_new(c));
				stack[++sp].b = b1;
                break;
            case SLE:
				validate_stack_address(sp-1);
				c = stack[sp--].s;
				b1 = String_le(String_new(stack[sp--].s),String_new(c));
				stack[++sp].b = b1;
                break;
			case VEQ:
				validate_stack_address(sp-1);
				l = stack[sp--].vptr;
				r = stack[sp--].vptr;
				b1 = Vector_eq(l,r);
				stack[++sp].b = b1;
				break;
			case VNEQ:
				validate_stack_address(sp-1);
				l = stack[sp--].vptr;
				r = stack[sp--].vptr;
				b1 = Vector_neq(l,r);
				stack[++sp].b = b1;
				break;
			case BR:
				ip += int16(code,ip) - 1;
				break;
			case BRF:
				validate_stack_address(sp);
				if ( !stack[sp--].b ) {
					int offset = int16(code,ip);
					ip += offset - 1;
				}
				else {
					ip += 2;
				}
				break;
			case ICONST:
				stack[++sp].i = int32(code,ip);
				ip += 4;
				break;
			case FCONST:
				stack[++sp].f = float32(code,ip);
				ip += 4;
				break;
			case SCONST :
				i = int16(code,ip);
				ip += 2;
				stack[++sp].s = vm->strings[i];
				break;
			case ILOAD:
				i = int16(code,ip);
				ip += 2;
				stack[++sp].i = vm->call_stack[vm->callsp].locals[i].i;
				break;
			case FLOAD:
				i = int16(code,ip);
				ip += 2;
				stack[++sp].f = vm->call_stack[vm->callsp].locals[i].f;
				break;
            case VLOAD:
                i = int16(code,ip);
                ip += 2;
                stack[++sp].vptr = vm->call_stack[vm->callsp].locals[i].vptr;
                break;
            case SLOAD:
                i = int16(code,ip);
                ip += 2;
                stack[++sp].s = vm->call_stack[vm->callsp].locals[i].s;
				break;
			case STORE:
				i = int16(code,ip);
				ip += 2;
				vm->call_stack[vm->callsp].locals[i] = stack[sp--]; // untyped store; it'll just copy all bits
				break;
			case VECTOR:
				i = stack[sp--].i;
				validate_stack_address(sp-i+1);
				double *data = (double*)malloc(i*sizeof(double));
				for (int j = i-1; j >= 0;j--) { data[j] = stack[sp--].f; }
				vptr = Vector_new(data,i);
				stack[++sp].vptr = vptr;
				break;
			case VLOAD_INDEX:
				i = stack[sp--].i;
				vptr = stack[sp--].vptr;
				vm->stack[++sp].f = ith(vptr, i-1);
				break;
			case STORE_INDEX:
				f = stack[sp--].f;
				i = stack[sp--].i;
				vptr = stack[sp--].vptr;
				set_ith(vptr, i-1, f);
				break;
			case SLOAD_INDEX:
				i = stack[sp--].i;
				if (i-1 >= strlen(stack[sp].s))
				{
					fprintf(stderr, "StringIndexOutOfRange: %d\n",(int)strlen(stack[sp].s));
					break;
				}
				c = String_from_char(stack[sp--].s[i-1])->str;
				stack[++sp].s = c;
				break;
			case PUSH_DFLT_RETV:
				i = *&vm->call_stack[vm->callsp].func->return_type;
				sp = push_default_value(i, sp, stack);
				break;
			case POP:
				sp--;
				break;
			case CALL:
				a = int16(code,ip); // load index of function from code memory
				WRITE_BACK_REGISTERS(vm); // (ip has been updated)
				vm_call(vm, &vm->functions[a]);
				LOAD_REGISTERS(vm);
				break;
			case RET:
				frame = &vm->call_stack[vm->callsp--];
				ip = frame->retaddr;
				break;
			case IPRINT:
				validate_stack_address(sp);
				printf("%d\n", stack[sp--].i);
				break;
			case FPRINT:
				validate_stack_address(sp);
				printf("%1.2f\n", stack[sp--].f);
				break;
			case BPRINT:
				validate_stack_address(sp);
				printf("%d\n", stack[sp--].b);
				break;
			case SPRINT:
				validate_stack_address(sp);
				printf("%s\n", stack[sp--].s);
				break;
			case VPRINT:
				validate_stack_address(sp);
				print_vector(stack[sp--].vptr);
				break;
			case VLEN:
				vptr = stack[sp--].vptr;
				i = Vector_len(vptr);
				stack[++sp].i = i;
				break;
			case SLEN:
				c = stack[sp--].s;
				i = String_len(String_new(c));
				stack[++sp].i = i;
				break;
			case GC_START:
				vm->call_stack[vm->callsp].save_gc_roots = gc_num_roots();
				break;
			case GC_END:
				gc_set_num_roots(vm->call_stack[vm->callsp].save_gc_roots);
				break;
			case SROOT:
				gc_add_root((void **)&stack[sp].s);
				break;
			case VROOT:
				gc_add_root((void **)&stack[sp].vptr);
				break;
			case COPY_VECTOR:
				if (vm->call_stack[vm->callsp].locals[i].vptr.vector != NULL) {
					stack[sp].vptr = Vector_copy(vm->call_stack[vm->callsp].locals[i].vptr);
				}
				else if (stack[sp].vptr.vector != NULL) {
					stack[sp].vptr = Vector_copy(stack[sp].vptr);
				}
				else {
					fprintf(stderr, "Vector reference cannot be found\n");
				}
				break;
			case NOP : break;
			default:
				printf("invalid opcode: %d at ip=%d\n", opcode, (ip - 1));
				exit(1);
		}
		WRITE_BACK_REGISTERS(vm);
		if (trace) vm_print_stack(vm);
		opcode = code[ip];
	}
	if (trace) vm_print_instr(vm, ip);
	if (trace) vm_print_stack(vm);

	gc_check();
}
Beispiel #8
0
Datei: ngs.c Projekt: Wingie/ngs
	}

	tree = yyctx.__;
	IF_DEBUG(COMPILER, print_ast(tree, 0);)

	yyrelease(&yyctx);

	// TODO: use native_... methods to load and run the code
	bytecode = compile(tree, source_file_name, &len);
	// BROKEN SINCE BYTECODE FORMAT CHANGE // IF_DEBUG(COMPILER, decompile(bytecode, 0, len);)
	vm_init(&vm, argc, argv);
	set_global(&vm, "BOOTSTRAP_FILE", make_string(bootstrap_file_name));
	ctx_init(&ctx);
	ip = vm_load_bytecode(&vm, bytecode);
	closure = make_closure_obj(ip, 0, 0, 0, 0, 0, NULL);
	mr = vm_call(&vm, &ctx, &result, closure, 0, NULL);
	if(mr == METHOD_OK) {
		return 0;
	}
	if(mr == METHOD_EXCEPTION) {
		if(obj_is_of_type(result, vm.Exception)) {
			printf("========= Uncaught exception of type '%s' =========\n", obj_to_cstring(NGS_TYPE_NAME(NORMAL_TYPE_INSTANCE_TYPE(result))));
			print_exception(&vm, result);
		} else {
			dump_titled("Uncaught exception", result);
		}
		return 1;
	}
	assert(0 == "Unexpected exit from bootstrap code");
}
Beispiel #9
0
void*
vm_run(void* arg)
{
    vm_ptr vm = (vm_ptr) arg;
    JSContext* cx;
    JSObject* gl;
    job_ptr job;
    ENTERM resp;
    int flags;
    
    cx = JS_NewContext(vm->runtime, vm->stack_size);
    if(cx == NULL)
    {
        fprintf(stderr, "Failed to create context.\n");
        goto done;
    }

    JS_BeginRequest(cx);

    flags = 0;
    flags |= JSOPTION_VAROBJFIX;
    flags |= JSOPTION_STRICT;
    flags |= JSVERSION_LATEST;
    flags |= JSOPTION_COMPILE_N_GO;
    flags |= JSOPTION_XML;
    JS_SetOptions(cx, JS_GetOptions(cx) | flags);
    
    gl = JS_NewObject(cx, &global_class, NULL, NULL);
    if(gl == NULL)
    {
        fprintf(stderr, "Failed to create global object.\n");
        goto done;
    }
    
    if(!JS_InitStandardClasses(cx, gl))
    {
        fprintf(stderr, "Failed to initialize classes.\n");
        goto done;
    }
    
    if(!install_jserl(cx, gl))
    {
        fprintf(stderr, "Failed to install erlang object.");
        goto done;
    }
    
    JS_SetErrorReporter(cx, vm_report_error);
    JS_SetContextPrivate(cx, (void*) vm);

    JS_EndRequest(cx);

    while(1)
    {
        job = queue_pop(vm->jobs);
        if(job->type == job_close)
        {
            job_destroy(job);
            break;
        }

        JS_BeginRequest(cx);
        assert(vm->curr_job == NULL && "vm already has a job set.");
        vm->curr_job = job;

        if(job->type == job_eval)
        {
            resp = vm_eval(cx, gl, job);
        }
        else if(job->type == job_call)
        {
            resp = vm_call(cx, gl, job);
        }
        else
        {
            assert(0 && "Invalid job type.");
        }

        vm->curr_job = NULL;
        JS_EndRequest(cx);
        JS_MaybeGC(cx);

        // XXX: If pid is not alive, we just ignore it.
        enif_send(NULL, &(job->pid), job->env, resp);

        job_destroy(job);
    }

done:
    JS_BeginRequest(cx);
    if(cx != NULL) JS_DestroyContext(cx);
    return NULL;
}