void Parrot_run_native(Parrot_Interp interpreter, native_func_t func) { static opcode_t program_code[2]; struct PackFile * pf; program_code[0] = interpreter->op_lib->op_code("enternative", 0); program_code[1] = 0; /* end */ pf = PackFile_new(0); pf->cur_cs = (struct PackFile_ByteCode *) (pf->PackFuncs[PF_BYTEC_SEG].new_seg)(pf, "code", 1); pf->byte_code = pf->cur_cs->base.data = program_code; pf->cur_cs->base.size = 2; Parrot_loadbc(interpreter, pf); run_native = func; runops(interpreter, interpreter->resume_offset); }
struct PackFile * Parrot_readbc(struct Parrot_Interp *interpreter, const char *filename) { #if PARROT_HAS_HEADER_UNISTD off_t program_size, wanted; #else size_t program_size, wanted; #endif char *program_code; struct PackFile *pf; PMC * io = NULL; INTVAL is_mapped = 0; #ifdef PARROT_HAS_HEADER_SYSSTAT struct stat file_stat; #endif #ifdef PARROT_HAS_HEADER_SYSMMAN int fd = -1; #endif if (filename == NULL || strcmp(filename, "-") == 0) { /* read from STDIN */ io = PIO_STDIN(interpreter); /* read 1k at a time */ program_size = 0; } else { #ifdef PARROT_HAS_HEADER_SYSSTAT /* if we have stat(), get the actual file size so we can read it * in one chunk. */ if (stat(filename, &file_stat)) { PIO_eprintf(interpreter, "Parrot VM: Can't stat %s, code %i.\n", filename, errno); return NULL; } # ifndef PARROT_HAS_BROKEN_ISREG /* S_ISREG is strangely broken my lcc/linux install (though it did * once work */ if (!S_ISREG(file_stat.st_mode)) { PIO_eprintf(interpreter, "Parrot VM: %s is not a normal file.\n", filename); return NULL; } # endif /* PARROT_HAS_BROKEN_ISREG */ program_size = file_stat.st_size; #else /* PARROT_HAS_HEADER_SYSSTAT */ /* otherwise, we will read it 1k at a time */ program_size = 0; #endif /* PARROT_HAS_HEADER_SYSSTAT */ #ifndef PARROT_HAS_HEADER_SYSMMAN io = PIO_open(interpreter, NULL, filename, "<"); if (!io) { PIO_eprintf(interpreter, "Parrot VM: Can't open %s, code %i.\n", filename, errno); return NULL; } #else /* PARROT_HAS_HEADER_SYSMMAN */ /* the file wasn't from stdin, and we have mmap available- use it */ io = NULL; #endif /* PARROT_HAS_HEADER_SYSMMAN */ interpreter->current_file = string_make(interpreter, filename, strlen(filename), NULL, 0, NULL); } #ifdef PARROT_HAS_HEADER_SYSMMAN again: #endif /* if we've opened a file (or stdin) with PIO, read it in */ if (io != NULL) { size_t chunk_size; char *cursor; INTVAL read_result; chunk_size = program_size > 0 ? program_size : 1024; program_code = (char *)mem_sys_allocate(chunk_size); wanted = program_size; program_size = 0; if (!program_code) { /* Whoops, out of memory. */ PIO_eprintf(interpreter, "Parrot VM: Could not allocate buffer to read packfile from PIO.\n"); return NULL; } cursor = (char *)program_code; while ((read_result = PIO_read(interpreter, io, cursor, chunk_size)) > 0) { program_size += read_result; if (program_size == wanted) break; chunk_size = 1024; program_code = mem_sys_realloc(program_code, program_size + chunk_size); if (!program_code) { PIO_eprintf(interpreter, "Parrot VM: Could not reallocate buffer while reading packfile from PIO.\n"); return NULL; } cursor = (char *)program_code + program_size; } if (read_result < 0) { PIO_eprintf(interpreter, "Parrot VM: Problem reading packfile from PIO.\n"); return NULL; } PIO_close(interpreter, io); } else { /* if we've gotten here, we opted not to use PIO to read the file. * use mmap */ #ifdef PARROT_HAS_HEADER_SYSMMAN fd = open(filename, O_RDONLY | O_BINARY); if (!fd) { PIO_eprintf(interpreter, "Parrot VM: Can't open %s, code %i.\n", filename, errno); return NULL; } program_code = mmap(0, program_size, PROT_READ, MAP_SHARED, fd, (off_t)0); if (program_code == (void *)MAP_FAILED) { Parrot_warn(interpreter, PARROT_WARNINGS_IO_FLAG, "Parrot VM: Can't mmap file %s, code %i.\n", filename, errno); /* try again, now with IO reading the file */ io = PIO_open(interpreter, NULL, filename, "<"); if (!io) { PIO_eprintf(interpreter, "Parrot VM: Can't open %s, code %i.\n", filename, errno); return NULL; } goto again; } is_mapped = 1; #else /* PARROT_HAS_HEADER_SYSMMAN */ PIO_eprintf(interpreter, "Parrot VM: uncaught error occurred reading " "file or mmap not available.\n"); return NULL; #endif /* PARROT_HAS_HEADER_SYSMMAN */ } /* Now that we have the bytecode, let's unpack it. */ pf = PackFile_new(is_mapped); if (!PackFile_unpack (interpreter, pf, (opcode_t *)program_code, program_size)) { PIO_eprintf(interpreter, "Parrot VM: Can't unpack packfile %s.\n", filename); return NULL; } #ifdef PARROT_HAS_HEADER_SYSMMAN if (fd >= 0) { close(fd); /* the man page states, it's ok to close a mmaped file */ } #else /* XXX Parrot_exec uses this mem_sys_free(program_code); */ #endif return pf; }
int main(int argc, const char *argv[]) { int nextarg; Parrot_Interp interp; PDB_t *pdb; const char *scriptname = NULL; const unsigned char * configbytes = Parrot_get_config_hash_bytes(); const int configlength = Parrot_get_config_hash_length(); interp = Parrot_new(NULL); Parrot_set_executable_name(interp, Parrot_str_new(interp, argv[0], 0)); Parrot_set_configuration_hash_legacy(interp, configlength, configbytes); Parrot_debugger_init(interp); pdb = interp->pdb; pdb->state = PDB_ENTER; Parrot_block_GC_mark(interp); Parrot_block_GC_sweep(interp); nextarg = 1; if (argv[nextarg] && strcmp(argv[nextarg], "--script") == 0) { scriptname = argv [++nextarg]; ++nextarg; } if (argv[nextarg]) { const char *filename = argv[nextarg]; const char *ext = strrchr(filename, '.'); if (ext && STREQ(ext, ".pbc")) { Parrot_PackFile pf = Parrot_pbc_read(interp, filename, 0); if (!pf) return 1; Parrot_pbc_load(interp, pf); PackFile_fixup_subs(interp, PBC_MAIN, NULL); } else { STRING *errmsg = NULL; Parrot_PackFile pf = PackFile_new(interp, 0); Parrot_pbc_load(interp, pf); Parrot_compile_file(interp, filename, &errmsg); if (errmsg) Parrot_ex_throw_from_c_args(interp, NULL, 1, "%S", errmsg); PackFile_fixup_subs(interp, PBC_POSTCOMP, NULL); /* load the source for debugger list */ PDB_load_source(interp, filename); PackFile_fixup_subs(interp, PBC_MAIN, NULL); } } else { /* Generate some code to be able to enter into runloop */ STRING *compiler = Parrot_str_new_constant(interp, "PIR"); STRING *errstr = NULL; const char source []= ".sub aux :main\nexit 0\n.end\n"; Parrot_compile_string(interp, compiler, source, &errstr); if (!STRING_IS_NULL(errstr)) Parrot_io_eprintf(interp, "%Ss\n", errstr); } Parrot_unblock_GC_mark(interp); Parrot_unblock_GC_sweep(interp); if (scriptname) PDB_script_file(interp, scriptname); else PDB_printwelcome(); Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger")); PDB_run_code(interp, argc - nextarg, argv + nextarg); Parrot_x_exit(interp, 0); }
the resulting bytecode in C<pbcpmc>. This function returns a true value if this call is successful and false value otherwise. =cut */ PARROT_API Parrot_Int Parrot_api_load_bytecode_bytes(Parrot_PMC interp_pmc, ARGIN(const unsigned char * const pbc), Parrot_Int bytecode_size, ARGOUT(Parrot_PMC * pbcpmc)) { ASSERT_ARGS(Parrot_api_load_bytecode_bytes) EMBED_API_CALLIN(interp_pmc, interp) PackFile * const pf = PackFile_new(interp, 0); PARROT_ASSERT(pf); Parrot_block_GC_mark(interp); if (!PackFile_unpack(interp, pf, (const opcode_t *)pbc, bytecode_size)) { Parrot_unblock_GC_mark(interp); Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE, "Could not unpack packfile"); } *pbcpmc = Parrot_pf_get_packfile_pmc(interp, pf); Parrot_unblock_GC_mark(interp); EMBED_API_CALLOUT(interp_pmc, interp); } /* Load the bytecode into the interpreter, but don't execute it */ /* TODO: This only works with the inital bytecode. After this we should use
int main(int argc, char **argv) { long *opp; int dummy_var; struct Parrot_Interp * interpreter; struct PackFile * pf; opcode_t *code_start; INTVAL i; PMC *userargv; extern char *program_code; extern long opcode_map; extern int bytecode_offset; #if defined(JIT_CGP) extern void * exec_prederef_code; #endif extern int Parrot_exec_run; extern struct PackFile_Constant *exec_const_table; extern struct PackFile_Constant const_table; extern struct Parrot_Interp interpre; /* s. exec.c */ Parrot_exec_run = 1; /* s. packfile.c (PackFile_ConstTable_unpack()) */ exec_const_table = &const_table; interpreter = Parrot_new(NULL); if (!interpreter) { return 1; } Parrot_init(interpreter); run_native = run_compiled; /* TODO make also a shared variant of PackFile_new */ pf = PackFile_new(0); if (!PackFile_unpack(interpreter, pf, (opcode_t *)(&program_code), sizeof(&program_code))) { printf( "Can't unpack.\n" ); return 1; } Parrot_loadbc(interpreter, pf); setup_argv(interpreter, argc, argv); /* opcode_map has the offset of each opcode in the compiled code * this modifies it to be address of the opcode. */ opp = &opcode_map; for (i = 0; i < (int)interpre.code->cur_cs->base.size; i++) { opp[i] += (long)run_compiled; } #if defined(JIT_CGP) exec_init_prederef(interpreter, &exec_prederef_code); #endif Parrot_set_run_core(interpreter, PARROT_EXEC_CORE); interpreter->code->byte_code = (opcode_t *)&((&program_code)[bytecode_offset]); Parrot_exec_run = 0; runops(interpreter, 0); /* run_compiled(interpreter, (opcode_t *)&((&program_code)[bytecode_offset])); */ exit(0); }