struct gsparsedline * gsinput_next_line(struct gsparsedfile_segment **ppseg, struct gsparsedline *p) { struct gsparsedline *pres; pres = (struct gsparsedline *)((uchar*)p + sizeof(*p) + p->numarguments * sizeof(gsinterned_string)); if ((uchar*)pres >= (uchar*)(*ppseg)->extent) gsfatal(UNIMPL("%P: Next line when changing segments"), p->pos); return pres; }
int genbf_inclusive_or_expr(struct inclusive_or_expr *a, int lval, struct type **t) { if (!a->end) { if (lval) ERROR("inclusive_or_expr", "Invalid l-value."); /* genbf_inclusive_or_expr(a->v1); SPC; printf("|\n"); */ UNIMPL("inclusive_or_expr"); } return genbf_exclusive_or_expr(a->v2, lval, t); }
struct type *genbf_declarator2(struct declarator2 *a, struct type *into) { struct type *nt; char *szs; int sz; switch (a->type) { case _IDENTIFIER: NEW(nt, struct type); nt->next = into; /* FIXME: there are other types :P */ nt->basic_type = TYPE_INT; nt->array = 0; nt->size = 1; return nt; case _DECLARATOR: return genbf_declarator(a->v1._declarator, into); case _ARRAY: /* we must add this to the type for the below declarator2 */ into = genbf_declarator2(a->v1._declarator2, into); NEW(nt, struct type); nt->next = into; /* get the size out of the expression, hopefully */ szs = genbf_conditional_expr_get_primary(_CONSTANT, a->v2._conditional_expr); if (!szs) { ERROR("declarator2", "Complex array definitions are not yet supported."); } /* turn it into a number */ if (szs[0] == '\'') { sz = *genbf_parse_string(szs); } else { sz = atoi(szs); } nt->basic_type = TYPE_PTR; nt->array = sz; nt->size = sz * into->size; return nt; default: UNIMPL("declarator2"); } }
static int api_gc_trace_code_segment(struct gsstringbuilder *err, struct api_code_segment **ppcode) { struct api_code_segment *code, *newcode; gsvalue gctemp; int i; code = *ppcode; if (code->fwd) { *ppcode = code->fwd; return 0; } if (!gs_sys_block_in_gc_from_space(code)) return 0; if (code->ip < 0) { gsstring_builder_print(err, "%p: instruction pointer is negative: %d", code, code->ip); return -1; } if (code->ip > code->size) { gsstring_builder_print(err, "%p: instruction pointer is too large: %d > %d", code, code->ip, code->size); return -1; } newcode = api_new_code_segment(); if (newcode->size < code->size - code->ip) { gsstring_builder_print(err, UNIMPL("api_gc_trace_code_segment: not enough space for all instructions")); return -1; } newcode->ip = newcode->size - (code->size - code->ip); /* > newcode->size - newcode->ip = code->size - code->ip; */ memcpy(newcode->instrs + newcode->ip, code->instrs + code->ip, sizeof(struct api_instr)*(code->size - code->ip)); code->fwd = newcode; for (i = newcode->ip; i < newcode->size; i++) { if (gs_gc_trace_pos(err, &newcode->instrs[i].pos) < 0) return -1; if (GS_GC_TRACE(err, &newcode->instrs[i].instr) < 0) return -1; if (api_gc_trace_promise(err, &newcode->instrs[i].presult) < 0) return -1; } *ppcode = newcode; return 0; }
struct api_thread * api_add_thread(struct gspos pos, struct api_thread_table *api_thread_table, void *main_thread_data, struct api_prim_table *api_prim_table, gsvalue entry) { int i; struct api_thread *thread; api_take_thread_queue(); thread = 0; for (i = 0; i < API_NUMTHREADS; i++) { api_take_thread(&api_thread_queue->threads[i]); if (api_thread_queue->threads[i].state == api_thread_st_unused) { thread = &api_thread_queue->threads[i]; api_thread_queue->numthreads++; goto have_thread; } else { api_release_thread(&api_thread_queue->threads[i]); } } gsfatal(UNIMPL("thread queue overflow")); have_thread: api_release_thread_queue(); if (gsflag_stat_collection) { thread->start_time = nsec(); thread->prog_term_time = 0; } thread->state = api_thread_st_active; thread->ismain = 0; thread->api_thread_table = api_thread_table; thread->api_prim_table = api_prim_table; thread->client_data = main_thread_data; thread->status = 0; thread->code = api_alloc_code_segment(pos, thread, entry); thread->eprim_blocking = 0; return thread; }
/* ================= GLimp_SetGamma ================= */ void GLimp_SetGamma( unsigned char red[ 256 ], unsigned char green[ 256 ], unsigned char blue[ 256 ] ) { #if defined( IPHONE ) UNIMPL(); #else #if 1 Uint16 table[ 256 ]; int i, value, lastvalue = 0; for ( i = 0; i < 256; i++ ) { value = ( ( ( Uint16 ) red[ i ] ) << 8 ) | red[ i ]; if ( i < 128 && ( value > ( ( 128 + i ) << 8 ) ) ) { value = ( 128 + i ) << 8; } if ( i && ( value < lastvalue ) ) { value = lastvalue; } lastvalue = table[ i ] = value; } if ( SDL_SetGammaRamp( table, table, table ) == -1 ) { Com_Printf( "SDL_SetGammaRamp failed.\n" ); } #else float g = Cvar_Get( "r_gamma", "1.0", 0 )->value; if ( SDL_SetGamma( g, g, g ) == -1 ) { Com_Printf( "SDL_SetGamma failed.\n" ); } #endif }
void genbf_init_declarator(struct init_declarator *a) { struct type *vt; int i; /* push this variable */ pushVar(genbf_declarator2_get_identifier(a->v1->v2), 1); /* then use genbf_declarator to get its type */ vt = genbf_declarator(a->v1, NULL); curvar->type = vt; curvar->width = vt->size; /* and push it in BF */ for (i = 0; i < curvar->width; i++) BF_PUSH; if (a->assign) { UNIMPL("init_declarator with assignment"); } }
static int CvContourTree_nptr(lua_State *L) { UNIMPL(L); return 0; }
void genbf_labeled_statement(struct labeled_statement *a) { UNIMPL("labeled_statement"); }
void _aulldiv(void){UNIMPL();}
static int CvContourTree_nblock_max(lua_State *L) { UNIMPL(L); return 0; }
void IofCompleteRequest(void){UNIMPL();}
void genbf_assignment_operator(struct assignment_operator *a) { UNIMPL("assignment_operator"); }
void KfAcquireSpinLock(void){UNIMPL();}
static int api_exec_instr(struct api_thread *thread, gsvalue instr) { struct gs_blockdesc *block; block = BLOCK_CONTAINING(instr); if (gsisimplementation_failure_block(block)) { struct gsimplementation_failure *p; char buf[0x100]; p = (struct gsimplementation_failure *)instr; gsimplementation_failure_format(buf, buf + sizeof(buf), p); api_abend(thread, "%s", buf); return 0; } else if (gsisheap_block(block)) { struct gsheap_item *hp; hp = (struct gsheap_item *)instr; switch (hp->type) { case gsclosure: { struct gsclosure *cl; cl = (struct gsclosure *)hp; switch (cl->cl.code->tag) { case gsbc_impprog: api_unpack_block_statement(thread, cl); return 1; default: api_abend(thread, UNIMPL("API instruction execution (%d closures)"), cl->cl.code->tag); return 0; } } default: api_abend(thread, UNIMPL("API instruction execution (%d exprs)"), hp->type); return 0; } } else if (gsisapiprim_block(block)) { struct gseprim *eprim; struct api_prim_table *table; eprim = (struct gseprim *)instr; table = thread->api_prim_table; if (eprim->p.index < 0) { api_abend(thread, "%P: Unknown primitive", eprim->pos); return 0; } else if (eprim->p.index >= table->numprims) { api_abend(thread, "%P: Primitive out of bounds", eprim->pos); return 0; } else { enum api_prim_execution_state st; gsvalue res; st = table->execs[eprim->p.index](thread, eprim, &thread->eprim_blocking, &res); switch (st) { case api_st_success: api_update_promise(thread->code->instrs[thread->code->ip].presult, res); thread->code->ip++; thread->eprim_blocking = 0; if (thread->code->ip >= thread->code->size) api_done(thread) ; return 1; case api_st_error: /* We assume the exec function called api_abend */ return 0; case api_st_blocked: /* Loop and try again next time */ return 0; default: api_abend(thread, UNIMPL("API instruction execution with state %d"), st); return 0; } } } else { api_abend(thread, UNIMPL("API instruction execution (%s)"), block->class->description); return 0; } }
void ExInitializeNPagedLookasideList(void){UNIMPL();}
void ExInterlockedPushEntrySList(void){UNIMPL();}
void ExDeleteNPagedLookasideList(void){UNIMPL();}
void _allrem(void){UNIMPL();}
void _allshr(void){UNIMPL();}
void IoReleaseCancelSpinLock(void){UNIMPL();}
void _allmul(long p1, long p2, long p3, long p4){UNIMPL();}
void genbf_selection_statement(struct selection_statement *a) { char *nname, *pblockname; int pblocknum; switch (a->type) { case _IF: case _IF_ELSE: genbf_expr(a->v1, 0, NULL); /* this will use a sneaky "subblock" format to make the jump-back * location predictable. basically: * main: * if (blah) { * main!0!1 * } else { * main!1!1 * } * main!2 */ /* get an "if-not" as well */ pblockname = curblock->name; pblocknum = curblock->num; printf("[>>>+>+<<<<-]>>>>[<<<<+>>>>-]+" "<[[-]>-<<<<(%s!%d)>>>]" ">[-<<<<(%s!%d)>>>>]" "<<<<", pblockname, pblocknum + 1, pblockname, pblocknum + 2); popVar(); /* go on to the if-block */ pushSubBlock(0); outBlock(); genbf_statement(a->v2); /* this needs to continue to the proper place */ if (a->type == _IF) { printf("(%s!%d)", pblockname, pblocknum + 2); } else { printf("(%s!%d)", pblockname, pblocknum + 3); /* this is an if/else, so now we need yet another subblock */ popNamedBlock(); pushSubBlock(1); outBlock(); genbf_statement(a->v3); printf("(%s!%d)", pblockname, pblocknum + 3); } /* finally continue with our regularly scheduled programming */ popNamedBlock(); pushBlock(); if (a->type == _IF) { curblock->num += 1; } else { curblock->num += 2; } outBlock(); break; case _SWITCH: UNIMPL("selection_statement"); /* SPC; printf("switch (\n"); genbf_expr(a->v1); SPC; printf(")\n"); genbf_statement(a->v2); */ break; } }
void KeGetCurrentIrql(void){UNIMPL();}
/* Note: §c{apisetupmainthread} §emph{never returns; it calls §c{exits} */ void apisetupmainthread(struct gspos pos, struct api_thread_table *api_thread_table, void *api_main_thread_data, struct api_prim_table *api_prim_table, gsvalue entry) { struct api_thread *mainthread, *thread; int threadnum; int suspended_runnable_thread; struct api_thread_stats stats; if (api_thread_queue) gsfatal("apisetupmainthread called twice") ; api_thread_queue = gs_sys_global_block_suballoc(&api_thread_queue_info, sizeof(*api_thread_queue)); memset(api_thread_queue, 0, sizeof(*api_thread_queue)); mainthread = api_add_thread(pos, api_thread_table, api_main_thread_data, api_prim_table, entry); mainthread->ismain = 1; api_release_thread(mainthread); mainthread = 0; stats.thread_lifetime = 0; stats.loops = stats.instrs = stats.loops_waiting = 0; for (;;) { suspended_runnable_thread = 0; if (gs_sys_should_gc()) { struct gsstringbuilder *err; gsstatprint("Before garbage collection: %dMB used\n", gs_sys_memory_allocated_size() / 0x400 / 0x400); err = gsreserve_string_builder(); gs_sys_wait_for_gc(); if (gs_sys_start_gc(err) < 0) { gsfinish_string_builder(err); api_handle_gc_failed(err); goto gc_done; } err = gsreserve_string_builder(); if (api_gc_trace_thread_queue(err) < 0) { gsfinish_string_builder(err); api_handle_gc_failed(err); goto gc_done; } if (gs_sys_finish_gc(err) < 0) { gsfinish_string_builder(err); api_handle_gc_failed(err); goto gc_done; } gsstatprint("After garbage collection: %dMB used\n", gs_sys_memory_allocated_size() / 0x400 / 0x400); } gc_done: if (gs_sys_memory_exhausted()) { gswarning("%s:%d: About to terminate on out of memory (%dMB used)", __FILE__, __LINE__, gs_sys_memory_allocated_size() / 0x400 / 0x400); api_take_thread_queue(); for (threadnum = 0; threadnum < API_NUMTHREADS; threadnum++) { thread = &api_thread_queue->threads[threadnum]; api_take_thread(thread); if (thread->state == api_thread_st_active) api_abend(thread, UNIMPL("Terminate on out of memory")) ; api_release_thread(thread); } api_release_thread_queue(); } for (threadnum = 0; threadnum < API_NUMTHREADS; threadnum++) { thread = 0; api_take_thread_queue(); for (; threadnum < API_NUMTHREADS && !thread; threadnum++) { thread = api_try_schedule_thread(&api_thread_queue->threads[threadnum]); } api_release_thread_queue(); if (thread) { stats.loops++; switch (thread->state) { case api_thread_st_active: { gstypecode st; gsvalue instr; struct api_code_segment *code; code = thread->code; instr = code->instrs[code->ip].instr; st = GS_SLOW_EVALUATE(code->instrs[code->ip].pos, instr); switch (st) { case gstywhnf: stats.instrs++; if (api_exec_instr(thread, instr) > 0) suspended_runnable_thread = 1 ; break; case gstyerr: case gstyimplerr: api_exec_err(thread, instr, st); break; case gstystack: stats.loops_waiting++; break; case gstyindir: code->instrs[code->ip].instr = GS_REMOVE_INDIRECTION(code->instrs[code->ip].pos, instr); suspended_runnable_thread = 1; break; case gstyenosys: api_abend(thread, "Un-implemented operation: %r"); break; default: api_abend_unimpl(thread, __FILE__, __LINE__, "API thread advancement (state = %d)", st); break; } break; } case api_thread_st_terminating_on_done: case api_thread_st_terminating_on_abend: { enum api_prim_execution_state st; int thread_abended = thread->state == api_thread_st_terminating_on_abend; if (gsflag_stat_collection && !thread->prog_term_time) { thread->prog_term_time = nsec(); stats.thread_lifetime += thread->prog_term_time - thread->start_time; } st = thread->api_thread_table->thread_term_status(thread); switch (st) { case api_st_success: { int have_other_threads; api_take_thread_queue(); api_thread_queue->numthreads--; have_other_threads = api_thread_queue->numthreads > 0; api_release_thread_queue(); thread->state = api_thread_st_unused; if (thread->ismain) { if (have_other_threads) { api_thread_pool_shutdown(&stats); gs_sys_num_procs--; gsfatal(UNIMPL("Thread is main thread and there are background threads --- fork into background. Do not release ACE or run shutdown hooks yet.")); } else { api_thread_pool_shutdown(&stats); if (thread_abended) { fprint(2, "%s\n", thread->status->start); gs_sys_num_procs--; exits(thread->status->start); } else { gs_sys_num_procs--; exits(""); } } } else { /* Thread is background thread */ if (have_other_threads) { api_thread_pool_shutdown(&stats); gs_sys_num_procs--; gsfatal(UNIMPL("Thread is background thread and there are other threads --- shut down thread and keep going. Do not release ACE or run shutdown hooks yet.")); } else { api_thread_pool_shutdown(&stats); gs_sys_num_procs--; gsfatal(UNIMPL("Thread is last background thread --- shut down. Always exits(\"\") in this case; exit status doesn't matter anyway. Complication: Need to run the stuff at the bottom of this thread, too.")); } } break; } case api_st_blocked: break; default: thread->state = api_thread_st_unused; api_thread_pool_shutdown(&stats); gs_sys_num_procs--; gsfatal(UNIMPL("Handle state %d from thread terminator next"), st); break; } break; } default: { thread->state = api_thread_st_unused; api_thread_pool_shutdown(&stats); gs_sys_num_procs--; gsfatal(UNIMPL("Handle thread state %d next"), thread->state); break; } } api_release_thread(thread); } } if (!suspended_runnable_thread) if (sleep(1) < 0) gswarning("%s:%d: sleep returned a negative number", __FILE__, __LINE__) ; } }
void KeInitializeEvent(void *event){UNIMPL();}
void RtlUnwind(void){UNIMPL();}
void genbf_type_specifier_list(struct type_specifier_list *a) { UNIMPL("type_specifier_list"); }
void KfReleaseSpinLock(void){UNIMPL();}
void RtlCompareMemory(void){UNIMPL();}