예제 #1
0
Val   _util_NetDB_mkservent   (Task* task,  struct servent* sentry)   {
    //=====================
    //
    // Mythryl type:
    //
    // Allocate an Lib7 value of type:
    //    Null_Or(   (String, List(String), Int, String)   )
    // to represent a struct servent value.  Note that the port number is returned
    // in network byteorder, so we need to map it to host order.


    if (sentry == NULL)   return OPTION_NULL;

    // If our agegroup0 buffer is more than half full,
    // empty it by doing a heapcleaning.  This is very
    // conservative -- which is the way I like it. :-)
    //
    if (agegroup0_freespace_in_bytes( task )
      < agegroup0_usedspace_in_bytes( task )
    ){
	call_heapcleaner( task,  0 );
    }

    // Build the return result:

    Val name    =  make_ascii_string_from_c_string__may_heapclean(		task, sentry->s_name,     NULL	);		Roots roots1 = { &name,	    NULL };
    Val aliases =  make_ascii_strings_from_vector_of_c_strings__may_heapclean(	task, sentry->s_aliases, &roots1);		Roots roots2 = { &aliases,  &roots1 };
    Val proto   =  make_ascii_string_from_c_string__may_heapclean(		task, sentry->s_proto,   &roots2);	//	Roots roots3 = { &proto,    &roots2 };
    Val port    =  TAGGED_INT_FROM_C_INT(					ntohs(sentry->s_port)		);

    Val result  =  make_four_slot_record(task,  name, aliases, port, proto);

    return OPTION_THE( task, result );
}
예제 #2
0
Val   _util_NetDB_mknetent   (Task *task, struct netent* nentry)   {
    //====================
    //
    // Allocate a Mythryl value of type
    //    Null_Or(   (String, List(String), Addr_Family, Sysword)   )
    // to represent a struct netent value.

    if (nentry == NULL)   return OPTION_NULL;

    // Build the return result:

    // If our agegroup0 buffer is more than half full,
    // empty it by doing a heapcleaning.  This is very
    // conservative -- which is the way I like it. :-)
    //
    if (agegroup0_freespace_in_bytes( task )
      < agegroup0_usedspace_in_bytes( task )
    ){
	call_heapcleaner( task, 0 );
    }

    Val name    =  make_ascii_string_from_c_string__may_heapclean(		task,                    nentry->n_name,     NULL	);		Roots roots1 = { &name,    NULL	    };
    Val aliases =  make_ascii_strings_from_vector_of_c_strings__may_heapclean(	task,                    nentry->n_aliases,  &roots1	);		Roots roots2 = { &aliases, &roots1  };
    Val af      =  make_system_constant__may_heapclean(				task, &_Sock_AddrFamily, nentry->n_addrtype, &roots2	);	//	Roots roots3 = { &af,      &roots2  };
    Val net     =  make_one_word_unt(						task,  (Vunt) (nentry->n_net)			);	//	Roots roots4 = { &net,	   &roots3  };

    Val	result  =  make_four_slot_record(					task,  name, aliases, af, net  );

    return   OPTION_THE( task, result );
}
예제 #3
0
Val   _lib7_netdb_get_protocol_by_number   (Task* task,  Val arg)   {
    //==================================
    //
    // Mythryl type:  Int -> Null_Or(  (String, List(String), Int)   )
    //
    // This fn gets bound as   get_prot_by_number'   in:
    //
    //     src/lib/std/src/socket/net-protocol-db.pkg

															ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int number = TAGGED_INT_TO_C_INT( arg );										// Last use of 'arg'.

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	struct protoent*  pentry =   getprotobynumber( number );
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );


    if (pentry == NULL)   return OPTION_NULL;


    Val name    =  make_ascii_string_from_c_string__may_heapclean	     (task, pentry->p_name,	NULL   );				Roots roots1 = { &name, NULL };

    Val aliases =  make_ascii_strings_from_vector_of_c_strings__may_heapclean(task, pentry->p_aliases, &roots1 );

    Val result	=  make_three_slot_record( task,   name,  aliases,  TAGGED_INT_FROM_C_INT(pentry->p_proto)  );

    result =  OPTION_THE( task, result );

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
예제 #4
0
Val   _lib7_netdb_get_protocol_by_name   (Task* task,  Val arg)   {
    //================================
    //
    // Mythryl type:   String -> Null_Or(   (String, List(String), Int)   )
    //
    // This fn gets bound as   get_prot_by_name'   in:
    // 
    //     src/lib/std/src/socket/net-protocol-db.pkg

															ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    struct protoent*  pentry;

    char* heap_name = HEAP_STRING_AS_C_STRING( arg );									// Last use of 'arg'.

    // We cannot reference anything on the Mythryl
    // heap between RELEASE_MYTHRYL_HEAP and RECOVER_MYTHRYL_HEAP
    // because garbage collection might be moving
    // it around, so copy heap_name into C storage: 
    //
    Mythryl_Heap_Value_Buffer  name_buf;
    //
    {	char* c_name =  buffer_mythryl_heap_value( &name_buf, (void*) heap_name, strlen( heap_name ) +1 );		// '+1' for terminal NUL on string.

	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    pentry =	getprotobyname( c_name );
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

	unbuffer_mythryl_heap_value( &name_buf );
    }

    if (pentry == NULL)   return OPTION_NULL;


    Val name    =  make_ascii_string_from_c_string__may_heapclean		(task, pentry->p_name,	   NULL   );					Roots roots1 = { &name, NULL };

    Val aliases =  make_ascii_strings_from_vector_of_c_strings__may_heapclean	(task, pentry->p_aliases, &roots1 );

    Val result
	=
        make_three_slot_record( task,   name,  aliases,  TAGGED_INT_FROM_C_INT(pentry->p_proto) );

    result =  OPTION_THE( task, result );

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
예제 #5
0
파일: import-heap.c 프로젝트: omork/mythryl
Task*   import_heap_image__may_heapclean   (const char* fname, Heapcleaner_Args* params,  Roots* extra_roots) {
    //  ================================
    //
    // This fn is called (only) by   load_and_run_heap_image__may_heapclean   in   src/c/main/load-and-run-heap-image.c
    //
    Task*		task;
    Heapfile_Header	image_header;
    Heap_Header	heap_header;
    Val		*externs;
    Pthread_Image	image;
    Inbuf		inbuf;

    if (fname != NULL) {
	//
        // Resolve the name of the image.
        //  If the file exists use it, otherwise try the
        // pathname with the machine ID as an extension.

	if ((inbuf.file = fopen(fname, "rb"))) {
	    //
	    if (verbosity__global > 0)   say("loading %s ", fname);

	} else {
	    //
	    if ((inbuf.file = fopen(fname, "rb"))) {
		//
	        if (verbosity__global > 0)   say("loading %s ", fname);

	    } else {

		die ("unable to open heap image \"%s\"\n", fname);
	    }
	}

	inbuf.needs_to_be_byteswapped = FALSE;
	inbuf.buf	    = NULL;
	inbuf.nbytes    = 0;

    } else {
	//
	// fname == NULL, so try to find
	// an in-core heap image:

  	#if defined(DLOPEN) && !defined(OPSYS_WIN32)
	    //
	    void *lib = dlopen (NULL, RTLD_LAZY);
	    void *vimg, *vimglenptr;

	    if ((vimg       = dlsym(lib,HEAP_IMAGE_SYMBOL    )) == NULL)      die("no in-core heap image found\n");
	    if ((vimglenptr = dlsym(lib,HEAP_IMAGE_LEN_SYMBOL)) == NULL)      die("unable to find length of in-core heap image\n");

	    inbuf.file      = NULL;
	    inbuf.needs_to_be_byteswapped = FALSE;

	    inbuf.base      = vimg;
	    inbuf.buf       = inbuf.base;
	    inbuf.nbytes    = *(long*)vimglenptr;
        #else
	    die("in-core heap images not implemented\n");
        #endif
    }

    READ(&inbuf, image_header);

    if (image_header.byte_order != ORDER)						die ("incorrect byte order in heap image\n");
    if (image_header.magic != IMAGE_MAGIC)						die ("bad magic number (%#x) in heap image\n", image_header.magic);
    if ((image_header.kind != EXPORT_HEAP_IMAGE) && (image_header.kind != EXPORT_FN_IMAGE))	die ("bad image kind (%d) in heap image\n", image_header.kind);

    READ(&inbuf, heap_header);

    // Check for command-line overrides of heap parameters:
    //
    if (params->agegroup0_buffer_bytesize == 0) {
        params->agegroup0_buffer_bytesize = heap_header.agegroup0_buffer_bytesize;
    }
    if (params->active_agegroups < heap_header.active_agegroups) {
        params->active_agegroups = heap_header.active_agegroups;
    }
    if (params->oldest_agegroup_retaining_fromspace_sibs_between_heapcleanings < 0) {
        params->oldest_agegroup_retaining_fromspace_sibs_between_heapcleanings = heap_header.oldest_agegroup_retaining_fromspace_sibs_between_heapcleanings;
    } 

    task = make_task( /*is_boot:*/FALSE, params );					// make_task		def in   src/c/main/runtime-state.c

    // Get the run-time pointers into the heap:
    //
    *PTR_CAST( Val*, PERVASIVE_PACKAGE_PICKLE_LIST_REFCELL__GLOBAL )
        =
        heap_header.pervasive_package_pickle_list;

    // This carefully constructed fake looks like a normal
    // compiled package from the Mythryl side but actually
    // links to compile C code -- see the hack in
    //	
    //     src/c/main/load-compiledfiles.c
    //
    runtime_package__global =  heap_header.runtime_pseudopackage;

    #ifdef ASM_MATH
	mathvec__global = heap_header.math_package;
    #endif


    externs = heapio__read_externs_table (&inbuf);				// Read the externals table.

    READ(&inbuf, image);							// Read and initialize the Mythryl state info.
    //
    if (image_header.kind == EXPORT_HEAP_IMAGE) {

        // Load the live registers:
        //
	ASSIGN( POSIX_INTERPROCESS_SIGNAL_HANDLER_REFCELL__GLOBAL,
                image.posix_interprocess_signal_handler
              );
	//
	task->argument		= image.stdArg;
	task->fate		= image.stdCont;
	task->current_closure	= image.stdClos;
	task->program_counter	= image.pc;
	task->exception_fate	= image.exception_fate;
	task->current_thread	= image.current_thread;
	//
	task->callee_saved_registers[0]	= image.calleeSave[0];
	task->callee_saved_registers[1]	= image.calleeSave[1];
	task->callee_saved_registers[2]	= image.calleeSave[2];

	read_heap (&inbuf, &heap_header, task, externs);			// Read the Mythryl heap.

	/* heapcleaner_messages_are_enabled__global = TRUE; */			// Heapcleaning messages are on by default for interactive images.

    } else { 									// EXPORT_FN_IMAGE

        // Restore the signal handler:
        //
	ASSIGN( POSIX_INTERPROCESS_SIGNAL_HANDLER_REFCELL__GLOBAL, image.posix_interprocess_signal_handler );

        // Read the Mythryl heap:
        //
	task->argument		= image.stdArg;
	read_heap (&inbuf, &heap_header, task, externs);

        // Initialize the calling context (taken from run_mythryl_function__may_heapclean):			// run_mythryl_function__may_heapclean	def in   src/c/main/run-mythryl-code-and-runtime-eventloop.c
        //
	Val function_to_run	= task->argument;
	//
	task->exception_fate	= PTR_CAST( Val,  handle_uncaught_exception_closure_v + 1 );
	task->current_thread	= HEAP_VOID;
	//
	task->fate		= PTR_CAST( Val,  return_to_c_level_c );
	task->current_closure	= function_to_run;
	//
	task->program_counter	=
	task->link_register	= GET_CODE_ADDRESS_FROM_CLOSURE( function_to_run );				// Last use of 'function_to_run'.

        // Set up the arguments to the imported function:
        //
	Val program_name =  make_ascii_string_from_c_string__may_heapclean(task, mythryl_program_name__global, extra_roots);		Roots roots1 = { &program_name, extra_roots };
        //
	Val args         =  make_ascii_strings_from_vector_of_c_strings__may_heapclean (task, commandline_args_without_argv0_or_runtime_args__global, &roots1 );

	task->argument = make_two_slot_record( task, program_name, args );

	// debug_say("arg = %#x : [%#x, %#x]\n", task->argument, GET_TUPLE_SLOT_AS_VAL(task->argument, 0), GET_TUPLE_SLOT_AS_VAL(task->argument, 1));

        // Heapcleaner messages are off by
        // default for spawn_to_disk images:
        //
	heapcleaner_messages_are_enabled__global =  FALSE;
    }

    FREE( externs );

    if (inbuf.file)   fclose (inbuf.file);

    if (verbosity__global > 0)   say(" done\n");

    return task;
}								// fun import_heap_image__may_heapclean