void EntityUpdate () { const unsigned stop_time = 100; if (!TextureReady ()) { sorted = false; return; } if (!sorted) { qsort (entity_list, entity_count, sizeof (struct entity), do_compare); sorted = true; } //We want to do several cells at once. Enough to get things done, but //not so many that the program is unresponsive. if (LOADING_SCREEN) { //If we're using a loading screen, we want to build as fast as possible struct timeval then, now; gettimeofday(&then, NULL); now = then; while (!compiled && ((now.tv_sec - then.tv_sec) * 1000 + (now.tv_usec - then.tv_usec) / 1000 < stop_time)) { do_compile (); gettimeofday(&now, NULL); } } else //Take it slow do_compile (); }
DVM_ExecutableList * DKC_compile(DKC_Compiler *compiler, FILE *fp, char *path) { extern FILE *yyin; DVM_ExecutableList *list; DVM_Executable *exe; DBG_assert(st_compiler_list == NULL, ("st_compiler_list != NULL(%p)", st_compiler_list)); set_path_to_compiler(compiler, path); compiler->input_mode = FILE_INPUT_MODE; yyin = fp; list = MEM_malloc(sizeof(DVM_ExecutableList)); list->list = NULL; exe = do_compile(compiler, list, NULL, DVM_FALSE); exe->path = MEM_strdup(path); list->top_level = exe; /* dvm_disassemble(exe);*/ dispose_compiler_list(); dkc_reset_string_literal_buffer(); return list; }
int compile(struct compilation_unit *cu) { if (opt_llvm_enable) return llvm_compile(cu); return do_compile(cu); }
void test_compile(void) { struct sym_test *st; struct compile_env *cenv; test_t t; int need; for (st = next_sym_test(NULL); st; st = next_sym_test(st)) { if ((sym != NULL) && strcmp(sym, sym_test_name(st))) { continue; } /* XXX: we really want a sym_test_desc() */ for (cenv = sym_test_env(st, NULL, &need); cenv != NULL; cenv = sym_test_env(st, cenv, &need)) { t = test_start("%s : %c%s", sym_test_name(st), need ? '+' : '-', env_name(cenv)); if (do_compile(t, st, cenv, need) == 0) { test_passed(t); } } } if (full_count > 0) { test_summary(); } }
static void doit(int undump, char* filename) { FILE* f= (filename==NULL) ? stdin : efopen(filename, undump ? "rb" : "r"); ZIO z; if (filename==NULL) filename="(stdin)"; zFopen(&z,f,filename); if (verbose) fprintf(stderr,"%s\n",filename); if (undump) do_undump(&z); else do_compile(&z); if (f!=stdin) fclose(f); }
static void do_compile_separately (void) { const char **new_new_argv; int i, new_new_argc; struct input_filename *current_ifn; if (num_infiles == 1 || ima_is_used) abort (); /* Total number of arguments in separate compiler invocation is : total number of original arguments - total no input files + one input file + "-o" + output file . */ new_new_argv = (const char **) malloc ((new_argc - num_infiles + 4) * sizeof (const char *)); if (!new_new_argv) abort (); for (current_ifn = in_files; current_ifn && current_ifn->name; current_ifn = current_ifn->next) { struct input_filename *ifn = in_files; int go_back = 0; new_new_argc = 1; for (i = 1; i < new_argc; i++) { if (ifn && ifn->name && !strcmp (new_argv[i], ifn->name)) { /* This argument is one of the input file. */ if (!strcmp (new_argv[i], current_ifn->name)) { /* If it is current input file name then add it in the new list. */ new_new_argv[new_new_argc++] = new_argv[i]; } /* This input file can not appear in again on the command line so next time look for next input file. */ ifn = ifn->next; } else { /* This argument is not a input file name. Add it into new list. */ new_new_argv[new_new_argc++] = new_argv[i]; } } /* OK now we have only one input file and all other arguments. */ do_compile (new_new_argv, new_new_argc); } }
static void doit(int undump, char* filename) { FILE* f= (filename==NULL) ? stdin : efopen(filename, undump ? "rb" : "r"); ZIO z; char source[255+2]; /* +2 for '@' and '\0' */ luaL_filesource(source,filename,sizeof(source)); zFopen(&z,f,source); if (verbose) fprintf(stderr,"%s\n",source+1); if (undump) do_undump(&z); else do_compile(&z); if (f!=stdin) fclose(f); }
void list_publics(int descr, dbref player, int arg[], int argc) { dbref program; if (argc > 1) { notify(player, "I don't understand which program you want to list PUBLIC functions for."); return; } program = (argc == 0) ? PLAYER_CURR_PROG(player) : arg[0]; if (Typeof(program) != TYPE_PROGRAM) { notify(player, "That isn't a program."); return; } if (!(controls(player, program) || Linkable(program))) { notify(player, "That's not a public program."); return; } if (!(PROGRAM_CODE(program))) { if (program == PLAYER_CURR_PROG(player)) { do_compile(descr, OWNER(program), program, 0); } else { struct line *tmpline; tmpline = PROGRAM_FIRST(program); PROGRAM_SET_FIRST(program, (struct line *) read_program(program)); do_compile(descr, OWNER(program), program, 0); free_prog_text(PROGRAM_FIRST(program)); PROGRAM_SET_FIRST(program, tmpline); } if (!PROGRAM_CODE(program)) { notify(player, "Program not compilable."); return; } } do_list_publics(player, program); }
void CRB_compile_string(CRB_Interpreter *interpreter, char **lines) { extern int yyparse(void); crb_set_current_interpreter(interpreter); crb_set_source_string(lines); interpreter->current_line_number = 1; interpreter->input_mode = CRB_STRING_INPUT_MODE; do_compile(interpreter); crb_reset_string_literal_buffer(); }
void EntityUpdate () { int stop_time; if (!TextureReady ()) { sorted = false; return; } if (!sorted) { std::sort (entity_list.begin(), entity_list.end()); sorted = true; } //We want to do several cells at once. Enough to get things done, but //not so many that the program is unresponsive. if (LOADING_SCREEN) { //If we're using a loading screen, we want to build as fast as possible stop_time = GetTimeInMillis () + 100; while (!compiled && GetTimeInMillis () < stop_time) do_compile (); } else //Take it slow do_compile (); }
void CRB_compile(CRB_Interpreter *interpreter, FILE *fp) { extern FILE *yyin; crb_set_current_interpreter(interpreter); interpreter->current_line_number = 1; interpreter->input_mode = CRB_FILE_INPUT_MODE; yyin = fp; do_compile(interpreter); crb_reset_string_literal_buffer(); }
void prim_cancallp(PRIM_PROTOTYPE) { CHECKOP(2); oper2 = POP(); /* string: public function name */ oper1 = POP(); /* dbref: Program dbref to check */ if (oper1->type != PROG_OBJECT) abort_interp("Expected dbref argument. (1)"); if (!valid_object(oper1)) abort_interp("Invalid dbref (1)"); if (Typeof(oper1->data.objref) != TYPE_PROGRAM) abort_interp("Object is not a MUF Program. (1)"); if (oper2->type != PROG_STRING) abort_interp("Expected string argument. (2)"); if (!oper2->data.string) abort_interp("Invalid Null string argument. (2)"); if (!(PROGRAM_CODE(oper1->data.objref))) { struct line *tmpline; tmpline = PROGRAM_FIRST(oper1->data.objref); PROGRAM_SET_FIRST(oper1->data.objref, (struct line *) read_program(oper1->data.objref)); do_compile(-1, OWNER(oper1->data.objref), oper1->data.objref, 0); free_prog_text(PROGRAM_FIRST(oper1->data.objref)); PROGRAM_SET_FIRST(oper1->data.objref, tmpline); } result = 0; if (ProgMLevel(oper1->data.objref) > 0 && (mlev >= 4 || OWNER(oper1->data.objref) == ProgUID || Linkable(oper1->data.objref)) ) { struct publics *pbs; pbs = PROGRAM_PUBS(oper1->data.objref); while (pbs) { if (!strcasecmp(oper2->data.string->data, pbs->subname)) break; pbs = pbs->next; } if (pbs && mlev >= pbs->mlev) result = 1; } CHECKOFLOW(1); CLEAR(oper1); CLEAR(oper2); PushInt(result); }
DVM_Executable * DKC_compile_string(DKC_Compiler *compiler, char **lines) { extern int yyparse(void); DVM_Executable *exe; dkc_set_source_string(lines); compiler->current_line_number = 1; compiler->input_mode = DKC_STRING_INPUT_MODE; exe = do_compile(compiler); dkc_reset_string_literal_buffer(); return exe; }
DVM_Executable * DKC_compile(DKC_Compiler *compiler, FILE *fp) { extern FILE *yyin; DVM_Executable *exe; compiler->current_line_number = 1; compiler->input_mode = DKC_FILE_INPUT_MODE; yyin = fp; exe = do_compile(compiler); dkc_reset_string_literal_buffer(); return exe; }
int main (int argc, const char **argv) { /* Initialization of SDCPP's environment. */ general_init (argv[0]); /* Parse the options and do minimal processing; basically just enough to default flags appropriately. */ decode_options (argc, argv); /* Exit early if we can (e.g. -help). */ if (!exit_after_options) do_compile (); if (errorcount) return (FATAL_EXIT_CODE); return (SUCCESS_EXIT_CODE); }
SearchFileStatus dkc_dynamic_compile(DKC_Compiler *compiler, char *package_name, DVM_ExecutableList *list, DVM_ExecutableItem **add_top, char *search_file) { SearchFileStatus status; extern FILE *yyin; DVM_ExecutableItem *tail; DVM_Executable *exe; SourceInput source_input; char found_path[FILENAME_MAX]; status = get_dynamic_load_input(package_name, found_path, search_file, &source_input); if (status != SEARCH_FILE_SUCCESS) { return status; } DBG_assert(st_compiler_list == NULL, ("st_compiler_list != NULL(%p)", st_compiler_list)); for (tail = list->list; tail->next; tail = tail->next) ; compiler->package_name = string_to_package_name(compiler, package_name); set_path_to_compiler(compiler, found_path); compiler->input_mode = source_input.input_mode; if (source_input.input_mode == FILE_INPUT_MODE) { yyin = source_input.u.file.fp; } else { dkc_set_source_string(source_input.u.string.lines); } exe = do_compile(compiler, list, found_path, DVM_FALSE); dispose_compiler_list(); dkc_reset_string_literal_buffer(); *add_top = tail->next; return SEARCH_FILE_SUCCESS; }
struct inst * interp_loop(dbref player, dbref program, struct frame *fr, int rettyp) { register struct inst *pc; register int atop; register struct inst *arg; register struct inst *temp1; register struct inst *temp2; register struct stack_addr *sys; register int instr_count; register int stop; int i = 0, tmp, writeonly, mlev; static struct inst retval; char dbuf[BUFFER_LEN]; int instno_debug_line = get_primitive("debug_line"); fr->level = ++interp_depth; /* increment interp level */ /* load everything into local stuff */ pc = fr->pc; atop = fr->argument.top; stop = fr->system.top; arg = fr->argument.st; sys = fr->system.st; writeonly = fr->writeonly; already_created = 0; fr->brkpt.isread = 0; if (!pc) { struct line *tmpline; tmpline = PROGRAM_FIRST(program); PROGRAM_SET_FIRST(program, (struct line *) read_program(program)); do_compile(-1, OWNER(program), program, 0); free_prog_text(PROGRAM_FIRST(program)); PROGRAM_SET_FIRST(program, tmpline); pc = fr->pc = PROGRAM_START(program); if (!pc) { abort_loop_hard("Program not compilable. Cannot run.", NULL, NULL); } PROGRAM_INC_PROF_USES(program); PROGRAM_INC_INSTANCES(program); } ts_useobject(program); err = 0; instr_count = 0; mlev = ProgMLevel(program); gettimeofday(&fr->proftime, NULL); /* This is the 'natural' way to exit a function */ while (stop) { /* Abort program if player/thing running it is recycled */ if ((player < 0) || (player >= db_top) || ((Typeof(player) != TYPE_PLAYER) && (Typeof(player) != TYPE_THING))) { reload(fr, atop, stop); prog_clean(fr); interp_depth--; calc_profile_timing(program,fr); return NULL; } fr->instcnt++; instr_count++; if ((fr->multitask == PREEMPT) || (FLAGS(program) & BUILDER)) { if (mlev == 4) { if (tp_max_ml4_preempt_count) { if (instr_count >= tp_max_ml4_preempt_count) abort_loop_hard("Maximum preempt instruction count exceeded", NULL, NULL); } else instr_count = 0; } else { /* else make sure that the program doesn't run too long */ if (instr_count >= tp_max_instr_count) abort_loop_hard("Maximum preempt instruction count exceeded", NULL, NULL); } } else { /* if in FOREGROUND or BACKGROUND mode, '0 sleep' every so often. */ if ((fr->instcnt > tp_instr_slice * 4) && (instr_count >= tp_instr_slice)) { fr->pc = pc; reload(fr, atop, stop); PLAYER_SET_BLOCK(player, (!fr->been_background)); add_muf_delay_event(0, fr->descr, player, NOTHING, NOTHING, program, fr, (fr->multitask == FOREGROUND) ? "FOREGROUND" : "BACKGROUND"); interp_depth--; calc_profile_timing(program,fr); return NULL; } } if (((FLAGS(program) & ZOMBIE) || fr->brkpt.force_debugging) && !fr->been_background && controls(player, program) ) { fr->brkpt.debugging = 1; } else { fr->brkpt.debugging = 0; } if (FLAGS(program) & DARK || (fr->brkpt.debugging && fr->brkpt.showstack && !fr->brkpt.bypass)) { if ((pc->type != PROG_PRIMITIVE) || (pc->data.number != instno_debug_line)) { char *m = debug_inst(fr, 0, pc, fr->pid, arg, dbuf, sizeof(dbuf), atop, program); notify_nolisten(player, m, 1); } } if (fr->brkpt.debugging) { short breakflag = 0; if (stop == 1 && !fr->brkpt.bypass && pc->type == PROG_PRIMITIVE && pc->data.number == IN_RET ) { /* Program is about to EXIT */ notify_nolisten(player, "Program is about to EXIT.", 1); breakflag = 1; } else if (fr->brkpt.count) { for (i = 0; i < fr->brkpt.count; i++) { if ((!fr->brkpt.pc[i] || pc == fr->brkpt.pc[i]) && /* pc matches */ (fr->brkpt.line[i] == -1 || (fr->brkpt.lastline != pc->line && fr->brkpt.line[i] == pc->line)) && /* line matches */ (fr->brkpt.level[i] == -1 || stop <= fr->brkpt.level[i]) && /* level matches */ (fr->brkpt.prog[i] == NOTHING || fr->brkpt.prog[i] == program) && /* program matches */ (fr->brkpt.linecount[i] == -2 || (fr->brkpt.lastline != pc->line && fr->brkpt.linecount[i]-- <= 0)) && /* line count matches */ (fr->brkpt.pccount[i] == -2 || (fr->brkpt.lastpc != pc && fr->brkpt.pccount[i]-- <= 0)) /* pc count matches */ ) { if (fr->brkpt.bypass) { if (fr->brkpt.pccount[i] == -1) fr->brkpt.pccount[i] = 0; if (fr->brkpt.linecount[i] == -1) fr->brkpt.linecount[i] = 0; } else { breakflag = 1; break; } } } } if (breakflag) { char *m; char buf[BUFFER_LEN]; if (fr->brkpt.dosyspop) { program = sys[--stop].progref; pc = sys[stop].offset; } add_muf_read_event(fr->descr, player, program, fr); reload(fr, atop, stop); fr->pc = pc; fr->brkpt.isread = 0; fr->brkpt.breaknum = i; fr->brkpt.lastlisted = 0; fr->brkpt.bypass = 0; fr->brkpt.dosyspop = 0; PLAYER_SET_CURR_PROG(player, program); PLAYER_SET_BLOCK(player, 0); interp_depth--; if (!fr->brkpt.showstack) { m = debug_inst(fr, 0, pc, fr->pid, arg, dbuf, sizeof(dbuf), atop, program); notify_nolisten(player, m, 1); } if (pc <= PROGRAM_CODE(program) || (pc - 1)->line != pc->line) { list_proglines(player, program, fr, pc->line, 0); } else { m = show_line_prims(fr, program, pc, 15, 1); snprintf(buf, sizeof(buf), " %s", m); notify_nolisten(player, buf, 1); } calc_profile_timing(program,fr); return NULL; } fr->brkpt.lastline = pc->line; fr->brkpt.lastpc = pc; fr->brkpt.bypass = 0; } if (mlev < 3) { if (fr->instcnt > (tp_max_instr_count * ((mlev == 2) ? 4 : 1))) abort_loop_hard("Maximum total instruction count exceeded.", NULL, NULL); } switch (pc->type) { case PROG_INTEGER: case PROG_FLOAT: case PROG_ADD: case PROG_OBJECT: case PROG_VAR: case PROG_LVAR: case PROG_SVAR: case PROG_STRING: case PROG_LOCK: case PROG_MARK: case PROG_ARRAY: if (atop >= STACK_SIZE) abort_loop("Stack overflow.", NULL, NULL); copyinst(pc, arg + atop); pc++; atop++; break; case PROG_LVAR_AT: case PROG_LVAR_AT_CLEAR: { struct inst *tmp; struct localvars *lv; if (atop >= STACK_SIZE) abort_loop("Stack overflow.", NULL, NULL); if (pc->data.number >= MAX_VAR || pc->data.number < 0) abort_loop("Scoped variable number out of range.", NULL, NULL); lv = localvars_get(fr, program); tmp = &(lv->lvars[pc->data.number]); copyinst(tmp, arg + atop); if (pc->type == PROG_LVAR_AT_CLEAR) { CLEAR(tmp); tmp->type = PROG_INTEGER; tmp->data.number = 0; } pc++; atop++; } break; case PROG_LVAR_BANG: { struct inst *the_var; struct localvars *lv; if (atop < 1) abort_loop("Stack Underflow.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); if (pc->data.number >= MAX_VAR || pc->data.number < 0) abort_loop("Scoped variable number out of range.", NULL, NULL); lv = localvars_get(fr, program); the_var = &(lv->lvars[pc->data.number]); CLEAR(the_var); temp1 = arg + --atop; *the_var = *temp1; pc++; } break; case PROG_SVAR_AT: case PROG_SVAR_AT_CLEAR: { struct inst *tmp; if (atop >= STACK_SIZE) abort_loop("Stack overflow.", NULL, NULL); tmp = scopedvar_get(fr, 0, pc->data.number); if (!tmp) abort_loop("Scoped variable number out of range.", NULL, NULL); copyinst(tmp, arg + atop); if (pc->type == PROG_SVAR_AT_CLEAR) { CLEAR(tmp); tmp->type = PROG_INTEGER; tmp->data.number = 0; } pc++; atop++; } break; case PROG_SVAR_BANG: { struct inst *the_var; if (atop < 1) abort_loop("Stack Underflow.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); the_var = scopedvar_get(fr, 0, pc->data.number); if (!the_var) abort_loop("Scoped variable number out of range.", NULL, NULL); CLEAR(the_var); temp1 = arg + --atop; *the_var = *temp1; pc++; } break; case PROG_FUNCTION: { int i = pc->data.mufproc->args; if (atop < i) abort_loop("Stack Underflow.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < i) abort_loop("Stack protection fault.", NULL, NULL); if (fr->skip_declare) fr->skip_declare = 0; else scopedvar_addlevel(fr, pc, pc->data.mufproc->vars); while (i-->0) { struct inst *tmp; temp1 = arg + --atop; tmp = scopedvar_get(fr, 0, i); if (!tmp) abort_loop_hard("Internal error: Scoped variable number out of range in FUNCTION init.", temp1, NULL); CLEAR(tmp); copyinst(temp1, tmp); CLEAR(temp1); } pc++; } break; case PROG_IF: if (atop < 1) abort_loop("Stack Underflow.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (false_inst(temp1)) pc = pc->data.call; else pc++; CLEAR(temp1); break; case PROG_EXEC: if (stop >= STACK_SIZE) abort_loop("System Stack Overflow", NULL, NULL); sys[stop].progref = program; sys[stop++].offset = pc + 1; pc = pc->data.call; fr->skip_declare = 0; /* Make sure we DON'T skip var decls */ break; case PROG_JMP: /* Don't need to worry about skipping scoped var decls here. */ /* JMP to a function header can only happen in IN_JMP */ pc = pc->data.call; break; case PROG_TRY: if (atop < 1) abort_loop("Stack Underflow.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (temp1->type != PROG_INTEGER || temp1->data.number < 0) abort_loop("Argument is not a positive integer.", temp1, NULL); if (fr->trys.top && atop - fr->trys.st->depth < temp1->data.number) abort_loop("Stack protection fault.", NULL, NULL); if (temp1->data.number > atop) abort_loop("Stack Underflow.", temp1, NULL); fr->trys.top++; fr->trys.st = push_try(fr->trys.st); fr->trys.st->depth = atop - temp1->data.number; fr->trys.st->call_level = stop; fr->trys.st->for_count = 0; fr->trys.st->addr = pc->data.call; pc++; CLEAR(temp1); break; case PROG_PRIMITIVE: /* * All pc modifiers and stuff like that should stay here, * everything else call with an independent dispatcher. */ switch (pc->data.number) { case IN_JMP: if (atop < 1) abort_loop("Stack underflow. Missing address.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (temp1->type != PROG_ADD) abort_loop("Argument is not an address.", temp1, NULL); if (temp1->data.addr->progref >= db_top || temp1->data.addr->progref < 0 || (Typeof(temp1->data.addr->progref) != TYPE_PROGRAM)) abort_loop_hard("Internal error. Invalid address.", temp1, NULL); if (program != temp1->data.addr->progref) { abort_loop("Destination outside current program.", temp1, NULL); } if (temp1->data.addr->data->type == PROG_FUNCTION) { fr->skip_declare = 1; } pc = temp1->data.addr->data; CLEAR(temp1); break; case IN_EXECUTE: if (atop < 1) abort_loop("Stack Underflow. Missing address.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (temp1->type != PROG_ADD) abort_loop("Argument is not an address.", temp1, NULL); if (temp1->data.addr->progref >= db_top || temp1->data.addr->progref < 0 || (Typeof(temp1->data.addr->progref) != TYPE_PROGRAM)) abort_loop_hard("Internal error. Invalid address.", temp1, NULL); if (stop >= STACK_SIZE) abort_loop("System Stack Overflow", temp1, NULL); sys[stop].progref = program; sys[stop++].offset = pc + 1; if (program != temp1->data.addr->progref) { program = temp1->data.addr->progref; fr->caller.st[++fr->caller.top] = program; mlev = ProgMLevel(program); PROGRAM_INC_INSTANCES(program); } pc = temp1->data.addr->data; CLEAR(temp1); break; case IN_CALL: if (atop < 1) abort_loop("Stack Underflow. Missing dbref argument.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; temp2 = 0; if (temp1->type != PROG_OBJECT) { temp2 = temp1; if (atop < 1) abort_loop("Stack Underflow. Missing dbref of func.", temp1, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (temp2->type != PROG_STRING) abort_loop("Public Func. name string required. (2)", temp1, temp2); if (!temp2->data.string) abort_loop("Null string not allowed. (2)", temp1, temp2); } if (temp1->type != PROG_OBJECT) abort_loop("Dbref required. (1)", temp1, temp2); if (!valid_object(temp1) || Typeof(temp1->data.objref) != TYPE_PROGRAM) abort_loop("Invalid object.", temp1, temp2); if (!(PROGRAM_CODE(temp1->data.objref))) { struct line *tmpline; tmpline = PROGRAM_FIRST(temp1->data.objref); PROGRAM_SET_FIRST(temp1->data.objref, (struct line *) read_program(temp1->data.objref)); do_compile(-1, OWNER(temp1->data.objref), temp1->data.objref, 0); free_prog_text(PROGRAM_FIRST(temp1->data.objref)); PROGRAM_SET_FIRST(temp1->data.objref, tmpline); if (!(PROGRAM_CODE(temp1->data.objref))) abort_loop("Program not compilable.", temp1, temp2); } if (ProgMLevel(temp1->data.objref) == 0) abort_loop("Permission denied", temp1, temp2); if (mlev < 4 && OWNER(temp1->data.objref) != ProgUID && !Linkable(temp1->data.objref)) abort_loop("Permission denied", temp1, temp2); if (stop >= STACK_SIZE) abort_loop("System Stack Overflow", temp1, temp2); sys[stop].progref = program; sys[stop].offset = pc + 1; if (!temp2) { pc = PROGRAM_START(temp1->data.objref); } else { struct publics *pbs; int tmpint; pbs = PROGRAM_PUBS(temp1->data.objref); while (pbs) { tmpint = string_compare(temp2->data.string->data, pbs->subname); if (!tmpint) break; pbs = pbs->next; } if (!pbs) abort_loop("PUBLIC or WIZCALL function not found. (2)", temp2, temp2); if (mlev < pbs->mlev) abort_loop("Insufficient permissions to call WIZCALL function. (2)", temp2, temp2); pc = pbs->addr.ptr; } stop++; if (temp1->data.objref != program) { calc_profile_timing(program,fr); gettimeofday(&fr->proftime, NULL); program = temp1->data.objref; fr->caller.st[++fr->caller.top] = program; PROGRAM_INC_INSTANCES(program); mlev = ProgMLevel(program); } PROGRAM_INC_PROF_USES(program); ts_useobject(program); CLEAR(temp1); if (temp2) CLEAR(temp2); break; case IN_RET: if (stop > 1 && program != sys[stop - 1].progref) { if (sys[stop - 1].progref >= db_top || sys[stop - 1].progref < 0 || (Typeof(sys[stop - 1].progref) != TYPE_PROGRAM)) abort_loop_hard("Internal error. Invalid address.", NULL, NULL); calc_profile_timing(program,fr); gettimeofday(&fr->proftime, NULL); PROGRAM_DEC_INSTANCES(program); program = sys[stop - 1].progref; mlev = ProgMLevel(program); fr->caller.top--; } scopedvar_poplevel(fr); pc = sys[--stop].offset; break; case IN_CATCH: case IN_CATCH_DETAILED: { int depth; if (!(fr->trys.top)) abort_loop_hard("Internal error. TRY stack underflow.", NULL, NULL); depth = fr->trys.st->depth; while (atop > depth) { temp1 = arg + --atop; CLEAR(temp1); } while (fr->trys.st->for_count-->0) { CLEAR(&fr->fors.st->cur); CLEAR(&fr->fors.st->end); fr->fors.top--; fr->fors.st = pop_for(fr->fors.st); } fr->trys.top--; fr->trys.st = pop_try(fr->trys.st); if (pc->data.number == IN_CATCH) { /* IN_CATCH */ if (fr->errorstr) { arg[atop].type = PROG_STRING; arg[atop++].data.string = alloc_prog_string(fr->errorstr); free(fr->errorstr); fr->errorstr = NULL; } else { arg[atop].type = PROG_STRING; arg[atop++].data.string = NULL; } if (fr->errorinst) { free(fr->errorinst); fr->errorinst = NULL; } } else { /* IN_CATCH_DETAILED */ stk_array *nu = new_array_dictionary(); if (fr->errorstr) { array_set_strkey_strval(&nu, "error", fr->errorstr); free(fr->errorstr); fr->errorstr = NULL; } if (fr->errorinst) { array_set_strkey_strval(&nu, "instr", fr->errorinst); free(fr->errorinst); fr->errorinst = NULL; } array_set_strkey_intval(&nu, "line", fr->errorline); array_set_strkey_refval(&nu, "program", fr->errorprog); arg[atop].type = PROG_ARRAY; arg[atop++].data.array = nu; } reload(fr, atop, stop); } pc++; break; case IN_EVENT_WAITFOR: if (atop < 1) abort_loop("Stack Underflow. Missing eventID list array argument.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (temp1->type != PROG_ARRAY) abort_loop("EventID string list array expected.", temp1, NULL); if (temp1->data.array && temp1->data.array->type != ARRAY_PACKED) abort_loop("Argument must be a list array of eventid strings.", temp1, NULL); if (!array_is_homogenous(temp1->data.array, PROG_STRING)) abort_loop("Argument must be a list array of eventid strings.", temp1, NULL); fr->pc = pc + 1; reload(fr, atop, stop); { int i, outcount; int count = array_count(temp1->data.array); char** events = (char**)malloc(count * sizeof(char**)); for (outcount = i = 0; i < count; i++) { char *val = array_get_intkey_strval(temp1->data.array, i); if (val != NULL) { int found = 0; int j; for (j = 0; j < outcount; j++) { if (!strcmp(events[j], val)) { found = 1; break; } } if (!found) { events[outcount++] = val; } } } muf_event_register_specific(player, program, fr, outcount, events); free(events); } PLAYER_SET_BLOCK(player, (!fr->been_background)); CLEAR(temp1); interp_depth--; calc_profile_timing(program,fr); return NULL; /* NOTREACHED */ break; case IN_READ: if (writeonly) abort_loop("Program is write-only.", NULL, NULL); if (fr->multitask == BACKGROUND) abort_loop("BACKGROUND programs are write only.", NULL, NULL); reload(fr, atop, stop); fr->brkpt.isread = 1; fr->pc = pc + 1; PLAYER_SET_CURR_PROG(player, program); PLAYER_SET_BLOCK(player, 0); add_muf_read_event(fr->descr, player, program, fr); interp_depth--; calc_profile_timing(program,fr); return NULL; /* NOTREACHED */ break; case IN_SLEEP: if (atop < 1) abort_loop("Stack Underflow.", NULL, NULL); if (fr->trys.top && atop - fr->trys.st->depth < 1) abort_loop("Stack protection fault.", NULL, NULL); temp1 = arg + --atop; if (temp1->type != PROG_INTEGER) abort_loop("Invalid argument type.", temp1, NULL); fr->pc = pc + 1; reload(fr, atop, stop); if (temp1->data.number < 0) abort_loop("Timetravel beyond scope of muf.", temp1, NULL); add_muf_delay_event(temp1->data.number, fr->descr, player, NOTHING, NOTHING, program, fr, "SLEEPING"); PLAYER_SET_BLOCK(player, (!fr->been_background)); interp_depth--; calc_profile_timing(program,fr); return NULL; /* NOTREACHED */ break; default: nargs = 0; reload(fr, atop, stop); tmp = atop; prim_func[pc->data.number - 1] (player, program, mlev, pc, arg, &tmp, fr); atop = tmp; pc++; break; } /* switch */ break; case PROG_CLEARED: log_status("WARNING: attempt to execute instruction cleared by %s:%hd in program %d", (char*)pc->data.addr, pc->line, program); pc = NULL; abort_loop_hard("Program internal error. Program erroneously freed from memory.", NULL, NULL); default: pc = NULL; abort_loop_hard("Program internal error. Unknown instruction type.", NULL, NULL); } /* switch */ if (err) { if (err != ERROR_DIE_NOW && fr->trys.top) { while (fr->trys.st->call_level < stop) { if (stop > 1 && program != sys[stop - 1].progref) { if (sys[stop - 1].progref >= db_top || sys[stop - 1].progref < 0 || (Typeof(sys[stop - 1].progref) != TYPE_PROGRAM)) abort_loop_hard("Internal error. Invalid address.", NULL, NULL); calc_profile_timing(program,fr); gettimeofday(&fr->proftime, NULL); PROGRAM_DEC_INSTANCES(program); program = sys[stop - 1].progref; mlev = ProgMLevel(program); fr->caller.top--; } scopedvar_poplevel(fr); stop--; } pc = fr->trys.st->addr; err = 0; } else { reload(fr, atop, stop); prog_clean(fr); PLAYER_SET_BLOCK(player, 0); interp_depth--; calc_profile_timing(program,fr); return NULL; } } } /* while */ PLAYER_SET_BLOCK(player, 0); if (atop) { struct inst *rv; if (rettyp) { copyinst(arg + atop - 1, &retval); rv = &retval; } else { if (!false_inst(arg + atop - 1)) { rv = (struct inst *) 1; } else { rv = NULL; } } reload(fr, atop, stop); prog_clean(fr); interp_depth--; calc_profile_timing(program,fr); return rv; } reload(fr, atop, stop); prog_clean(fr); interp_depth--; calc_profile_timing(program,fr); return NULL; }
/******************************************************* Function: ld_compile *******************************************************/ string ld_compile (bfd *abfd) { string input_path; string output_path; int argc; string *argv; int child_pid; int statptr; string file_name = (string)abfd->filename; if (tmpdir == 0) if (create_tmpdir (FALSE) != 0) { fprintf(stderr,"create_tmpdir() failed for %s\n",abfd->filename); exit(1); } if ((input_path = create_unique_file (file_name, 'B')) == 0) { fprintf(stderr,"create_unique_file() failed for %s\n",abfd->filename); exit(1); } if (abfd->arelt_data) { if (extract_archive_member (abfd, input_path) != 0) { fprintf(stderr,"extract_archive_member() failed for %s\n",abfd->filename); exit(1); } } else { UNLINK (input_path); if (make_link (file_name, input_path) != 0) { fprintf(stderr,"make_link() failed for %s\n",abfd->filename); exit(1); } } if ((output_path = create_unique_file (file_name, 'o')) == 0) { fprintf(stderr,"create_unique_file() failed for %s\n",abfd->filename); exit(1); } add_to_tmp_file_list (output_path); add_to_tmp_file_list (input_path); argv = get_command_line (abfd, input_path, output_path, &argc); if (ld_ipa_opt[LD_IPA_VERBOSE].flag || ld_ipa_opt[LD_IPA_SHOW].flag) fprintf(stderr,"Compiling %s\n",abfd->filename); child_pid = do_compile (argv); (void) waitpid (child_pid, &statptr, 0); if (statptr != 0 && WEXITSTATUS(statptr) != 0) { fprintf(stderr,"Compile of %s failed!\n",abfd->filename); exit(1); } active_pid = 0; FREE (argv); UNLINK (input_path); remove_from_tmp_file_list (input_path); FREE (input_path); return output_path; } /* ld_compile */
void editor(int descr, dbref player, const char *command) { dbref program; int arg[MAX_ARG + 1]; char buf[BUFFER_LEN]; const char *word[MAX_ARG + 1]; int i, j; /* loop variables */ program = PLAYER_CURR_PROG(player); /* check to see if we are insert mode */ if (PLAYER_INSERT_MODE(player)) { insert(player, command); /* insert it! */ return; } /* parse the commands */ for (i = 0; i <= MAX_ARG && *command; i++) { while (*command && isspace(*command)) command++; j = 0; while (*command && !isspace(*command)) { buf[j] = *command; command++, j++; } buf[j] = '\0'; word[i] = alloc_string(buf); if ((i == 1) && !string_compare(word[0], "def")) { if (word[1] && (word[1][0] == '.' || (word[1][0] >= '0' && word[1][0] <= '9'))) { notify(player, "Invalid macro name."); return; } while (*command && isspace(*command)) command++; word[2] = alloc_string(command); if (!word[2]) notify(player, "Invalid definition syntax."); else { if (insert_macro(word[1], word[2], player, ¯otop)) { notify(player, "Entry created."); } else { notify(player, "That macro already exists!"); } } for (; i >= 0; i--) { if (word[i]) free((void *) word[i]); } return; } arg[i] = atoi(buf); if (arg[i] < 0) { notify(player, "Negative arguments not allowed!"); for (; i >= 0; i--) { if (word[i]) free((void *) word[i]); } return; } } i--; while ((i >= 0) && !word[i]) i--; if (i < 0) { return; } else { switch (word[i][0]) { case KILL_COMMAND: if (!Wizard(player)) { notify(player, "I'm sorry Dave, but I can't let you do that."); } else { if (kill_macro(word[0], player, ¯otop)) notify(player, "Macro entry deleted."); else notify(player, "Macro to delete not found."); } break; case SHOW_COMMAND: list_macros(word, i, player, 1); break; case SHORTSHOW_COMMAND: list_macros(word, i, player, 0); break; case INSERT_COMMAND: do_insert(player, program, arg, i); notify(player, "Entering insert mode."); break; case DELETE_COMMAND: do_delete(player, program, arg, i); break; case QUIT_EDIT_COMMAND: do_quit(player, program); notify(player, "Editor exited."); break; case COMPILE_COMMAND: /* compile code belongs in compile.c, not in the editor */ do_compile(descr, player, program, 1); notify(player, "Compiler done."); break; case LIST_COMMAND: do_list(player, program, arg, i); break; case EDITOR_HELP_COMMAND: spit_file(player, EDITOR_HELP_FILE); break; case VIEW_COMMAND: val_and_head(player, arg, i); break; case UNASSEMBLE_COMMAND: disassemble(player, program); break; case NUMBER_COMMAND: toggle_numbers(player, arg, i); break; case PUBLICS_COMMAND: list_publics(descr, player, arg, i); break; default: notify(player, "Illegal editor command."); break; } } for (; i >= 0; i--) { if (word[i]) free((void *) word[i]); } }
jint Java_pp_compiler_Compile_compiler(JNIEnv* env, jobject obj, jstring jname) { int e; const char*path; int i; char*name; // index of the file name initialize(); // error capture e=0; if ((e=setjmp(jmp_env))!=0) { terminate(); if (iStackPtr>0) { #ifdef DEBUG return 12345; // for debug to stay in console #else return e; #endif // lauch editor on the error if e>0 // stay on the console on fatal error <0 } return -1; } // Parameters are used in other functons such as emitChar // so save them in globals Env=env; Obj=obj; // compute the identifier of the Java Method used by the compiler jclass cls = (*env)->GetObjectClass(env, obj); emitcharID = (*env)->GetMethodID(env, cls, "emitChar", "(C)V"); if (emitcharID == NULL) ReportError(INTERNAL,"method not found"); // Humm, method not found // get the path of the file to compile path=(*env)->GetStringUTFChars(env,jname,NULL); if (path==NULL) ReportError(OUTOFMEMORY); // out of memory // copy the path in the Pool and split it // split the path into the path and the name // a terminal zero is included in place of the last '/' // assign LoPoolMax to the end of the path name=split(path); (*env)->ReleaseStringUTFChars(env,jname,path); prompt(name); do_compile(); do_link(); build_exec(); terminate(); post_message(); return 0; }
static DVM_Executable * do_compile(DKC_Compiler *compiler, DVM_ExecutableList *list, char *path, DVM_Boolean is_required) { extern FILE *yyin; extern int yyparse(void); RequireList *req_pos; DKC_Compiler *req_comp; DVM_Executable *exe; DVM_Executable *req_exe; char found_path[FILENAME_MAX]; DKC_Compiler *compiler_backup; SourceInput source_input; compiler_backup = dkc_get_current_compiler(); dkc_set_current_compiler(compiler); if (yyparse()) { fprintf(stderr, "Error ! Error ! Error !\n"); exit(1); } for (req_pos = compiler->require_list; req_pos; req_pos = req_pos->next) { req_comp = search_compiler(st_compiler_list, req_pos->package_name); if (req_comp) { compiler->required_list = add_compiler_to_list(compiler->required_list, req_comp); continue; } req_comp = DKC_create_compiler(); /* BUGBUG req_comp references parent compiler's MEM_storage */ req_comp->package_name = req_pos->package_name; req_comp->source_suffix = DKH_SOURCE; compiler->required_list = add_compiler_to_list(compiler->required_list, req_comp); st_compiler_list = add_compiler_to_list(st_compiler_list, req_comp); get_require_input(req_pos, found_path, &source_input); set_path_to_compiler(req_comp, found_path); req_comp->input_mode = source_input.input_mode; if (source_input.input_mode == FILE_INPUT_MODE) { yyin = source_input.u.file.fp; } else { dkc_set_source_string(source_input.u.string.lines); } req_exe = do_compile(req_comp, list, found_path, DVM_TRUE); } dkc_fix_tree(compiler); exe = dkc_generate(compiler); if (path) { exe->path = MEM_strdup(path); } else { exe->path = NULL; } /* dvm_disassemble(exe);*/ exe->is_required = is_required; if (!add_exe_to_list(exe, list)) { dvm_dispose_executable(exe); } dkc_set_current_compiler(compiler_backup); return exe; }
/* Main entry point. This is gcc driver driver! Interpret -arch flag from the list of input arguments. Invoke appropriate compiler driver. 'lipo' the results if more than one -arch is supplied. */ int main (int argc, const char **argv) { size_t i; int l, pid, argv_0_len, prog_len; char *errmsg_fmt, *errmsg_arg; char *override_option_str = NULL; char path_buffer[2*PATH_MAX+1]; int linklen; total_argc = argc; prog_len = 0; argv_0_len = strlen (argv[0]); /* Get the progname, required by pexecute () and program location. */ prog_len = get_prog_name_len (argv[0]); /* If argv[0] is all program name (no slashes), search the PATH environment variable to get the fully resolved path to the executable. */ if (prog_len == argv_0_len) { #ifdef DEBUG progname = argv[0] + argv_0_len - prog_len; fprintf (stderr,"%s: before PATH resolution, full progname = %s\n", argv[0]+argv_0_len-prog_len, argv[0]); #endif argv[0] = resolve_path_to_executable (argv[0]); prog_len = get_prog_name_len (argv[0]); argv_0_len = strlen(argv[0]); } /* If argv[0] is a symbolic link, use the directory of the pointed-to file to find compiler components. */ if ((linklen = readlink (argv[0], path_buffer, PATH_MAX)) != -1) { /* readlink succeeds if argv[0] is a symlink. path_buffer now contains the file referenced. */ path_buffer[linklen] = '\0'; #ifdef DEBUG progname = argv[0] + argv_0_len - prog_len; fprintf (stderr, "%s: before symlink, full prog = %s target = %s\n", progname, argv[0], path_buffer); #endif argv[0] = resolve_symlink(argv[0], path_buffer, argv_0_len, prog_len); argv_0_len = strlen(argv[0]); /* Get the progname, required by pexecute () and program location. */ prog_len = get_prog_name_len (argv[0]); #ifdef DEBUG progname = argv[0] + argv_0_len - prog_len; printf("%s: ARGV[0] after symlink = %s\n", progname, argv[0]); #endif } progname = argv[0] + argv_0_len - prog_len; /* Setup driver prefix. */ prefix_len = argv_0_len - prog_len; curr_dir = (char *) malloc (sizeof (char) * (prefix_len + 1)); strncpy (curr_dir, argv[0], prefix_len); curr_dir[prefix_len] = '\0'; driver_exec_prefix = (argv[0], "/usr/bin", curr_dir); #ifdef DEBUG fprintf (stderr,"%s: full progname = %s\n", progname, argv[0]); fprintf (stderr,"%s: progname = %s\n", progname, progname); fprintf (stderr,"%s: driver_exec_prefix = %s\n", progname, driver_exec_prefix); #endif /* Before we get too far, rewrite the command line with any requested overrides */ if ((override_option_str = getenv ("QA_OVERRIDE_GCC3_OPTIONS")) != NULL) rewrite_command_line(override_option_str, &argc, (char***)&argv); initialize (); /* Process arguments. Take appropriate actions when -arch, -c, -S, -E, -o is encountered. Find input file name. */ for (i = 1; i < argc; i++) { if (!strcmp (argv[i], "-arch")) { if (i + 1 >= argc) abort (); add_arch (argv[i+1]); i++; } else if (!strcmp (argv[i], "-c")) { new_argv[new_argc++] = argv[i]; compile_only_request = 1; } else if (!strcmp (argv[i], "-S")) { new_argv[new_argc++] = argv[i]; asm_output_request = 1; } else if (!strcmp (argv[i], "-E")) { new_argv[new_argc++] = argv[i]; preprocessed_output_request = 1; } else if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD")) { new_argv[new_argc++] = argv[i]; dash_capital_m_seen = 1; } else if (!strcmp (argv[i], "-m32")) { new_argv[new_argc++] = argv[i]; dash_m32_seen = 1; } else if (!strcmp (argv[i], "-m64")) { new_argv[new_argc++] = argv[i]; dash_m64_seen = 1; } else if (!strcmp (argv[i], "-dynamiclib")) { new_argv[new_argc++] = argv[i]; dash_dynamiclib_seen = 1; } else if (!strcmp (argv[i], "-v")) { new_argv[new_argc++] = argv[i]; verbose_flag = 1; } else if (!strcmp (argv[i], "-o")) { if (i + 1 >= argc) fatal ("argument to '-o' is missing"); output_filename = argv[i+1]; i++; } else if ((! strcmp (argv[i], "-pass-exit-codes")) || (! strcmp (argv[i], "-print-search-dirs")) || (! strcmp (argv[i], "-print-libgcc-file-name")) || (! strncmp (argv[i], "-print-file-name=", 17)) || (! strncmp (argv[i], "-print-prog-name=", 17)) || (! strcmp (argv[i], "-print-multi-lib")) || (! strcmp (argv[i], "-print-multi-directory")) || (! strcmp (argv[i], "-print-multi-os-directory")) || (! strcmp (argv[i], "-ftarget-help")) || (! strcmp (argv[i], "-fhelp")) || (! strcmp (argv[i], "+e")) || (! strncmp (argv[i], "-Wa,",4)) || (! strncmp (argv[i], "-Wp,",4)) || (! strncmp (argv[i], "-Wl,",4)) || (! strncmp (argv[i], "-l", 2)) || (! strncmp (argv[i], "-weak-l", 7)) || (! strncmp (argv[i], "-specs=", 7)) || (! strcmp (argv[i], "-ObjC")) || (! strcmp (argv[i], "-fobjC")) || (! strcmp (argv[i], "-ObjC++")) || (! strcmp (argv[i], "-time")) || (! strcmp (argv[i], "-###")) || (! strcmp (argv[i], "-fconstant-cfstrings")) || (! strcmp (argv[i], "-fno-constant-cfstrings")) || (! strcmp (argv[i], "-static-libgcc")) || (! strcmp (argv[i], "-shared-libgcc")) || (! strcmp (argv[i], "-pipe")) ) { new_argv[new_argc++] = argv[i]; } else if (! strcmp (argv[i], "-save-temps") || ! strcmp (argv[i], "--save-temps")) { new_argv[new_argc++] = argv[i]; save_temps_seen = 1; } else if ((! strcmp (argv[i], "-Xlinker")) || (! strcmp (argv[i], "-Xassembler")) || (! strcmp (argv[i], "-Xpreprocessor")) || (! strcmp (argv[i], "-l")) || (! strcmp (argv[i], "-weak_library")) || (! strcmp (argv[i], "-weak_framework")) || (! strcmp (argv[i], "-specs")) || (! strcmp (argv[i], "-framework")) ) { new_argv[new_argc++] = argv[i]; i++; new_argv[new_argc++] = argv[i]; } else if (! strncmp (argv[i], "-Xarch_", 7)) { arch_conditional[new_argc] = get_arch_name (argv[i] + 7); i++; new_argv[new_argc++] = argv[i]; } else if (argv[i][0] == '-' && argv[i][1] != 0) { const char *p = &argv[i][1]; int c = *p; /* First copy this flag itself. */ new_argv[new_argc++] = argv[i]; if (argv[i][1] == 'M') dash_capital_m_seen = 1; /* Now copy this flag's arguments, if any, appropriately. */ if ((SWITCH_TAKES_ARG (c) > (p[1] != 0)) || WORD_SWITCH_TAKES_ARG (p)) { int j = 0; int n_args = WORD_SWITCH_TAKES_ARG (p); if (n_args == 0) { /* Count only the option arguments in separate argv elements. */ n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); } if (i + n_args >= argc) fatal ("argument to `-%s' is missing", p); while ( j < n_args) { i++; new_argv[new_argc++] = argv[i]; j++; } } } else { struct input_filename *ifn; new_argv[new_argc++] = argv[i]; ifn = (struct input_filename *) malloc (sizeof (struct input_filename)); ifn->name = argv[i]; ifn->index = i; ifn->next = NULL; num_infiles++; if (last_infile) last_infile->next = ifn; else in_files = ifn; last_infile = ifn; } } #if 0 if (num_infiles == 0) fatal ("no input files"); #endif if (num_arches == 0) add_arch(get_arch_name(NULL)); if (num_arches > 1) { if (preprocessed_output_request || save_temps_seen || asm_output_request || dash_capital_m_seen) fatal ("-E, -S, -save-temps and -M options are not allowed with multiple -arch flags"); } /* If -arch is not present OR Only one -arch <blah> is specified. Invoke appropriate compiler driver. FAT build is not required in this case. */ if (num_arches == 1) { int arch_specific_argc; const char **arch_specific_argv; /* Find compiler driver based on -arch <foo> and add approriate -m* argument. */ new_argv[0] = get_driver_name (get_arch_name (arches[0])); new_argc = new_argc + add_arch_options (0, new_argv, new_argc); #ifdef DEBUG printf ("%s: invoking single driver name = %s\n", progname, new_argv[0]); #endif /* Re insert output file name. */ if (output_filename) { new_argv[new_argc++] = "-o"; new_argv[new_argc++] = output_filename; } /* Add the NULL. */ new_argv[new_argc] = NULL; arch_specific_argv = (const char **) malloc ((new_argc + 1) * sizeof (const char *)); arch_specific_argc = filter_args_for_arch (new_argv, new_argc, arch_specific_argv, get_arch_name (arches[0])); #ifdef DEBUG debug_command_line (arch_specific_argv, arch_specific_argc); #endif pid = pexecute (arch_specific_argv[0], (char *const *)arch_specific_argv, progname, NULL, &errmsg_fmt, &errmsg_arg, PEXECUTE_SEARCH | PEXECUTE_ONE); if (pid == -1) pfatal_pexecute (errmsg_fmt, errmsg_arg); do_wait (pid, arch_specific_argv[0]); } else { /* Handle multiple -arch <blah>. */ /* If more than one input files are supplied but only one output filename is present then IMA will be used. */ if (num_infiles > 1 && !compile_only_request) ima_is_used = 1; /* Linker wants to know this in case of multiple -arch. */ if (!compile_only_request && !dash_dynamiclib_seen) new_argv[new_argc++] = "-Wl,-arch_multiple"; /* If only one input file is specified OR IMA is used then expected output is one FAT binary. */ if (num_infiles == 1 || ima_is_used) { const char *out_file; /* Create output file name based on input filename, if required. */ if (compile_only_request && !output_filename && num_infiles == 1) out_file = strip_path_and_suffix (in_files->name, ".o"); else out_file = (output_filename ? output_filename : final_output); /* Linker wants to know name of output file using one extra arg. */ if (!compile_only_request) { char *oname = (char *)(output_filename ? output_filename : final_output); char *n = malloc (sizeof (char) * (strlen (oname) + 5)); strcpy (n, "-Wl,"); strcat (n, oname); new_argv[new_argc++] = "-Wl,-final_output"; new_argv[new_argc++] = n; } /* Compile file(s) for each arch and lipo 'em together. */ do_compile (new_argv, new_argc); /* Make FAT binary by combining individual output files for each architecture, using 'lipo'. */ do_lipo (0, out_file); } else { /* Multiple input files are present and IMA is not used. Which means need to generate multiple FAT files. */ do_compile_separately (); do_lipo_separately (); } } final_cleanup (); free (curr_dir); return greatest_status; }