int main(int argc, char** argv) { int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; char nodename[100]; char browser[100]; int ct_mode; int dist_mode; int cnt; int erl_args; char** argv0 = argv; emulator = get_default_emulator(argv[0]); /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of * the array, to allow easy addition of commands in the beginning. */ eargv_size = argc*4+100; eargv_base = (char **) emalloc(eargv_size*sizeof(char*)); eargv = eargv_base; eargc = 0; push_words(emulator); eargc_base = eargc; eargv = eargv + eargv_size/2; eargc = 0; strcpy(nodename, "ct"); dist_mode = SHORT_NAME; browser[0] = '\0'; ct_mode = NORMAL_MODE; erl_args = argc; cnt = 1; /* * Check various flags before building command line */ while (cnt < argc) { if (strcmp(argv[1], "-erl_args") == 0) { erl_args = cnt; } else if (strcmp(argv[1], "-sname") == 0) { strcpy(nodename, argv[2]); cnt++, argv++; } else if (strcmp(argv[1], "-name") == 0) { strcpy(nodename, argv[2]); dist_mode = FULL_NAME; cnt++, argv++; } else { if (cnt < erl_args) { if (strcmp(argv[1], "-vts") == 0) { ct_mode = VTS_MODE; } else if (strcmp(argv[1], "-browser") == 0) { strcpy(browser, argv[2]); cnt++, argv++; } else if (strcmp(argv[1], "-shell") == 0) { ct_mode = CT_SHELL_MODE; } else if (strcmp(argv[1], "-ctmaster") == 0) { strcpy(nodename, "ct_master"); ct_mode = MASTER_MODE; } else if (strcmp(argv[1], "-ctname") == 0) { strcpy(nodename, argv[2]); ct_mode = ERL_SHELL_MODE; cnt++, argv++; } } } cnt++, argv++; } argv = argv0; /* * Push initial arguments. */ if (dist_mode == FULL_NAME) { PUSH2("-name", nodename); } else { PUSH2("-sname", nodename); } /* * Push everything else */ if (ct_mode == VTS_MODE) { PUSH4("-s", "webtool", "script_start", "vts"); if (browser[0] != '\0') PUSH(browser); PUSH3("-s", "ct_run", "script_start"); } else if (ct_mode == CT_SHELL_MODE) { PUSH3("-s", "ct_run", "script_start"); } else if (ct_mode == NORMAL_MODE) { PUSH3("-s", "ct_run", "script_start"); PUSH3("-s", "erlang", "halt"); } cnt = 1; while (cnt < argc) { if (strcmp(argv[1], "-erl_args") == 0) { PUSH("-ct_erl_args"); } else if ((strcmp(argv[1], "-sname") == 0) || (strcmp(argv[1], "-name") == 0)) { cnt++, argv++; } else if (cnt < erl_args) { if (strcmp(argv[1], "-config") == 0) PUSH("-ct_config"); else if (strcmp(argv[1], "-decrypt_key") == 0) PUSH("-ct_decrypt_key"); else if (strcmp(argv[1], "-decrypt_file") == 0) PUSH("-ct_decrypt_file"); else PUSH(argv[1]); } else { PUSH(argv[1]); } cnt++, argv++; } /* * Move up the commands for invoking the emulator and adjust eargv * accordingly. */ while (--eargc_base >= 0) { UNSHIFT(eargv_base[eargc_base]); } /* * Invoke Erlang with the collected options. */ PUSH(NULL); return run_erlang(eargv[0], eargv); }
int wmain(int argc, wchar_t **wcargv) { char** argv; #else int main(int argc, char** argv) { #endif int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; char nodename[100]; char browser[100]; int ct_mode; int dist_mode; int cnt; int erl_args; char** argv0; #ifdef __WIN32__ int i; int len; /* Convert argv to utf8 */ argv = malloc((argc+1) * sizeof(char*)); for (i=0; i<argc; i++) { len = WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, NULL, 0, NULL, NULL); argv[i] = malloc(len*sizeof(char)); WideCharToMultiByte(CP_UTF8, 0, wcargv[i], -1, argv[i], len, NULL, NULL); } argv[argc] = NULL; #endif argv0 = argv; emulator = get_default_emulator(argv[0]); if (strlen(emulator) >= MAXPATHLEN) error("Emulator path length is too large"); /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of * the array, to allow easy addition of commands in the beginning. */ eargv_size = argc*4+100; eargv_base = (char **) emalloc(eargv_size*sizeof(char*)); eargv = eargv_base; eargc = 0; PUSH(strsave(emulator)); eargc_base = eargc; eargv = eargv + eargv_size/2; eargc = 0; strcpy(nodename, "ct"); dist_mode = SHORT_NAME; browser[0] = '\0'; ct_mode = NORMAL_MODE; erl_args = argc; cnt = 1; /* * Check various flags before building command line */ while (cnt < argc) { if (strcmp(argv[1], "-erl_args") == 0) { erl_args = cnt; } else if (strcmp(argv[1], "-sname") == 0) { strncpy(nodename, argv[2], sizeof(nodename)); nodename[sizeof(nodename)-1] = '\0'; cnt++, argv++; } else if (strcmp(argv[1], "-name") == 0) { strncpy(nodename, argv[2], sizeof(nodename)); nodename[sizeof(nodename)-1] = '\0'; dist_mode = FULL_NAME; cnt++, argv++; } else { if (cnt < erl_args) { if (strcmp(argv[1], "-vts") == 0) { ct_mode = VTS_MODE; } else if (strcmp(argv[1], "-browser") == 0) { strncpy(browser, argv[2], sizeof(browser)); browser[sizeof(browser)-1] = '\0'; cnt++, argv++; } else if (strcmp(argv[1], "-shell") == 0) { ct_mode = CT_SHELL_MODE; } else if (strcmp(argv[1], "-ctmaster") == 0) { strcpy(nodename, "ct_master"); ct_mode = MASTER_MODE; } else if (strcmp(argv[1], "-ctname") == 0) { strncpy(nodename, argv[2], sizeof(nodename)); nodename[sizeof(nodename)-1] = '\0'; ct_mode = ERL_SHELL_MODE; cnt++, argv++; } } } cnt++, argv++; } argv = argv0; /* * Push initial arguments. */ if (dist_mode == FULL_NAME) { PUSH2("-name", nodename); } else { PUSH2("-sname", nodename); } /* * Push everything else */ if (ct_mode == VTS_MODE) { PUSH4("-s", "ct_webtool", "script_start", "vts"); if (browser[0] != '\0') PUSH(browser); PUSH3("-s", "ct_run", "script_start"); } else if (ct_mode == CT_SHELL_MODE) { PUSH3("-s", "ct_run", "script_start"); } else if (ct_mode == NORMAL_MODE) { PUSH3("-s", "ct_run", "script_start"); PUSH3("-s", "erlang", "halt"); } cnt = 1; while (cnt < argc) { if (strcmp(argv[1], "-erl_args") == 0) { PUSH("-ct_erl_args"); } else if ((strcmp(argv[1], "-sname") == 0) || (strcmp(argv[1], "-name") == 0)) { cnt++, argv++; } else if (cnt < erl_args) { if (strcmp(argv[1], "-config") == 0) PUSH("-ct_config"); else if (strcmp(argv[1], "-decrypt_key") == 0) PUSH("-ct_decrypt_key"); else if (strcmp(argv[1], "-decrypt_file") == 0) PUSH("-ct_decrypt_file"); else PUSH(argv[1]); } else { PUSH(argv[1]); } cnt++, argv++; } /* * Move up the commands for invoking the emulator and adjust eargv * accordingly. */ while (--eargc_base >= 0) { UNSHIFT(eargv_base[eargc_base]); } /* * Invoke Erlang with the collected options. */ PUSH(NULL); return run_erlang(eargv[0], eargv); }
void GC_push_stack_for(GC_thread thread) { int dummy; ptr_t sp, stack_min; DWORD me = GetCurrentThreadId(); if (thread -> stack_base) { if (thread -> id == me) { sp = (ptr_t) &dummy; } else { CONTEXT context; context.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL; if (!GetThreadContext(thread -> handle, &context)) ABORT("GetThreadContext failed"); /* Push all registers that might point into the heap. Frame */ /* pointer registers are included in case client code was */ /* compiled with the 'omit frame pointer' optimisation. */ # define PUSH1(reg) GC_push_one((word)context.reg) # define PUSH2(r1,r2) PUSH1(r1), PUSH1(r2) # define PUSH4(r1,r2,r3,r4) PUSH2(r1,r2), PUSH2(r3,r4) # if defined(I386) PUSH4(Edi,Esi,Ebx,Edx), PUSH2(Ecx,Eax), PUSH1(Ebp); sp = (ptr_t)context.Esp; # elif defined(X86_64) PUSH4(Rax,Rcx,Rdx,Rbx); PUSH2(Rbp, Rsi); PUSH1(Rdi); PUSH4(R8, R9, R10, R11); PUSH4(R12, R13, R14, R15); sp = (ptr_t)context.Rsp; # elif defined(ARM32) PUSH4(R0,R1,R2,R3),PUSH4(R4,R5,R6,R7),PUSH4(R8,R9,R10,R11),PUSH1(R12); sp = (ptr_t)context.Sp; # elif defined(SHx) PUSH4(R0,R1,R2,R3), PUSH4(R4,R5,R6,R7), PUSH4(R8,R9,R10,R11); PUSH2(R12,R13), PUSH1(R14); sp = (ptr_t)context.R15; # elif defined(MIPS) PUSH4(IntAt,IntV0,IntV1,IntA0), PUSH4(IntA1,IntA2,IntA3,IntT0); PUSH4(IntT1,IntT2,IntT3,IntT4), PUSH4(IntT5,IntT6,IntT7,IntS0); PUSH4(IntS1,IntS2,IntS3,IntS4), PUSH4(IntS5,IntS6,IntS7,IntT8); PUSH4(IntT9,IntK0,IntK1,IntS8); sp = (ptr_t)context.IntSp; # elif defined(PPC) PUSH4(Gpr0, Gpr3, Gpr4, Gpr5), PUSH4(Gpr6, Gpr7, Gpr8, Gpr9); PUSH4(Gpr10,Gpr11,Gpr12,Gpr14), PUSH4(Gpr15,Gpr16,Gpr17,Gpr18); PUSH4(Gpr19,Gpr20,Gpr21,Gpr22), PUSH4(Gpr23,Gpr24,Gpr25,Gpr26); PUSH4(Gpr27,Gpr28,Gpr29,Gpr30), PUSH1(Gpr31); sp = (ptr_t)context.Gpr1; # elif defined(ALPHA) PUSH4(IntV0,IntT0,IntT1,IntT2), PUSH4(IntT3,IntT4,IntT5,IntT6); PUSH4(IntT7,IntS0,IntS1,IntS2), PUSH4(IntS3,IntS4,IntS5,IntFp); PUSH4(IntA0,IntA1,IntA2,IntA3), PUSH4(IntA4,IntA5,IntT8,IntT9); PUSH4(IntT10,IntT11,IntT12,IntAt); sp = (ptr_t)context.IntSp; # else # error "architecture is not supported" # endif } /* ! current thread */ stack_min = GC_get_stack_min(thread->stack_base); if (sp >= stack_min && sp < thread->stack_base) { # if DEBUG_WIN32_PTHREADS || DEBUG_WIN32_THREADS \ || DEBUG_CYGWIN_THREADS GC_printf("Pushing thread from %p to %p for 0x%x from 0x%x\n", sp, thread -> stack_base, thread -> id, me); # endif GC_push_all_stack(sp, thread->stack_base); } else { WARN("Thread stack pointer 0x%lx out of range, pushing everything\n", (unsigned long)(size_t)sp); GC_push_all_stack(stack_min, thread->stack_base); } } /* thread looks live */ }