예제 #1
0
int
main(int argc, char **argv)
{
    time_t now;
    char time_buffer[32];

    if (argc < 2) {
        (void) fprintf(stderr, "Usage: %s <command> ...\n", argv[0]);
        exit(1);
    }

    rotate_logs();
    redirect_output();
    disable_cores();
    dump_privs();
    dump_args(argc, argv);

    /* get the current time for the log */
    time(&now);
    cftime(time_buffer, "%Y-%m-%dT%H:%M:%SZ", &now);

    /* print the header for the output from the program we exec (pre-flush) */
    (void) printf("=== OUTPUT (%s) ===\n", time_buffer);

    /* flush before next cmd takes over */
    (void) fflush(stdout);
    (void) fflush(stderr);

    exec_next(argc, argv);

    /* if we got here, we failed */
    (void) fprintf(stderr, "FATAL: execvp() failed.\n");
    exit(1);
}
예제 #2
0
int
main(int argc, char **argv)
{
    if (argc < 2) {
        (void) fprintf(stderr, "Usage: %s <command> ...\n", argv[0]);
        exit(1);
    }

    rotate_logs();
    redirect_output();
    dump_privs();
    dump_args(argc, argv);

    /* print the header for the output from the program we exec (pre-flush) */
    (void) puts("=== OUTPUT ===");

    /* flush before next cmd takes over */
    (void) fflush(stdout);
    (void) fflush(stderr);

    exec_next(argc, argv);

    /* if we got here, we failed */
    (void) fprintf(stderr, "FATAL: execvp() failed.\n");
    exit(1);
}
예제 #3
0
파일: menu2.c 프로젝트: j-a-r-i/StmMeasure
void act_timer_begin(uint8_t len, uint8_t *args)
{
    dump_args(len, args);
    sche_set_start(args[0],
		   args[1]*10 + args[2],
		   args[3]*10 + args[4]);
}
예제 #4
0
static int do_ipconfig(int argc, char *argv[])
{
	int i, a = 0;
	char **args = alloca((argc + 3) * sizeof(char *));

	if (!args)
		return -1;

	args[a++] = (char *)"IP-Config";
	args[a++] = (char *)"-i";
	args[a++] = (char *)"Linux kinit";

	DEBUG(("Running ipconfig\n"));

	for (i = 1; i < argc; i++) {
		if (strncmp(argv[i], "ip=", 3) == 0 ||
		    strncmp(argv[i], "nfsaddrs=", 9) == 0) {
			args[a++] = argv[i];
		}
	}

	if (a > 1) {
		args[a] = NULL;
		dump_args(a, args);
		return ipconfig_main(a, args);
	}

	return 0;
}
예제 #5
0
파일: menu2.c 프로젝트: j-a-r-i/StmMeasure
void act_timer_end(uint8_t len, uint8_t *args)
{
    dump_args(len, args);
    sche_set_stop(args[0],
		  args[1]*10 + args[2],
		  args[3]*10 + args[4]);
}
예제 #6
0
파일: gem_exe.c 프로젝트: Azolo/gem-exefy
int
main(int argc, char **argv)
{
    int i;
    int myargc;
    char** myargv;
    char script_path[MAXPATHLEN];
    char* dump_val;
    DWORD attr;

#ifdef HAVE_LOCALE_H
    setlocale(LC_CTYPE, "");
#endif

    dump_val = getenv("EXEFY_DUMP");

    if (GetModuleFileName(NULL, script_path, MAXPATHLEN)) {
        for (i = strlen(script_path) - 1; i >= 0; --i) {
            if (*(script_path + i) == '.') {
                *(script_path + i) = '\0';
                break;
            }
        }

        attr = GetFileAttributes(script_path);
        if (attr == INVALID_FILE_ATTRIBUTES) {
            printf("Script %s is missing!", script_path);
            return -1;
        }
        // Let Ruby initialize program arguments
        ruby_sysinit(&argc, &argv);

        // Change arguments by inserting path to script file
        // as second argument (first argument is always executable
        // name) and copying arguments from command line after it.
        myargc = argc + 1;
        myargv = (char**)xmalloc(sizeof(char*) * (myargc + 1));
        memset(myargv, 0, sizeof(char*) * (myargc + 1));
        *myargv = *argv;
        *(myargv + 1) = &script_path[0];

        for (i = 1; i < argc; ++i) {
            *(myargv + i + 1) = *(argv + i);
        }

        if (NULL != dump_val) {
            dump_args(myargc, myargv);
        }

        {
            RUBY_INIT_STACK;
            ruby_init();
            return ruby_run_node(ruby_options(myargc, myargv));
        }
    }
}
예제 #7
0
파일: main.c 프로젝트: taysom/tau
void process_command (char *line)
{
	int	argc;
	char	**argv;

	if (setjmp(Err_jmp)) return;
	argc = line2argv(line, &argv);
	execute(argc, argv);
	if (debug_is_on()) dump_args(argc, argv);
}
예제 #8
0
파일: main.c 프로젝트: taysom/tau
int main (int argc, char *argv[])
{
	char	*line;
	char	*s;
	int	c;

	while ((c = getopt(argc, argv, "dv?")) != -1) {
		switch (c) {
		case 'd':
			Debug = TRUE;
			break;
		case 'v':
			Zerofill = TRUE;
			break;
		case '?':
		default:
			usage();
			exit(1);
			break;
		}
	}
	initsyms();
	initkmem();

	initeval();

	setjmp(Err_jmp);
	for (;;) {
#if READLINE IS_ENABLED
		line = readline("> ");	/* use getline on OS-X */
		if (!line) {
			break;
		}
		s = stripwhite(line);
		if (*s) {
			add_history(s);
		}
#else
		ssize_t	rc;
		size_t	n;
		printf("? ");
		fflush(stdin);
		line = NULL;
		rc = getline( &line, &n, stdin);
		s = stripwhite(line);
#endif
		parse_line(s);
		if (Debug) dump_args();
		invokeCmd(Argc, Argv);
		free(line);
	}
	printf("\n");
	return 0;
}
예제 #9
0
파일: testmpi.c 프로젝트: jcazzie/chapel
/* called by a single thread before gasnet_init */
void init_test_mpi(int *argc, char ***argv) {
    int initialized = 0;

    #if 0
      dump_args(*argc, *argv);
    #endif

    /* initialize MPI, if necessary */
    MPI_SAFE(MPI_Initialized(&initialized));
    if (!initialized) {
      printf("Initializing MPI...\n");
      MPI_SAFE(MPI_Init(argc, argv));
    }

    #if 0
      dump_args(*argc, *argv);
    #endif

    MPI_SAFE(MPI_Barrier(MPI_COMM_WORLD));
}
예제 #10
0
파일: aes-pipe.c 프로젝트: flihp/aes-pipe
int
main (int argc, char* argv[])
{
    args_t args = { 0, };
    crypt_data_t crypt_data = { 0, };
    ssize_t count = 0;
    crypt_init_t init_func = NULL;
    crypt_update_t update_func = NULL;
    crypt_final_t final_func = NULL;

    parse_args (argc, argv, &args);
    if (check_sanity (argv[0], &args))
        exit (EXIT_FAILURE);
    /*  set global flag  */
    verbose = args.verbose;
    if (verbose)
        dump_args (&args);

    crypt_data.keysize = get_key (args.keyfile, crypt_data.keybuf, EVP_MAX_KEY_LENGTH);
    if (crypt_data.keysize == -1)
        exit (EXIT_FAILURE);
    crypt_data.ivsize = crypt_data.keysize;

    if (args.encrypt) {
        crypt_data.ivsize = iv_write (&crypt_data, STDOUT_FILENO);
        if (crypt_data.ivsize == -1)
            exit (EXIT_FAILURE);
        init_func = &EVP_EncryptInit_ex;
        update_func = &EVP_EncryptUpdate;
        final_func = &EVP_EncryptFinal_ex;
    }
    if (args.decrypt) {
        crypt_data.ivsize = iv_read (&crypt_data, STDIN_FILENO);
        if (crypt_data.ivsize == -1)
            exit (EXIT_FAILURE);
        init_func = &EVP_DecryptInit_ex;
        update_func = &EVP_DecryptUpdate;
        final_func = &EVP_DecryptFinal_ex;
    }
    count = aes_init (&crypt_data, init_func);
    if (count == -1)
        exit (EXIT_FAILURE);
    count = proc_loop (&crypt_data, update_func, final_func);
    if (count == -1)
        exit (EXIT_FAILURE);

    if (verbose)
        fprintf (stderr,
                 "successfully %s %d bytes of data\n",
                 args.encrypt ? "encrypted" : "decrypted",
                 count);

    exit (EXIT_SUCCESS);
}
예제 #11
0
파일: menu2.c 프로젝트: j-a-r-i/StmMeasure
void act_meas_low(uint8_t len, uint8_t *args)
{
    dump_args(len, args);
    meas_set_low_limit(args[0], args[1]*100 + args[2]*10 + args[3]);
}
예제 #12
0
파일: menu2.c 프로젝트: j-a-r-i/StmMeasure
void act_set_clock(uint8_t len, uint8_t *args)
{
    dump_args(len, args);
}
예제 #13
0
int main(int argc, char *argv[])
{
	char **cmdv, **args;
	char *cmdlines[3];
	int i;
	const char *errmsg;
	int ret = 0;
	int cmdc;
	int fd;
	struct timeval now;
	char *mount_argv[] = {"mount_part", "rootfs", "/root"};
	pid_t pid;
	int nandboot = 0;

	gettimeofday(&now, NULL);
	srand48(now.tv_usec ^ (now.tv_sec << 24));

	/* Default parameters for anything init-like we execute */
	init_argc = argc;
	init_argv = alloca((argc+1)*sizeof(char *));
	memcpy(init_argv, argv, (argc+1)*sizeof(char *));

	/*
	 * omit /dev/console when generating initramfs,
	 * so we create it dynamically
	 */
	if (access("/dev/console", O_RDWR)) {
		mknod("/dev/console", S_IFCHR|0644, makedev(5, 1));
	}

	if ((fd = open("/dev/console", O_RDWR)) != -1) {
		dup2(fd, STDIN_FILENO);
		dup2(fd, STDOUT_FILENO);
		dup2(fd, STDERR_FILENO);

		if (fd > STDERR_FILENO) {
			close(fd);
		}
	}

	mnt_procfs = mount_sys_fs("/proc/cmdline", "/proc", "proc") >= 0;
	if (!mnt_procfs) {
		ret = 1;
		goto bail;
	}

	mnt_sysfs = mount_sys_fs("/sys/bus", "/sys", "sysfs") >= 0;
	if (!mnt_sysfs) {
		ret = 1;
		goto bail;
	}

	/* Construct the effective kernel command line.  The
	   effective kernel command line consists of /arch.cmd, if
	   it exists, /proc/cmdline, plus any arguments after an --
	   argument on the proper command line, in that order. */

	ret = readfile("/arch.cmd", &cmdlines[0]);
	if (ret < 0)
		cmdlines[0] = "";

	ret = readfile("/proc/cmdline", &cmdlines[1]);
	if (ret < 0) {
		fprintf(stderr, "%s: cannot read /proc/cmdline\n", progname);
		ret = 1;
		goto bail;
	}

	cmdlines[2] = NULL;

	/* Find an -- argument, and if so append to the command line */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "--")) {
			i++;
			break;
		}
	}
	args = &argv[i];	/* Points either to first argument past -- or
				   to the final NULL */

	/* Count the number of arguments */
	cmdc = split_cmdline(INT_MAX, NULL, argv[0], cmdlines, args);

	/* Actually generate the cmdline array */
	cmdv = (char **)alloca((cmdc+1)*sizeof(char *));
	if (split_cmdline(cmdc, cmdv, argv[0], cmdlines, args) != cmdc) {
		ret = 1;
		goto bail;
	}

	/* Debugging... */
	dump_args(cmdc, cmdv);

	{
		const char * root_device_name = get_arg(cmdc, cmdv, "root=");
		if (strncmp(root_device_name, "/dev/mtdblock", strlen("/dev/mtdblock")) == 0) {
			nandboot = 1;
			printf("kinit: NAND mode, check online upgrade flag\n");
			do_rootfs_OU();
		} else {
			nandboot = 0;
			printf("kinit: None-NAND mode, ignore online upgrade flag\n");
		}
	}

	/* Resume from suspend-to-disk, if appropriate */
	/* If successful, does not return */
	do_resume(cmdc, cmdv);

	/* Initialize networking, if applicable */
	do_ipconfig(cmdc, cmdv);

	check_path("/root");

	if (nandboot) {
		int index = 0;
		while (1) {
			char name[128];
			snprintf(name, sizeof(name), "/sys/block/mtdblock%d", index);
			if (access(name, F_OK) == 0) {
				snprintf(name, sizeof(name), "/dev/mtdblock%d", index);
				create_dev(name, name_to_dev_t(name));
				index++;
			} else {
				break;
			}
		}
		if((pid=fork())<0)
			fprintf(stderr, "fork error.\n");
		else if(pid == 0)
		{
			if((ret = execve("/bin/mount_part", mount_argv, NULL)) <0)
				perror("excute mount_part error\n");
		}
		if(waitpid(pid, NULL, 0) < 0)
			fprintf(stderr, "wait mount_part error.\n");
	} else {
		do_mounts(cmdc, cmdv);
	}

	if (mnt_procfs) {
		umount2("/proc", 0);
		mnt_procfs = 0;
	}

	if (mnt_sysfs) {
		umount2("/sys", 0);
		mnt_sysfs = 0;
	}

	make_devices();

	init_path = find_init("/root", get_arg(cmdc, cmdv, "init="));
	if (!init_path) {
		fprintf(stderr, "%s: init not found!\n", progname);
		ret = 2;
		goto bail;
	}
	DEBUG(("kinit: init_path = %s, init=%s\n", init_path, get_arg(cmdc, cmdv, "init=")));

	init_argv[0] = strrchr(init_path, '/') + 1;

	errmsg = run_init("/root", "/dev/console", init_path, init_argv);

	/* If run_init returned, something went bad */
	fprintf(stderr, "%s: %s: %s\n", progname, errmsg, strerror(errno));
	ret = 2;
	goto bail;

bail:
	if (mnt_procfs)
		umount2("/proc", 0);

	if (mnt_sysfs)
		umount2("/sys", 0);

	/*
	 * If we get here, something bad probably happened, and the kernel
	 * will most likely panic.  Drain console output so the user can
	 * figure out what happened.
	 */
	tcdrain(2);
	tcdrain(1);

	return ret;
}
예제 #14
0
파일: bc.c 프로젝트: KnightSch/micropython
// On entry code_state should be allocated somewhere (stack/heap) and
// contain the following valid entries:
//    - code_state->ip should contain the offset in bytes from the start of
//      the bytecode chunk to just after n_state and n_exc_stack
//    - code_state->n_state should be set to the state size (locals plus stack)
void mp_setup_code_state(mp_code_state *code_state, mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    // This function is pretty complicated.  It's main aim is to be efficient in speed and RAM
    // usage for the common case of positional only args.
    size_t n_state = code_state->n_state;

    // ip comes in as an offset into bytecode, so turn it into a true pointer
    code_state->ip = self->bytecode + (size_t)code_state->ip;

    // store pointer to constant table
    code_state->const_table = self->const_table;

    #if MICROPY_STACKLESS
    code_state->prev = NULL;
    #endif

    // get params
    size_t scope_flags = *code_state->ip++;
    size_t n_pos_args = *code_state->ip++;
    size_t n_kwonly_args = *code_state->ip++;
    size_t n_def_pos_args = *code_state->ip++;

    code_state->sp = &code_state->state[0] - 1;
    code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;

    // zero out the local stack to begin with
    memset(code_state->state, 0, n_state * sizeof(*code_state->state));

    const mp_obj_t *kwargs = args + n_args;

    // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed)
    mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - n_pos_args - n_kwonly_args];

    // check positional arguments

    if (n_args > n_pos_args) {
        // given more than enough arguments
        if ((scope_flags & MP_SCOPE_FLAG_VARARGS) == 0) {
            fun_pos_args_mismatch(self, n_pos_args, n_args);
        }
        // put extra arguments in varargs tuple
        *var_pos_kw_args-- = mp_obj_new_tuple(n_args - n_pos_args, args + n_pos_args);
        n_args = n_pos_args;
    } else {
        if ((scope_flags & MP_SCOPE_FLAG_VARARGS) != 0) {
            DEBUG_printf("passing empty tuple as *args\n");
            *var_pos_kw_args-- = mp_const_empty_tuple;
        }
        // Apply processing and check below only if we don't have kwargs,
        // otherwise, kw handling code below has own extensive checks.
        if (n_kw == 0 && (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) == 0) {
            if (n_args >= (size_t)(n_pos_args - n_def_pos_args)) {
                // given enough arguments, but may need to use some default arguments
                for (size_t i = n_args; i < n_pos_args; i++) {
                    code_state->state[n_state - 1 - i] = self->extra_args[i - (n_pos_args - n_def_pos_args)];
                }
            } else {
                fun_pos_args_mismatch(self, n_pos_args - n_def_pos_args, n_args);
            }
        }
    }

    // copy positional args into state
    for (size_t i = 0; i < n_args; i++) {
        code_state->state[n_state - 1 - i] = args[i];
    }

    // check keyword arguments

    if (n_kw != 0 || (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) {
        DEBUG_printf("Initial args: ");
        dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);

        mp_obj_t dict = MP_OBJ_NULL;
        if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
            dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0?
            *var_pos_kw_args = dict;
        }

        // get pointer to arg_names array
        const mp_obj_t *arg_names = (const mp_obj_t*)code_state->const_table;

        for (size_t i = 0; i < n_kw; i++) {
            mp_obj_t wanted_arg_name = kwargs[2 * i];
            for (size_t j = 0; j < n_pos_args + n_kwonly_args; j++) {
                if (wanted_arg_name == arg_names[j]) {
                    if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
                        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                            "function got multiple values for argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name)));
                    }
                    code_state->state[n_state - 1 - j] = kwargs[2 * i + 1];
                    goto continue2;
                }
            }
            // Didn't find name match with positional args
            if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) {
                nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
            }
            mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
continue2:;
        }

        DEBUG_printf("Args with kws flattened: ");
        dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);

        // fill in defaults for positional args
        mp_obj_t *d = &code_state->state[n_state - n_pos_args];
        mp_obj_t *s = &self->extra_args[n_def_pos_args - 1];
        for (size_t i = n_def_pos_args; i > 0; i--, d++, s--) {
            if (*d == MP_OBJ_NULL) {
                *d = *s;
            }
        }

        DEBUG_printf("Args after filling default positional: ");
        dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);

        // Check that all mandatory positional args are specified
        while (d < &code_state->state[n_state]) {
            if (*d++ == MP_OBJ_NULL) {
                nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                    "function missing required positional argument #%d", &code_state->state[n_state] - d));
            }
        }

        // Check that all mandatory keyword args are specified
        // Fill in default kw args if we have them
        for (size_t i = 0; i < n_kwonly_args; i++) {
            if (code_state->state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) {
                mp_map_elem_t *elem = NULL;
                if ((scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) {
                    elem = mp_map_lookup(&((mp_obj_dict_t*)MP_OBJ_TO_PTR(self->extra_args[n_def_pos_args]))->map, arg_names[n_pos_args + i], MP_MAP_LOOKUP);
                }
                if (elem != NULL) {
                    code_state->state[n_state - 1 - n_pos_args - i] = elem->value;
                } else {
                    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                        "function missing required keyword argument '%q'", MP_OBJ_QSTR_VALUE(arg_names[n_pos_args + i])));
                }
            }
        }

    } else {
        // no keyword arguments given
        if (n_kwonly_args != 0) {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                "function missing keyword-only argument"));
        }
        if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
            *var_pos_kw_args = mp_obj_new_dict(0);
        }
    }

    // get the ip and skip argument names
    const byte *ip = code_state->ip;

    // store pointer to code_info and jump over it
    {
        code_state->code_info = ip;
        const byte *ip2 = ip;
        size_t code_info_size = mp_decode_uint(&ip2);
        ip += code_info_size;
    }

    // bytecode prelude: initialise closed over variables
    size_t local_num;
    while ((local_num = *ip++) != 255) {
        code_state->state[n_state - 1 - local_num] =
            mp_obj_new_cell(code_state->state[n_state - 1 - local_num]);
    }

    // now that we skipped over the prelude, set the ip for the VM
    code_state->ip = ip;

    DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", n_pos_args, n_kwonly_args);
    dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args);
    dump_args(code_state->state, n_state);
}
예제 #15
0
파일: menu2.c 프로젝트: j-a-r-i/StmMeasure
void act_timer_activate(uint8_t len, uint8_t *args)
{
    dump_args(len, args);
}
예제 #16
0
int main(int argc, const char ** argv)
{
	int i;
	const char ** dd_args;
	struct tevent_context *ev;

	poptContext pctx;
	struct poptOption poptions[] = {
		/* POPT_AUTOHELP */
		{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, cifsddHelpOptions,
			0, "Help options:", NULL },
		POPT_COMMON_SAMBA
		POPT_COMMON_CONNECTION
		POPT_COMMON_CREDENTIALS
		POPT_COMMON_VERSION
		{ NULL }
	};

	/* Block sizes. */
	set_arg_val("bs", (uint64_t)4096);
	set_arg_val("ibs", (uint64_t)4096);
	set_arg_val("obs", (uint64_t)4096);
	/* Block counts. */
	set_arg_val("count", (uint64_t)-1);
	set_arg_val("seek", (uint64_t)0);
	set_arg_val("seek", (uint64_t)0);
	/* Files. */
	set_arg_val("if", NULL);
	set_arg_val("of", NULL);
	/* Options. */
	set_arg_val("direct", false);
	set_arg_val("sync", false);
	set_arg_val("oplock", false);

	pctx = poptGetContext(PROGNAME, argc, argv, poptions, 0);
	while ((i = poptGetNextOpt(pctx)) != -1) {
		;
	}

	for (dd_args = poptGetArgs(pctx); dd_args && *dd_args; ++dd_args) {

		if (!set_arg_argv(*dd_args)) {
			fprintf(stderr, "%s: invalid option: %s\n",
					PROGNAME, *dd_args);
			exit(SYNTAX_EXIT_CODE);
		}

		/* "bs" has the side-effect of setting "ibs" and "obs". */
		if (strncmp(*dd_args, "bs=", 3) == 0) {
			uint64_t bs = check_arg_numeric("bs");
			set_arg_val("ibs", bs);
			set_arg_val("obs", bs);
		}
	}

	ev = s4_event_context_init(talloc_autofree_context());

	gensec_init(cmdline_lp_ctx);
	dump_args();

	if (check_arg_numeric("ibs") == 0 || check_arg_numeric("ibs") == 0) {
		fprintf(stderr, "%s: block sizes must be greater that zero\n",
				PROGNAME);
		exit(SYNTAX_EXIT_CODE);
	}

	if (check_arg_pathname("if") == NULL) {
		fprintf(stderr, "%s: missing input filename\n", PROGNAME);
		exit(SYNTAX_EXIT_CODE);
	}

	if (check_arg_pathname("of") == NULL) {
		fprintf(stderr, "%s: missing output filename\n", PROGNAME);
		exit(SYNTAX_EXIT_CODE);
	}

	CatchSignal(SIGINT, dd_handle_signal);
	CatchSignal(SIGUSR1, dd_handle_signal);
	return(copy_files(ev, cmdline_lp_ctx));
}
예제 #17
0
void dump_decl(decl *d, dump *ctx, const char *desc)
{
	const int is_func = !!type_is(d->ref, type_func);
	type *ty;

	if(!desc){
		if(d->spel){
			desc = is_func ? "function" : "variable";
		}else{
			desc = "type";
		}
	}

	dump_desc_colour_newline(ctx, desc, d, &d->where,
			maybe_colour(ctx->fout, col_desc_decl), 0);

	if(d->proto)
		dump_printf_indent(ctx, 0, " prev %p", (void *)d->proto);

	if(d->spel)
		dump_printf_indent(ctx, 0, " %s", d->spel);

	dump_type(ctx, d->ref);

	if(d->store)
		dump_printf_indent(ctx, 0, " %s", decl_store_to_str(d->store));

	dump_printf_indent(ctx, 0, "\n");

	if(!is_func){
		type *tof = type_skip_non_tdefs(d->ref);
		if(tof->type == type_tdef && !tof->bits.tdef.decl){
			/* show typeof expr */
			dump_inc(ctx);
			dump_expr(tof->bits.tdef.type_of, ctx);
			dump_dec(ctx);
		}

		if(d->bits.var.field_width){
			dump_inc(ctx);
			dump_expr(d->bits.var.field_width, ctx);
			dump_dec(ctx);
		}

		if(!d->spel){
			dump_sue(ctx, d->ref);
		}else if(d->bits.var.init.dinit){
			dump_inc(ctx);
			dump_init(ctx, d->bits.var.init.dinit);
			dump_dec(ctx);
		}
	}

	dump_inc(ctx);
	dump_attributes(d->attr, ctx);
	ty = type_skip_non_attr(d->ref);
	if(ty && ty->type == type_attr)
		dump_attributes(ty->bits.attr, ctx);
	dump_dec(ctx);

	if(is_func && d->bits.func.code){
		funcargs *fa = type_funcargs(d->ref);

		dump_inc(ctx);
		dump_args(fa, ctx);
		dump_stmt(d->bits.func.code, ctx);
		dump_dec(ctx);
	}
}
예제 #18
0
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    MP_STACK_CHECK();

    DEBUG_printf("Input n_args: " UINT_FMT ", n_kw: " UINT_FMT "\n", n_args, n_kw);
    DEBUG_printf("Input pos args: ");
    dump_args(args, n_args);
    DEBUG_printf("Input kw args: ");
    dump_args(args + n_args, n_kw * 2);
    mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in);
    DEBUG_printf("Func n_def_args: %d\n", self->n_def_args);

    // get start of bytecode
    const byte *ip = self->bytecode;

    // bytecode prelude: state size and exception stack size
    mp_uint_t n_state = mp_decode_uint(&ip);
    mp_uint_t n_exc_stack = mp_decode_uint(&ip);

#if VM_DETECT_STACK_OVERFLOW
    n_state += 1;
#endif

    // allocate state for locals and stack
    mp_uint_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
    mp_code_state_t *code_state = NULL;
    if (state_size > VM_MAX_STATE_ON_STACK) {
        code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
    }
    if (code_state == NULL) {
        code_state = alloca(sizeof(mp_code_state_t) + state_size);
        state_size = 0; // indicate that we allocated using alloca
    }

    code_state->ip = (byte*)(ip - self->bytecode); // offset to after n_state/n_exc_stack
    code_state->n_state = n_state;
    mp_setup_code_state(code_state, self, n_args, n_kw, args);

    // execute the byte code with the correct globals context
    code_state->old_globals = mp_globals_get();
    mp_globals_set(self->globals);
    mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(code_state, MP_OBJ_NULL);
    mp_globals_set(code_state->old_globals);

#if VM_DETECT_STACK_OVERFLOW
    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        if (code_state->sp < code_state->state) {
            printf("VM stack underflow: " INT_FMT "\n", code_state->sp - code_state->state);
            assert(0);
        }
    }
    // We can't check the case when an exception is returned in state[n_state - 1]
    // and there are no arguments, because in this case our detection slot may have
    // been overwritten by the returned exception (which is allowed).
    if (!(vm_return_kind == MP_VM_RETURN_EXCEPTION && self->n_pos_args + self->n_kwonly_args == 0)) {
        // Just check to see that we have at least 1 null object left in the state.
        bool overflow = true;
        for (mp_uint_t i = 0; i < n_state - self->n_pos_args - self->n_kwonly_args; i++) {
            if (code_state->state[i] == MP_OBJ_NULL) {
                overflow = false;
                break;
            }
        }
        if (overflow) {
            printf("VM stack overflow state=%p n_state+1=" UINT_FMT "\n", code_state->state, n_state);
            assert(0);
        }
    }
#endif

    mp_obj_t result;
    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        // return value is in *sp
        result = *code_state->sp;
    } else {
        // must be an exception because normal functions can't yield
        assert(vm_return_kind == MP_VM_RETURN_EXCEPTION);
        // return value is in fastn[0]==state[n_state - 1]
        result = code_state->state[n_state - 1];
    }

    // free the state if it was allocated on the heap
    if (state_size != 0) {
        m_del_var(mp_code_state_t, byte, state_size, code_state);
    }

    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        return result;
    } else { // MP_VM_RETURN_EXCEPTION
        nlr_raise(result);
    }
}
예제 #19
0
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
    DEBUG_printf("Input: ");
    dump_args(args, n_args);
    mp_obj_fun_bc_t *self = self_in;

    const mp_obj_t *kwargs = args + n_args;
    mp_obj_t *extra_args = self->extra_args + self->n_def_args;
    uint n_extra_args = 0;


    // check positional arguments

    if (n_args > self->n_args) {
        // given more than enough arguments
        if (!self->takes_var_args) {
            goto arg_error;
        }
        // put extra arguments in varargs tuple
        *extra_args = mp_obj_new_tuple(n_args - self->n_args, args + self->n_args);
        n_extra_args = 1;
        n_args = self->n_args;
    } else {
        if (self->takes_var_args) {
            DEBUG_printf("passing empty tuple as *args\n");
            *extra_args = mp_const_empty_tuple;
            n_extra_args = 1;
        }
        // Apply processing and check below only if we don't have kwargs,
        // otherwise, kw handling code below has own extensive checks.
        if (n_kw == 0) {
            if (n_args >= self->n_args - self->n_def_args) {
                // given enough arguments, but may need to use some default arguments
                extra_args -= self->n_args - n_args;
                n_extra_args += self->n_args - n_args;
            } else {
                goto arg_error;
            }
        }
    }

    // check keyword arguments

    if (n_kw != 0) {
        // We cannot use dynamically-sized array here, because GCC indeed
        // deallocates it on leaving defining scope (unlike most static stack allocs).
        // So, we have 2 choices: allocate it unconditionally at the top of function
        // (wastes stack), or use alloca which is guaranteed to dealloc on func exit.
        //mp_obj_t flat_args[self->n_args];
        mp_obj_t *flat_args = alloca(self->n_args * sizeof(mp_obj_t));
        for (int i = self->n_args - 1; i >= 0; i--) {
            flat_args[i] = MP_OBJ_NULL;
        }
        memcpy(flat_args, args, sizeof(*args) * n_args);
        DEBUG_printf("Initial args: ");
        dump_args(flat_args, self->n_args);

        mp_obj_t dict = MP_OBJ_NULL;
        if (self->takes_kw_args) {
            dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0?
        }
        for (uint i = 0; i < n_kw; i++) {
            qstr arg_name = MP_OBJ_QSTR_VALUE(kwargs[2 * i]);
            for (uint j = 0; j < self->n_args; j++) {
                if (arg_name == self->args[j]) {
                    if (flat_args[j] != MP_OBJ_NULL) {
                        nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                            "function got multiple values for argument '%s'", qstr_str(arg_name)));
                    }
                    flat_args[j] = kwargs[2 * i + 1];
                    goto continue2;
                }
            }
            // Didn't find name match with positional args
            if (!self->takes_kw_args) {
                nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
            }
            mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
continue2:;
        }
        DEBUG_printf("Args with kws flattened: ");
        dump_args(flat_args, self->n_args);

        // Now fill in defaults
        mp_obj_t *d = &flat_args[self->n_args - 1];
        mp_obj_t *s = &self->extra_args[self->n_def_args - 1];
        for (int i = self->n_def_args; i > 0; i--) {
            if (*d == MP_OBJ_NULL) {
                *d-- = *s--;
            }
        }
        DEBUG_printf("Args after filling defaults: ");
        dump_args(flat_args, self->n_args);

        // Now check that all mandatory args specified
        while (d >= flat_args) {
            if (*d-- == MP_OBJ_NULL) {
                nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                    "function missing required positional argument #%d", d - flat_args));
            }
        }

        args = flat_args;
        n_args = self->n_args;

        if (self->takes_kw_args) {
            extra_args[n_extra_args] = dict;
            n_extra_args += 1;
        }
    } else {
        // no keyword arguments given
        if (self->takes_kw_args) {
            extra_args[n_extra_args] = mp_obj_new_dict(0);
            n_extra_args += 1;
        }
    }

    mp_map_t *old_globals = mp_globals_get();
    mp_globals_set(self->globals);
    mp_obj_t result;
    DEBUG_printf("Calling: args=%p, n_args=%d, extra_args=%p, n_extra_args=%d\n", args, n_args, extra_args, n_extra_args);
    dump_args(args, n_args);
    dump_args(extra_args, n_extra_args);
    mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code(self->bytecode, args, n_args, extra_args, n_extra_args, &result);
    mp_globals_set(old_globals);

    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        return result;
    } else { // MP_VM_RETURN_EXCEPTION
        nlr_jump(result);
    }

arg_error:
    nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
}
예제 #20
0
파일: objfun.c 프로젝트: Rosuav/micropython
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
    // This function is pretty complicated.  It's main aim is to be efficient in speed and RAM
    // usage for the common case of positional only args.

    DEBUG_printf("Input n_args: %d, n_kw: %d\n", n_args, n_kw);
    DEBUG_printf("Input pos args: ");
    dump_args(args, n_args);
    DEBUG_printf("Input kw args: ");
    dump_args(args + n_args, n_kw * 2);
    mp_obj_fun_bc_t *self = self_in;
    DEBUG_printf("Func n_def_args: %d\n", self->n_def_args);

    const byte *ip = self->bytecode;

    // get code info size, and skip line number table
    machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
    ip += code_info_size;

    // bytecode prelude: state size and exception stack size; 16 bit uints
    machine_uint_t n_state = ip[0] | (ip[1] << 8);
    machine_uint_t n_exc_stack = ip[2] | (ip[3] << 8);
    ip += 4;

#if VM_DETECT_STACK_OVERFLOW
    n_state += 1;
#endif

    // allocate state for locals and stack
    uint state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
    mp_code_state *code_state;
    if (state_size > VM_MAX_STATE_ON_STACK) {
        code_state = m_new_obj_var(mp_code_state, byte, state_size);
    } else {
        code_state = alloca(sizeof(mp_code_state) + state_size);
    }

    code_state->code_info = self->bytecode;
    code_state->sp = &code_state->state[0] - 1;
    code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;
    code_state->n_state = n_state;

    // zero out the local stack to begin with
    memset(code_state->state, 0, n_state * sizeof(*code_state->state));

    const mp_obj_t *kwargs = args + n_args;

    // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed)
    mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - self->n_pos_args - self->n_kwonly_args];

    // check positional arguments

    if (n_args > self->n_pos_args) {
        // given more than enough arguments
        if (!self->takes_var_args) {
            fun_pos_args_mismatch(self, self->n_pos_args, n_args);
        }
        // put extra arguments in varargs tuple
        *var_pos_kw_args-- = mp_obj_new_tuple(n_args - self->n_pos_args, args + self->n_pos_args);
        n_args = self->n_pos_args;
    } else {
        if (self->takes_var_args) {
            DEBUG_printf("passing empty tuple as *args\n");
            *var_pos_kw_args-- = mp_const_empty_tuple;
        }
        // Apply processing and check below only if we don't have kwargs,
        // otherwise, kw handling code below has own extensive checks.
        if (n_kw == 0 && !self->has_def_kw_args) {
            if (n_args >= self->n_pos_args - self->n_def_args) {
                // given enough arguments, but may need to use some default arguments
                for (uint i = n_args; i < self->n_pos_args; i++) {
                    code_state->state[n_state - 1 - i] = self->extra_args[i - (self->n_pos_args - self->n_def_args)];
                }
            } else {
                fun_pos_args_mismatch(self, self->n_pos_args - self->n_def_args, n_args);
            }
        }
    }

    // copy positional args into state
    for (uint i = 0; i < n_args; i++) {
        code_state->state[n_state - 1 - i] = args[i];
    }

    // check keyword arguments

    if (n_kw != 0 || self->has_def_kw_args) {
        DEBUG_printf("Initial args: ");
        dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);

        mp_obj_t dict = MP_OBJ_NULL;
        if (self->takes_kw_args) {
            dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0?
            *var_pos_kw_args = dict;
        }

        for (uint i = 0; i < n_kw; i++) {
            qstr arg_name = MP_OBJ_QSTR_VALUE(kwargs[2 * i]);
            for (uint j = 0; j < self->n_pos_args + self->n_kwonly_args; j++) {
                if (arg_name == self->args[j]) {
                    if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
                        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                            "function got multiple values for argument '%s'", qstr_str(arg_name)));
                    }
                    code_state->state[n_state - 1 - j] = kwargs[2 * i + 1];
                    goto continue2;
                }
            }
            // Didn't find name match with positional args
            if (!self->takes_kw_args) {
                nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
            }
            mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
continue2:;
        }

        DEBUG_printf("Args with kws flattened: ");
        dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);

        // fill in defaults for positional args
        mp_obj_t *d = &code_state->state[n_state - self->n_pos_args];
        mp_obj_t *s = &self->extra_args[self->n_def_args - 1];
        for (int i = self->n_def_args; i > 0; i--, d++, s--) {
            if (*d == MP_OBJ_NULL) {
                *d = *s;
            }
        }

        DEBUG_printf("Args after filling default positional: ");
        dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);

        // Check that all mandatory positional args are specified
        while (d < &code_state->state[n_state]) {
            if (*d++ == MP_OBJ_NULL) {
                nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                    "function missing required positional argument #%d", &code_state->state[n_state] - d));
            }
        }

        // Check that all mandatory keyword args are specified
        // Fill in default kw args if we have them
        for (uint i = 0; i < self->n_kwonly_args; i++) {
            if (code_state->state[n_state - 1 - self->n_pos_args - i] == MP_OBJ_NULL) {
                mp_map_elem_t *elem = NULL;
                if (self->has_def_kw_args) {
                    elem = mp_map_lookup(&((mp_obj_dict_t*)self->extra_args[self->n_def_args])->map, MP_OBJ_NEW_QSTR(self->args[self->n_pos_args + i]), MP_MAP_LOOKUP);
                }
                if (elem != NULL) {
                    code_state->state[n_state - 1 - self->n_pos_args - i] = elem->value;
                } else {
                    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                        "function missing required keyword argument '%s'", qstr_str(self->args[self->n_pos_args + i])));
                }
            }
        }

    } else {
        // no keyword arguments given
        if (self->n_kwonly_args != 0) {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                "function missing keyword-only argument"));
        }
        if (self->takes_kw_args) {
            *var_pos_kw_args = mp_obj_new_dict(0);
        }
    }

    // bytecode prelude: initialise closed over variables
    for (uint n_local = *ip++; n_local > 0; n_local--) {
        uint local_num = *ip++;
        code_state->state[n_state - 1 - local_num] = mp_obj_new_cell(code_state->state[n_state - 1 - local_num]);
    }

    // now that we skipped over the prelude, set the ip for the VM
    code_state->ip = ip;

    DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", self->n_pos_args, self->n_kwonly_args);
    dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);
    dump_args(code_state->state, n_state);

    // execute the byte code with the correct globals context
    mp_obj_dict_t *old_globals = mp_globals_get();
    mp_globals_set(self->globals);
    mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(code_state, MP_OBJ_NULL);
    mp_globals_set(old_globals);

#if VM_DETECT_STACK_OVERFLOW
    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        if (code_state->sp < code_state->state) {
            printf("VM stack underflow: " INT_FMT "\n", code_state->sp - code_state->state);
            assert(0);
        }
    }
    // We can't check the case when an exception is returned in state[n_state - 1]
    // and there are no arguments, because in this case our detection slot may have
    // been overwritten by the returned exception (which is allowed).
    if (!(vm_return_kind == MP_VM_RETURN_EXCEPTION && self->n_pos_args + self->n_kwonly_args == 0)) {
        // Just check to see that we have at least 1 null object left in the state.
        bool overflow = true;
        for (uint i = 0; i < n_state - self->n_pos_args - self->n_kwonly_args; i++) {
            if (code_state->state[i] == MP_OBJ_NULL) {
                overflow = false;
                break;
            }
        }
        if (overflow) {
            printf("VM stack overflow state=%p n_state+1=" UINT_FMT "\n", code_state->state, n_state);
            assert(0);
        }
    }
#endif

    mp_obj_t result;
    switch (vm_return_kind) {
        case MP_VM_RETURN_NORMAL:
            // return value is in *sp
            result = *code_state->sp;
            break;

        case MP_VM_RETURN_EXCEPTION:
            // return value is in state[n_state - 1]
            result = code_state->state[n_state - 1];
            break;

        case MP_VM_RETURN_YIELD: // byte-code shouldn't yield
        default:
            assert(0);
            result = mp_const_none;
            vm_return_kind = MP_VM_RETURN_NORMAL;
            break;
    }

    // free the state if it was allocated on the heap
    if (state_size > VM_MAX_STATE_ON_STACK) {
        m_del_var(mp_code_state, byte, state_size, code_state);
    }

    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        return result;
    } else { // MP_VM_RETURN_EXCEPTION
        nlr_raise(result);
    }
}
예제 #21
0
int mount_nfs_root(int argc, char *argv[], int flags)
{
	(void)flags;		/* FIXME - don't ignore this */

	struct in_addr addr = { INADDR_NONE };
	__u32 client = INADDR_NONE;
	const int len = 1024;
	struct netdev *dev;
	char *mtpt = MOUNT_POINT;
	char *path = NULL;
	char *dev_bootpath = NULL;
	char root[len];
	char *x, *opts;
	int ret = 0;
	int a = 1;
	char *nfs_argv[NFS_ARGC + 1] = { "NFS-Mount" };

	for (dev = ifaces; dev; dev = dev->next) {
		if (dev->ip_server != INADDR_NONE &&
		    dev->ip_server != INADDR_ANY) {
			addr.s_addr = dev->ip_server;
			client = dev->ip_addr;
			dev_bootpath = dev->bootpath;
			break;
		}
		if (dev->ip_addr != INADDR_NONE && dev->ip_addr != INADDR_ANY) {
			client = dev->ip_addr;
		}
	}

	/*
	 * if the "nfsroot" option is set then it overrides
	 * bootpath supplied by the boot server.
	 */
	if ((path = get_arg(argc, argv, "nfsroot=")) == NULL) {
		if ((path = dev_bootpath) == NULL || path[0] == '\0')
			/* no path - set a default */
			path = (char *)"/tftpboot/%s";
	} else if (dev_bootpath && dev_bootpath[0] != '\0')
		fprintf(stderr,
			"nfsroot=%s overrides boot server bootpath %s\n",
			path, dev_bootpath);

	if ((opts = strchr(path, ',')) != NULL) {
		*opts++ = '\0';
		nfs_argv[a++] = (char *)"-o";
		nfs_argv[a++] = opts;
	}

	if ((x = strchr(path, ':')) == NULL) {
		if (addr.s_addr == INADDR_NONE) {
			fprintf(stderr, "Root-NFS: no server defined\n");
			exit(1);
		}

		snprintf(root, len, "%s:%s", inet_ntoa(addr), path);
	} else {
		strcpy(root, path);
	}

	nfs_argv[a++] = sub_client(client, root, len);

	dprintf("NFS-Root: mounting %s on %s with options \"%s\"\n",
		nfs_argv[a-1], mtpt, opts ? opts : "");

	nfs_argv[a++] = mtpt;
	nfs_argv[a] = NULL;
	assert(a <= NFS_ARGC);

	dump_args(a, nfs_argv);

	if ((ret = nfsmount_main(a, nfs_argv)) != 0) {
		ret = -1;
		goto done;
	}

      done:
	return ret;
}
예제 #22
0
// code_state should have ->ip filled in (pointing past code info block),
// as well as ->n_state.
void mp_setup_code_state(mp_code_state *code_state, mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
    mp_obj_fun_bc_t *self = self_in;
    machine_uint_t n_state = code_state->n_state;
    const byte *ip = code_state->ip;

    code_state->code_info = self->bytecode;
    code_state->sp = &code_state->state[0] - 1;
    code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;

    // zero out the local stack to begin with
    memset(code_state->state, 0, n_state * sizeof(*code_state->state));

    const mp_obj_t *kwargs = args + n_args;

    // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed)
    mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - self->n_pos_args - self->n_kwonly_args];

    // check positional arguments

    if (n_args > self->n_pos_args) {
        // given more than enough arguments
        if (!self->takes_var_args) {
            fun_pos_args_mismatch(self, self->n_pos_args, n_args);
        }
        // put extra arguments in varargs tuple
        *var_pos_kw_args-- = mp_obj_new_tuple(n_args - self->n_pos_args, args + self->n_pos_args);
        n_args = self->n_pos_args;
    } else {
        if (self->takes_var_args) {
            DEBUG_printf("passing empty tuple as *args\n");
            *var_pos_kw_args-- = mp_const_empty_tuple;
        }
        // Apply processing and check below only if we don't have kwargs,
        // otherwise, kw handling code below has own extensive checks.
        if (n_kw == 0 && !self->has_def_kw_args) {
            if (n_args >= self->n_pos_args - self->n_def_args) {
                // given enough arguments, but may need to use some default arguments
                for (uint i = n_args; i < self->n_pos_args; i++) {
                    code_state->state[n_state - 1 - i] = self->extra_args[i - (self->n_pos_args - self->n_def_args)];
                }
            } else {
                fun_pos_args_mismatch(self, self->n_pos_args - self->n_def_args, n_args);
            }
        }
    }

    // copy positional args into state
    for (uint i = 0; i < n_args; i++) {
        code_state->state[n_state - 1 - i] = args[i];
    }

    // check keyword arguments

    if (n_kw != 0 || self->has_def_kw_args) {
        DEBUG_printf("Initial args: ");
        dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);

        mp_obj_t dict = MP_OBJ_NULL;
        if (self->takes_kw_args) {
            dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0?
            *var_pos_kw_args = dict;
        }

        for (uint i = 0; i < n_kw; i++) {
            qstr arg_name = MP_OBJ_QSTR_VALUE(kwargs[2 * i]);
            for (uint j = 0; j < self->n_pos_args + self->n_kwonly_args; j++) {
                if (arg_name == self->args[j]) {
                    if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
                        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                            "function got multiple values for argument '%s'", qstr_str(arg_name)));
                    }
                    code_state->state[n_state - 1 - j] = kwargs[2 * i + 1];
                    goto continue2;
                }
            }
            // Didn't find name match with positional args
            if (!self->takes_kw_args) {
                nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
            }
            mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
continue2:;
        }

        DEBUG_printf("Args with kws flattened: ");
        dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);

        // fill in defaults for positional args
        mp_obj_t *d = &code_state->state[n_state - self->n_pos_args];
        mp_obj_t *s = &self->extra_args[self->n_def_args - 1];
        for (int i = self->n_def_args; i > 0; i--, d++, s--) {
            if (*d == MP_OBJ_NULL) {
                *d = *s;
            }
        }

        DEBUG_printf("Args after filling default positional: ");
        dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);

        // Check that all mandatory positional args are specified
        while (d < &code_state->state[n_state]) {
            if (*d++ == MP_OBJ_NULL) {
                nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                    "function missing required positional argument #%d", &code_state->state[n_state] - d));
            }
        }

        // Check that all mandatory keyword args are specified
        // Fill in default kw args if we have them
        for (uint i = 0; i < self->n_kwonly_args; i++) {
            if (code_state->state[n_state - 1 - self->n_pos_args - i] == MP_OBJ_NULL) {
                mp_map_elem_t *elem = NULL;
                if (self->has_def_kw_args) {
                    elem = mp_map_lookup(&((mp_obj_dict_t*)self->extra_args[self->n_def_args])->map, MP_OBJ_NEW_QSTR(self->args[self->n_pos_args + i]), MP_MAP_LOOKUP);
                }
                if (elem != NULL) {
                    code_state->state[n_state - 1 - self->n_pos_args - i] = elem->value;
                } else {
                    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
                        "function missing required keyword argument '%s'", qstr_str(self->args[self->n_pos_args + i])));
                }
            }
        }

    } else {
        // no keyword arguments given
        if (self->n_kwonly_args != 0) {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                "function missing keyword-only argument"));
        }
        if (self->takes_kw_args) {
            *var_pos_kw_args = mp_obj_new_dict(0);
        }
    }

    // bytecode prelude: initialise closed over variables
    for (uint n_local = *ip++; n_local > 0; n_local--) {
        uint local_num = *ip++;
        code_state->state[n_state - 1 - local_num] = mp_obj_new_cell(code_state->state[n_state - 1 - local_num]);
    }

    // now that we skipped over the prelude, set the ip for the VM
    code_state->ip = ip;

    DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", self->n_pos_args, self->n_kwonly_args);
    dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args);
    dump_args(code_state->state, n_state);
}
예제 #23
0
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
    // This function is pretty complicated.  It's main aim is to be efficient in speed and RAM
    // usage for the common case of positional only args.

    DEBUG_printf("Input n_args: %d, n_kw: %d\n", n_args, n_kw);
    DEBUG_printf("Input pos args: ");
    dump_args(args, n_args);
    DEBUG_printf("Input kw args: ");
    dump_args(args + n_args, n_kw * 2);
    mp_obj_fun_bc_t *self = self_in;
    DEBUG_printf("Func n_def_args: %d\n", self->n_def_args);

    const byte *ip = self->bytecode;

    // get code info size, and skip line number table
    machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
    ip += code_info_size;

    // bytecode prelude: state size and exception stack size; 16 bit uints
    machine_uint_t n_state = ip[0] | (ip[1] << 8);
    machine_uint_t n_exc_stack = ip[2] | (ip[3] << 8);
    ip += 4;

#if VM_DETECT_STACK_OVERFLOW
    n_state += 1;
#endif

    // allocate state for locals and stack
    uint state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
    mp_code_state *code_state;
    if (state_size > VM_MAX_STATE_ON_STACK) {
        code_state = m_new_obj_var(mp_code_state, byte, state_size);
    } else {
        code_state = alloca(sizeof(mp_code_state) + state_size);
    }

    code_state->n_state = n_state;
    code_state->ip = ip;
    mp_setup_code_state(code_state, self_in, n_args, n_kw, args);

    // execute the byte code with the correct globals context
    mp_obj_dict_t *old_globals = mp_globals_get();
    mp_globals_set(self->globals);
    mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(code_state, MP_OBJ_NULL);
    mp_globals_set(old_globals);

#if VM_DETECT_STACK_OVERFLOW
    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        if (code_state->sp < code_state->state) {
            printf("VM stack underflow: " INT_FMT "\n", code_state->sp - code_state->state);
            assert(0);
        }
    }
    // We can't check the case when an exception is returned in state[n_state - 1]
    // and there are no arguments, because in this case our detection slot may have
    // been overwritten by the returned exception (which is allowed).
    if (!(vm_return_kind == MP_VM_RETURN_EXCEPTION && self->n_pos_args + self->n_kwonly_args == 0)) {
        // Just check to see that we have at least 1 null object left in the state.
        bool overflow = true;
        for (uint i = 0; i < n_state - self->n_pos_args - self->n_kwonly_args; i++) {
            if (code_state->state[i] == MP_OBJ_NULL) {
                overflow = false;
                break;
            }
        }
        if (overflow) {
            printf("VM stack overflow state=%p n_state+1=" UINT_FMT "\n", code_state->state, n_state);
            assert(0);
        }
    }
#endif

    mp_obj_t result;
    switch (vm_return_kind) {
        case MP_VM_RETURN_NORMAL:
            // return value is in *sp
            result = *code_state->sp;
            break;

        case MP_VM_RETURN_EXCEPTION:
            // return value is in state[n_state - 1]
            result = code_state->state[n_state - 1];
            break;

        case MP_VM_RETURN_YIELD: // byte-code shouldn't yield
        default:
            assert(0);
            result = mp_const_none;
            vm_return_kind = MP_VM_RETURN_NORMAL;
            break;
    }

    // free the state if it was allocated on the heap
    if (state_size > VM_MAX_STATE_ON_STACK) {
        m_del_var(mp_code_state, byte, state_size, code_state);
    }

    if (vm_return_kind == MP_VM_RETURN_NORMAL) {
        return result;
    } else { // MP_VM_RETURN_EXCEPTION
        nlr_raise(result);
    }
}