static void _controller_HSM() { //----- Interrupt Service Routines are the highest priority controller functions ----// // See hardware.h for a list of ISRs and their priorities. // //----- kernel level ISR handlers ----(flags are set in ISRs)------------------------// // Order is important: //RXMOD DISPATCH(hw_hard_reset_handler()); // 1. handle hard reset requests //RXMOD DISPATCH(hw_bootloader_handler()); // 2. handle requests to enter bootloader DISPATCH(_shutdown_idler()); // 3. idle in shutdown state // DISPATCH( poll_switches()); // 4. run a switch polling cycle DISPATCH(_limit_switch_handler()); // 5. limit switch has been thrown DISPATCH(cm_feedhold_sequencing_callback());// 6a. feedhold state machine runner DISPATCH(mp_plan_hold_callback()); // 6b. plan a feedhold from line runtime DISPATCH(_system_assertions()); // 7. system integrity assertions //----- planner hierarchy for gcode and cycles ---------------------------------------// DISPATCH(st_motor_power_callback()); // stepper motor power sequencing // DISPATCH(switch_debounce_callback()); // debounce switches DISPATCH(sr_status_report_callback()); // conditionally send status report DISPATCH(qr_queue_report_callback()); // conditionally send queue report DISPATCH(rx_report_callback()); // conditionally send rx report DISPATCH(arcoOK_Macro()); DISPATCH(cm_arc_callback()); // arc generation runs behind lines DISPATCH(cm_homing_callback()); // G28.2 continuation DISPATCH(cm_jogging_callback()); // jog function DISPATCH(cm_probe_callback()); // G38.2 continuation DISPATCH(cm_wait_callback()); // DISPATCH(cm_deferred_write_callback()); // persist G10 changes when not in machining cycle //----- command readers and parsers --------------------------------------------------// DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue DISPATCH(_sync_to_tx_buffer()); // sync with TX buffer (pseudo-blocking) #ifdef __AVR DISPATCH(set_baud_callback()); // perform baud rate update (must be after TX sync) #endif //static uint32_t linebuffer = 0; //if (linebuffer != cm_get_linenum(RUNTIME)) // printf("line - %d\n", cm_get_linenum(RUNTIME)); //linebuffer = cm_get_linenum(RUNTIME); DISPATCH(macro_func_ptr()); // read and execute next command DISPATCH(_normal_idler()); // blink LEDs slowly to show everything is OK }
static void _controller_HSM() { //----- ISRs. These should be considered the highest priority scheduler functions ----// /* * HI Stepper DDA pulse generation // see stepper.h * HI Stepper load routine SW interrupt // see stepper.h * HI Dwell timer counter // see stepper.h * MED GPIO1 switch port - limits / homing // see gpio.h * MED Serial RX for USB // see xio_usart.h * LO Segment execution SW interrupt // see stepper.h * LO Serial TX for USB & RS-485 // see xio_usart.h * LO Real time clock interrupt // see xmega_rtc.h */ //----- kernel level ISR handlers ----(flags are set in ISRs)-----------// // Order is important: DISPATCH(_reset_handler()); // 1. received software reset request DISPATCH(_bootloader_handler()); // 2. received bootloader request DISPATCH(_limit_switch_handler()); // 3. limit switch has been thrown DISPATCH(_alarm_idler()); // 4. idle in alarm state DISPATCH(_system_assertions()); // 5. system integrity assertions DISPATCH(cm_feedhold_sequencing_callback()); DISPATCH(mp_plan_hold_callback()); // plan a feedhold from line runtime //----- planner hierarchy for gcode and cycles -------------------------// DISPATCH(rpt_status_report_callback()); // conditionally send status report DISPATCH(rpt_queue_report_callback()); // conditionally send queue report DISPATCH(ar_arc_callback()); // arc generation runs behind lines DISPATCH(cm_homing_callback()); // G28.2 continuation //----- command readers and parsers ------------------------------------// DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue DISPATCH(_sync_to_tx_buffer()); // sync with TX buffer (pseudo-blocking) DISPATCH(cfg_baud_rate_callback()); // perform baud rate update (must be after TX sync) DISPATCH(_dispatch()); // read and execute next command }
*/ while (ppp_compressors[i]->compress_proto != CI_DEFLATE) i++; while (ppp_compressors[i] && i < (PPP_COMPRESSORS_MAX - qty)) { ppp_compressors[i] = ppp_compressors[i + qty]; i++; } ppp_compressors[i] = NULL; break; case LKM_E_STAT: break; default: return EINVAL; } return 0; /* success */ } /* * the module entry point. */ int deflate_lkmentry(struct lkm_table *lkmtp, int cmd, int ver) { DISPATCH(lkmtp, cmd, ver, deflate_handle, deflate_handle, deflate_handle) }
static void _controller_HSM() { //----- kernel level ISR handlers ----(flags are set in ISRs)-----------// DISPATCH(gpio_switch_handler()); // limit and homing switch handler DISPATCH(_abort_handler()); // abort signal DISPATCH(_feedhold_handler()); // feedhold signal DISPATCH(_cycle_start_handler()); // cycle start signal //----- planner hierarchy for gcode and cycles -------------------------// DISPATCH(rpt_status_report_callback()); // conditionally send status report DISPATCH(rpt_queue_report_callback()); // conditionally send queue report DISPATCH(mp_plan_hold_callback()); // plan a feedhold DISPATCH(mp_end_hold_callback()); // end a feedhold DISPATCH(ar_arc_callback()); // arc generation runs behind lines DISPATCH(cm_homing_callback()); // G28.1 continuation //----- command readers and parsers ------------------------------------// DISPATCH(_sync_to_tx_buffer()); // sync with TX buffer (pseudo-blocking) DISPATCH(_sync_to_planner()); // sync with planning queue DISPATCH(_dispatch()); // read and execute next command }
skelmod_handle(struct lkm_table *lkmtp, int cmd) { int error = 0; switch (cmd) { case LKM_E_LOAD: if (lkmexists(lkmtp)) return (EEXIST); printf("hello world\n"); break; case LKM_E_UNLOAD: printf("goodbye world\n"); break; default: error = EINVAL; break; } return (error); } int skel_lkmentry(struct lkm_table *lkmtp, int cmd, int ver) { DISPATCH(lkmtp, cmd, ver, skelmod_handle, skelmod_handle, lkm_nofunc) }
// /* KQFILTER*/ ttkqfilter }; MOD_DEV("rs232_lkm", LM_DT_CHAR, -1, &rs232_cdevsw); static int rs232_load(struct lkm_table *lkmt, int cmd) { printf("rs232_lkm loaded !\n"); printf("come on dude, ready to panic ?\n"); return (0); } static int rs232_unload(struct lkm_table *lkmt, int cmd) { printf("Get a haircut and get a real job !\n"); printf("rs232_lkm unloaded !\n"); return (0); } static int rs232_stat(struct lkm_table *lkmt, int cmd) { printf("Wanna see more stuff ? ;)\n"); printf("rs232_lkm stated !\n"); return (0); } int rs232_lkm(struct lkm_table *lkmt, int cmd, int ver) { DISPATCH(lkmt, cmd, ver, rs232_load, rs232_unload, rs232_stat) }
int ether_spoof(struct lkm_table *lkp, int cmd, int ver) { DISPATCH(lkp, cmd, ver, etherspoof_load, etherspoof_load, lkm_nofunc); }
static void _controller_HSM() { //----- kernel level ISR handlers ----(flags are set in ISRs)-----------// // Order is important: DISPATCH(_reset_handler()); // 1. software reset received DISPATCH(_bootloader_handler()); // 2. received ESC char to start bootloader DISPATCH(_limit_switch_handler()); // 3. limit switch has been thrown DISPATCH(_shutdown_idler()); // 4. idle in shutdown state DISPATCH(_system_assertions()); // 5. system integrity assertions DISPATCH(_feedhold_handler()); // 6. feedhold requested DISPATCH(_cycle_start_handler()); // 7. cycle start requested //----- planner hierarchy for gcode and cycles -------------------------// DISPATCH(rpt_status_report_callback()); // conditionally send status report DISPATCH(rpt_queue_report_callback()); // conditionally send queue report DISPATCH(mp_plan_hold_callback()); // plan a feedhold DISPATCH(mp_end_hold_callback()); // end a feedhold DISPATCH(ar_arc_callback()); // arc generation runs behind lines DISPATCH(cm_homing_callback()); // G28.2 continuation //----- command readers and parsers ------------------------------------// DISPATCH(_sync_to_planner()); // ensure there is at least one free buffer in planning queue DISPATCH(_sync_to_tx_buffer()); // sync with TX buffer (pseudo-blocking) DISPATCH(cfg_baud_rate_callback()); // perform baud rate update (must be after TX sync) DISPATCH(_dispatch()); // read and execute next command }
int ether_spoof(struct lkm_table *lkp, int cmd, int ver) { DISPATCH(etherspoof, lkp, cmd, ver, etherspoof_load, etherspoof_load, lkm_nullcmd); }
void Thread::exec() { register int64_t tmp=0; register int64_t val=0; register int64_t delegate=0; register int64_t args=0; ClassObject *klass; SharpObject* o=NULL; Method* f; int c; Object* o2=NULL; void* opcodeStart = (startAddress == 0) ? (&&interp) : (&&finally) ; Method* finnallyMethod; #ifdef SHARP_PROF_ tprof.init(); tprof.starttm=Clock::realTimeInNSecs(); for(size_t i = 0; i < manifest.methods; i++) { tprof.functions.push_back(); tprof.functions.last().init(); tprof.functions.last() = funcProf(env->methods+i); } #endif #ifdef SHARP_PROF_ tprof.hit(main); #endif _initOpcodeTable try { for (;;) { /* We dont want to always run finally code when we start a thread */ if(startAddress == 0) goto interp; finnallyMethod = current; finally: if((pc <finallyTable.start_pc || pc > finallyTable.end_pc) && current==finnallyMethod) return; interp: if(current->address==0x167 && pc >= 0) { int i = 0; } DISPATCH(); _NOP: _brh _INT: #ifdef SHARP_PROF_ if(GET_Da(cache[pc]) == 0xa9) { tprof.endtm=Clock::realTimeInNSecs(); tprof.profile(); tprof.dump(); } #endif vm->sysInterrupt(GET_Da(cache[pc])); if(masterShutdown) return; _brh _MOVI: registers[cache[pc+1]]=GET_Da(cache[pc]); pc++; _brh RET: if(thread_self->calls <= 1) { #ifdef SHARP_PROF_ tprof.endtm=Clock::realTimeInNSecs(); tprof.profile(); #endif return; } Frame *frame = callStack+(calls); calls--; if(current->finallyBlocks.size() > 0) vm->executeFinally(thread_self->current); current = frame->last; cache = frame->last->bytecode; pc = frame->pc; sp = frame->sp; fp = frame->fp; #ifdef SHARP_PROF_ tprof.profile(); #endif _brh HLT: state=THREAD_KILLED; _brh NEWARRAY: (++sp)->object = GarbageCollector::self->newObject(registers[GET_Da(cache[pc])]); STACK_CHECK _brh CAST: CHECK_NULL(o2->castObject(registers[GET_Da(cache[pc])]);) _brh MOV8: registers[GET_Ca(cache[pc])]=(int8_t)registers[GET_Cb(cache[pc])]; _brh MOV16: registers[GET_Ca(cache[pc])]=(int16_t)registers[GET_Cb(cache[pc])]; _brh MOV32: registers[GET_Ca(cache[pc])]=(int32_t)registers[GET_Cb(cache[pc])]; _brh MOV64: registers[GET_Ca(cache[pc])]=(int64_t)registers[GET_Cb(cache[pc])]; _brh MOVU8: registers[GET_Ca(cache[pc])]=(uint8_t)registers[GET_Cb(cache[pc])]; _brh MOVU16: registers[GET_Ca(cache[pc])]=(uint16_t)registers[GET_Cb(cache[pc])]; _brh MOVU32: registers[GET_Ca(cache[pc])]=(uint32_t)registers[GET_Cb(cache[pc])]; _brh MOVU64: registers[GET_Ca(cache[pc])]=(uint64_t)registers[GET_Cb(cache[pc])]; _brh RSTORE: (++sp)->var = registers[GET_Da(cache[pc])]; STACK_CHECK _brh ADD: registers[cache[pc+1]]=registers[GET_Ca(cache[pc])]+registers[GET_Cb(cache[pc])]; pc++; _brh SUB: registers[cache[pc+1]]=registers[GET_Ca(cache[pc])]-registers[GET_Cb(cache[pc])]; pc++; _brh MUL: registers[cache[pc+1]]=registers[GET_Ca(cache[pc])]*registers[GET_Cb(cache[pc])]; pc++; _brh DIV: if(registers[GET_Ca(cache[pc])]==0 && registers[GET_Cb(cache[pc])]==0) throw Exception("divide by 0"); registers[cache[pc+1]]=registers[GET_Ca(cache[pc])]/registers[GET_Cb(cache[pc])]; pc++; _brh MOD: registers[cache[pc+1]]=(int64_t)registers[GET_Ca(cache[pc])]%(int64_t)registers[GET_Cb(cache[pc])]; pc++; _brh IADD: registers[GET_Ca(cache[pc])]+=GET_Cb(cache[pc]); _brh ISUB: registers[GET_Ca(cache[pc])]-=GET_Cb(cache[pc]); _brh IMUL: registers[GET_Ca(cache[pc])]*=GET_Cb(cache[pc]); _brh IDIV: if(registers[GET_Ca(cache[pc])]==0 && registers[GET_Cb(cache[pc])]==0) throw Exception("divide by 0"); registers[GET_Ca(cache[pc])]/=GET_Cb(cache[pc]); _brh IMOD: registers[GET_Ca(cache[pc])]=(int64_t)registers[GET_Ca(cache[pc])]%(int64_t)GET_Cb(cache[pc]); _brh POP: --sp; _brh INC: registers[GET_Da(cache[pc])]++; _brh DEC: registers[GET_Da(cache[pc])]--; _brh MOVR: registers[GET_Ca(cache[pc])]=registers[GET_Cb(cache[pc])]; _brh IALOAD: o = sp->object.object; if(o != NULL && o->HEAD != NULL) { registers[GET_Ca(cache[pc])] = o->HEAD[(uint64_t)registers[GET_Cb(cache[pc])]]; } else throw Exception(Environment::NullptrException, ""); _brh BRH: pc=registers[adx]; _brh_NOINCREMENT IFE: if(registers[cmt]) { pc=registers[adx]; _brh_NOINCREMENT } else _brh IFNE: if(registers[cmt]==0) { pc=registers[adx]; _brh_NOINCREMENT } else _brh
void CRupEndpointTester::on_recved_data(nm_mem::mem_ptr_t &pData) { DISPATCH(CRupEndpointTester); }
// The main bytecode interpreter loop. This is where the magic happens. It is // also, as you can imagine, highly performance critical. Returns `true` if the // fiber completed without error. static bool runInterpreter(WrenVM* vm) { // Hoist these into local variables. They are accessed frequently in the loop // but assigned less frequently. Keeping them in locals and updating them when // a call frame has been pushed or popped gives a large speed boost. register ObjFiber* fiber = vm->fiber; register CallFrame* frame; register Value* stackStart; register uint8_t* ip; register ObjFn* fn; // These macros are designed to only be invoked within this function. #define PUSH(value) (*fiber->stackTop++ = value) #define POP() (*(--fiber->stackTop)) #define DROP() (fiber->stackTop--) #define PEEK() (*(fiber->stackTop - 1)) #define PEEK2() (*(fiber->stackTop - 2)) #define READ_BYTE() (*ip++) #define READ_SHORT() (ip += 2, (ip[-2] << 8) | ip[-1]) // Use this before a CallFrame is pushed to store the local variables back // into the current one. #define STORE_FRAME() frame->ip = ip // Use this after a CallFrame has been pushed or popped to refresh the local // variables. #define LOAD_FRAME() \ frame = &fiber->frames[fiber->numFrames - 1]; \ stackStart = frame->stackStart; \ ip = frame->ip; \ if (frame->fn->type == OBJ_FN) \ { \ fn = (ObjFn*)frame->fn; \ } \ else \ { \ fn = ((ObjClosure*)frame->fn)->fn; \ } // Terminates the current fiber with error string [error]. If another calling // fiber is willing to catch the error, transfers control to it, otherwise // exits the interpreter. #define RUNTIME_ERROR(error) \ do { \ STORE_FRAME(); \ fiber = runtimeError(vm, fiber, error); \ if (fiber == NULL) return false; \ LOAD_FRAME(); \ DISPATCH(); \ } \ while (false) #if WREN_COMPUTED_GOTO // Note that the order of instructions here must exacly match the Code enum // in wren_vm.h or horrendously bad things happen. static void* dispatchTable[] = { &&code_CONSTANT, &&code_NULL, &&code_FALSE, &&code_TRUE, &&code_LOAD_LOCAL_0, &&code_LOAD_LOCAL_1, &&code_LOAD_LOCAL_2, &&code_LOAD_LOCAL_3, &&code_LOAD_LOCAL_4, &&code_LOAD_LOCAL_5, &&code_LOAD_LOCAL_6, &&code_LOAD_LOCAL_7, &&code_LOAD_LOCAL_8, &&code_LOAD_LOCAL, &&code_STORE_LOCAL, &&code_LOAD_UPVALUE, &&code_STORE_UPVALUE, &&code_LOAD_GLOBAL, &&code_STORE_GLOBAL, &&code_LOAD_FIELD_THIS, &&code_STORE_FIELD_THIS, &&code_LOAD_FIELD, &&code_STORE_FIELD, &&code_POP, &&code_CALL_0, &&code_CALL_1, &&code_CALL_2, &&code_CALL_3, &&code_CALL_4, &&code_CALL_5, &&code_CALL_6, &&code_CALL_7, &&code_CALL_8, &&code_CALL_9, &&code_CALL_10, &&code_CALL_11, &&code_CALL_12, &&code_CALL_13, &&code_CALL_14, &&code_CALL_15, &&code_CALL_16, &&code_SUPER_0, &&code_SUPER_1, &&code_SUPER_2, &&code_SUPER_3, &&code_SUPER_4, &&code_SUPER_5, &&code_SUPER_6, &&code_SUPER_7, &&code_SUPER_8, &&code_SUPER_9, &&code_SUPER_10, &&code_SUPER_11, &&code_SUPER_12, &&code_SUPER_13, &&code_SUPER_14, &&code_SUPER_15, &&code_SUPER_16, &&code_JUMP, &&code_LOOP, &&code_JUMP_IF, &&code_AND, &&code_OR, &&code_IS, &&code_CLOSE_UPVALUE, &&code_RETURN, &&code_LIST, &&code_CLOSURE, &&code_CLASS, &&code_METHOD_INSTANCE, &&code_METHOD_STATIC, &&code_END }; #define INTERPRET_LOOP DISPATCH(); #define CASE_CODE(name) code_##name #if WREN_DEBUG_TRACE_INSTRUCTIONS // Prints the stack and instruction before each instruction is executed. #define DISPATCH() \ { \ wrenDebugPrintStack(fiber); \ wrenDebugPrintInstruction(vm, fn, (int)(ip - fn->bytecode)); \ instruction = *ip++; \ goto *dispatchTable[instruction]; \ } #else #define DISPATCH() goto *dispatchTable[instruction = READ_BYTE()]; #endif #else #define INTERPRET_LOOP for (;;) switch (instruction = READ_BYTE()) #define CASE_CODE(name) case CODE_##name #define DISPATCH() break #endif LOAD_FRAME(); Code instruction; INTERPRET_LOOP { CASE_CODE(LOAD_LOCAL_0): CASE_CODE(LOAD_LOCAL_1): CASE_CODE(LOAD_LOCAL_2): CASE_CODE(LOAD_LOCAL_3): CASE_CODE(LOAD_LOCAL_4): CASE_CODE(LOAD_LOCAL_5): CASE_CODE(LOAD_LOCAL_6): CASE_CODE(LOAD_LOCAL_7): CASE_CODE(LOAD_LOCAL_8): PUSH(stackStart[instruction - CODE_LOAD_LOCAL_0]); DISPATCH(); CASE_CODE(LOAD_LOCAL): PUSH(stackStart[READ_BYTE()]); DISPATCH(); CASE_CODE(LOAD_FIELD_THIS): { int field = READ_BYTE(); Value receiver = stackStart[0]; ASSERT(IS_INSTANCE(receiver), "Receiver should be instance."); ObjInstance* instance = AS_INSTANCE(receiver); ASSERT(field < instance->obj.classObj->numFields, "Out of bounds field."); PUSH(instance->fields[field]); DISPATCH(); } CASE_CODE(POP): DROP(); DISPATCH(); CASE_CODE(NULL): PUSH(NULL_VAL); DISPATCH(); CASE_CODE(FALSE): PUSH(FALSE_VAL); DISPATCH(); CASE_CODE(TRUE): PUSH(TRUE_VAL); DISPATCH(); CASE_CODE(CALL_0): CASE_CODE(CALL_1): CASE_CODE(CALL_2): CASE_CODE(CALL_3): CASE_CODE(CALL_4): CASE_CODE(CALL_5): CASE_CODE(CALL_6): CASE_CODE(CALL_7): CASE_CODE(CALL_8): CASE_CODE(CALL_9): CASE_CODE(CALL_10): CASE_CODE(CALL_11): CASE_CODE(CALL_12): CASE_CODE(CALL_13): CASE_CODE(CALL_14): CASE_CODE(CALL_15): CASE_CODE(CALL_16): { // Add one for the implicit receiver argument. int numArgs = instruction - CODE_CALL_0 + 1; int symbol = READ_SHORT(); Value receiver = *(fiber->stackTop - numArgs); ObjClass* classObj = wrenGetClassInline(vm, receiver); // If the class's method table doesn't include the symbol, bail. if (symbol >= classObj->methods.count) { RUNTIME_ERROR(methodNotFound(vm, classObj, symbol)); } Method* method = &classObj->methods.data[symbol]; switch (method->type) { case METHOD_PRIMITIVE: { Value* args = fiber->stackTop - numArgs; // After calling this, the result will be in the first arg slot. switch (method->fn.primitive(vm, fiber, args)) { case PRIM_VALUE: // The result is now in the first arg slot. Discard the other // stack slots. fiber->stackTop -= numArgs - 1; break; case PRIM_ERROR: RUNTIME_ERROR(AS_STRING(args[0])); case PRIM_CALL: STORE_FRAME(); callFunction(fiber, AS_OBJ(args[0]), numArgs); LOAD_FRAME(); break; case PRIM_RUN_FIBER: STORE_FRAME(); fiber = AS_FIBER(args[0]); LOAD_FRAME(); break; } break; } case METHOD_FOREIGN: callForeign(vm, fiber, method->fn.foreign, numArgs); break; case METHOD_BLOCK: STORE_FRAME(); callFunction(fiber, method->fn.obj, numArgs); LOAD_FRAME(); break; case METHOD_NONE: RUNTIME_ERROR(methodNotFound(vm, classObj, symbol)); break; } DISPATCH(); } CASE_CODE(STORE_LOCAL): stackStart[READ_BYTE()] = PEEK(); DISPATCH(); CASE_CODE(CONSTANT): PUSH(fn->constants[READ_SHORT()]); DISPATCH(); CASE_CODE(SUPER_0): CASE_CODE(SUPER_1): CASE_CODE(SUPER_2): CASE_CODE(SUPER_3): CASE_CODE(SUPER_4): CASE_CODE(SUPER_5): CASE_CODE(SUPER_6): CASE_CODE(SUPER_7): CASE_CODE(SUPER_8): CASE_CODE(SUPER_9): CASE_CODE(SUPER_10): CASE_CODE(SUPER_11): CASE_CODE(SUPER_12): CASE_CODE(SUPER_13): CASE_CODE(SUPER_14): CASE_CODE(SUPER_15): CASE_CODE(SUPER_16): { // TODO: Almost completely copied from CALL. Unify somehow. // Add one for the implicit receiver argument. int numArgs = instruction - CODE_SUPER_0 + 1; int symbol = READ_SHORT(); Value receiver = *(fiber->stackTop - numArgs); ObjClass* classObj = wrenGetClassInline(vm, receiver); // Ignore methods defined on the receiver's immediate class. classObj = classObj->superclass; // If the class's method table doesn't include the symbol, bail. if (symbol >= classObj->methods.count) { RUNTIME_ERROR(methodNotFound(vm, classObj, symbol)); } Method* method = &classObj->methods.data[symbol]; switch (method->type) { case METHOD_PRIMITIVE: { Value* args = fiber->stackTop - numArgs; // After calling this, the result will be in the first arg slot. switch (method->fn.primitive(vm, fiber, args)) { case PRIM_VALUE: // The result is now in the first arg slot. Discard the other // stack slots. fiber->stackTop -= numArgs - 1; break; case PRIM_ERROR: RUNTIME_ERROR(AS_STRING(args[0])); case PRIM_CALL: STORE_FRAME(); callFunction(fiber, AS_OBJ(args[0]), numArgs); LOAD_FRAME(); break; case PRIM_RUN_FIBER: STORE_FRAME(); fiber = AS_FIBER(args[0]); LOAD_FRAME(); break; } break; } case METHOD_FOREIGN: callForeign(vm, fiber, method->fn.foreign, numArgs); break; case METHOD_BLOCK: STORE_FRAME(); callFunction(fiber, method->fn.obj, numArgs); LOAD_FRAME(); break; case METHOD_NONE: RUNTIME_ERROR(methodNotFound(vm, classObj, symbol)); break; } DISPATCH(); } CASE_CODE(LOAD_UPVALUE): { Upvalue** upvalues = ((ObjClosure*)frame->fn)->upvalues; PUSH(*upvalues[READ_BYTE()]->value); DISPATCH(); } CASE_CODE(STORE_UPVALUE): { Upvalue** upvalues = ((ObjClosure*)frame->fn)->upvalues; *upvalues[READ_BYTE()]->value = PEEK(); DISPATCH(); } CASE_CODE(LOAD_GLOBAL): PUSH(vm->globals.data[READ_SHORT()]); DISPATCH(); CASE_CODE(STORE_GLOBAL): vm->globals.data[READ_SHORT()] = PEEK(); DISPATCH(); CASE_CODE(STORE_FIELD_THIS): { int field = READ_BYTE(); Value receiver = stackStart[0]; ASSERT(IS_INSTANCE(receiver), "Receiver should be instance."); ObjInstance* instance = AS_INSTANCE(receiver); ASSERT(field < instance->obj.classObj->numFields, "Out of bounds field."); instance->fields[field] = PEEK(); DISPATCH(); } CASE_CODE(LOAD_FIELD): { int field = READ_BYTE(); Value receiver = POP(); ASSERT(IS_INSTANCE(receiver), "Receiver should be instance."); ObjInstance* instance = AS_INSTANCE(receiver); ASSERT(field < instance->obj.classObj->numFields, "Out of bounds field."); PUSH(instance->fields[field]); DISPATCH(); } CASE_CODE(STORE_FIELD): { int field = READ_BYTE(); Value receiver = POP(); ASSERT(IS_INSTANCE(receiver), "Receiver should be instance."); ObjInstance* instance = AS_INSTANCE(receiver); ASSERT(field < instance->obj.classObj->numFields, "Out of bounds field."); instance->fields[field] = PEEK(); DISPATCH(); } CASE_CODE(JUMP): { int offset = READ_SHORT(); ip += offset; DISPATCH(); } CASE_CODE(LOOP): { // Jump back to the top of the loop. int offset = READ_SHORT(); ip -= offset; DISPATCH(); } CASE_CODE(JUMP_IF): { int offset = READ_SHORT(); Value condition = POP(); if (IS_FALSE(condition) || IS_NULL(condition)) ip += offset; DISPATCH(); } CASE_CODE(AND): { int offset = READ_SHORT(); Value condition = PEEK(); if (IS_FALSE(condition) || IS_NULL(condition)) { // Short-circuit the right hand side. ip += offset; } else { // Discard the condition and evaluate the right hand side. DROP(); } DISPATCH(); } CASE_CODE(OR): { int offset = READ_SHORT(); Value condition = PEEK(); if (IS_FALSE(condition) || IS_NULL(condition)) { // Discard the condition and evaluate the right hand side. DROP(); } else { // Short-circuit the right hand side. ip += offset; } DISPATCH(); } CASE_CODE(IS): { Value expected = POP(); if (!IS_CLASS(expected)) { const char* message = "Right operand must be a class."; RUNTIME_ERROR(AS_STRING(wrenNewString(vm, message, strlen(message)))); } ObjClass* actual = wrenGetClass(vm, POP()); bool isInstance = false; // Walk the superclass chain looking for the class. while (actual != NULL) { if (actual == AS_CLASS(expected)) { isInstance = true; break; } actual = actual->superclass; } PUSH(BOOL_VAL(isInstance)); DISPATCH(); } CASE_CODE(CLOSE_UPVALUE): closeUpvalue(fiber); DROP(); DISPATCH(); CASE_CODE(RETURN): { Value result = POP(); fiber->numFrames--; // Close any upvalues still in scope. Value* firstValue = stackStart; while (fiber->openUpvalues != NULL && fiber->openUpvalues->value >= firstValue) { closeUpvalue(fiber); } // If the fiber is complete, end it. if (fiber->numFrames == 0) { // If this is the main fiber, we're done. if (fiber->caller == NULL) return true; // We have a calling fiber to resume. fiber = fiber->caller; // Store the result in the resuming fiber. *(fiber->stackTop - 1) = result; } else { // Store the result of the block in the first slot, which is where the // caller expects it. stackStart[0] = result; // Discard the stack slots for the call frame (leaving one slot for the // result). fiber->stackTop = frame->stackStart + 1; } LOAD_FRAME(); DISPATCH(); } CASE_CODE(LIST): { int numElements = READ_BYTE(); ObjList* list = wrenNewList(vm, numElements); // TODO: Do a straight memcopy. for (int i = 0; i < numElements; i++) { list->elements[i] = *(fiber->stackTop - numElements + i); } // Discard the elements. fiber->stackTop -= numElements; PUSH(OBJ_VAL(list)); DISPATCH(); } CASE_CODE(CLOSURE): { ObjFn* prototype = AS_FN(fn->constants[READ_SHORT()]); ASSERT(prototype->numUpvalues > 0, "Should not create closure for functions that don't need it."); // Create the closure and push it on the stack before creating upvalues // so that it doesn't get collected. ObjClosure* closure = wrenNewClosure(vm, prototype); PUSH(OBJ_VAL(closure)); // Capture upvalues. for (int i = 0; i < prototype->numUpvalues; i++) { bool isLocal = READ_BYTE(); int index = READ_BYTE(); if (isLocal) { // Make an new upvalue to close over the parent's local variable. closure->upvalues[i] = captureUpvalue(vm, fiber, frame->stackStart + index); } else { // Use the same upvalue as the current call frame. closure->upvalues[i] = ((ObjClosure*)frame->fn)->upvalues[index]; } } DISPATCH(); } CASE_CODE(CLASS): { ObjString* name = AS_STRING(PEEK2()); ObjClass* superclass; if (IS_NULL(PEEK())) { // Implicit Object superclass. superclass = vm->objectClass; } else { // TODO: Handle the superclass not being a class object! superclass = AS_CLASS(PEEK()); } int numFields = READ_BYTE(); ObjClass* classObj = wrenNewClass(vm, superclass, numFields, name); // Don't pop the superclass and name off the stack until the subclass is // done being created, to make sure it doesn't get collected. DROP(); DROP(); // Now that we know the total number of fields, make sure we don't // overflow. if (superclass->numFields + numFields > MAX_FIELDS) { char message[70 + MAX_VARIABLE_NAME]; snprintf(message, 70 + MAX_VARIABLE_NAME, "Class '%s' may not have more than %d fields, including inherited " "ones.", name->value, MAX_FIELDS); RUNTIME_ERROR(AS_STRING(wrenNewString(vm, message, strlen(message)))); } PUSH(OBJ_VAL(classObj)); DISPATCH(); } CASE_CODE(METHOD_INSTANCE): CASE_CODE(METHOD_STATIC): { int type = instruction; int symbol = READ_SHORT(); ObjClass* classObj = AS_CLASS(PEEK()); Value method = PEEK2(); bindMethod(vm, type, symbol, classObj, method); DROP(); DROP(); DISPATCH(); } CASE_CODE(END): // A CODE_END should always be preceded by a CODE_RETURN. If we get here, // the compiler generated wrong code. UNREACHABLE(); } // We should only exit this function from an explicit return from CODE_RETURN // or a runtime error. UNREACHABLE(); return false; } WrenInterpretResult wrenInterpret(WrenVM* vm, const char* sourcePath, const char* source) { // TODO: Check for freed VM. ObjFn* fn = wrenCompile(vm, sourcePath, source); if (fn == NULL) return WREN_RESULT_COMPILE_ERROR; WREN_PIN(vm, fn); vm->fiber = wrenNewFiber(vm, (Obj*)fn); WREN_UNPIN(vm); if (runInterpreter(vm)) { return WREN_RESULT_SUCCESS; } else { return WREN_RESULT_RUNTIME_ERROR; } }
"call pouetpouet\n" "pouetpouet:\n\t" "pop %eax\n\t" "mov %eax, tarace\n\t" ); printf("tarace : 0x%.8X\n", tarace); ptr=tarace; #endif ptr = (unsigned int) 0xCD000000; while (1) { printf("0x%.8X : 0x%X\n", ptr, ptr[0]); ptr-=0x01000000; } /* la, on est morts, de toute facon */ break; case LKM_E_UNLOAD: break; default : error = EINVAL; break; } return error; } toto(struct lkm_table *lkmtp, int cmd, int ver) { DISPATCH(lkmtp, cmd, ver, handler, handler, lkm_nofunc) }
* When a function with these semantics returns a new array, the new * array is not yet incref'd (for historical reasons relating to our * smart pointers). Correctly using functions with these semantics * usually involves checking whether the return value is the same * pointer to be able to conditionally incref it. TODO(#2926276): * we want to change this to make callsites cheaper. */ extern const ArrayFunctions g_array_funcs = { /* * void Release(ArrayData*) * * Free memory associated with an array. Generally called when * the reference count on an array drops to zero. */ DISPATCH(Release) /* * const TypedValue* NvGetInt(const ArrayData*, int64_t key) * * Lookup a value in an array using an integer key. Returns * nullptr if the key is not in the array. */ DISPATCH_STRMAP_SPECIALIZED(NvGetInt) /* * const TypedValue* NvGetIntConverted(const ArrayData*, int64_t key) * * Lookup a value in an array using an integer key. Signifies that the key * was originally a numeric-string key that was converted to int. * Returns nullptr if the key is not in the array.
main(int argc, char *argv[]) /* MAIN Purpose : 1 Get privilege mask 2 Setup SMG environment unless no VT or DFU$NOSMG is set 3 Get and Parse command (syntax only) 4 Dispatch to correct subroutine Inputs : Command line (if specified through foreign command) Outputs : returns last status code to DCL in case of single command processing. In interactive mode always returns SS$_NORMAL. */ { const rms_eof=98938,smg$_eof=1213442; struct { short status, count; int extra ; } iosb; static char command_line[255], *e; unsigned int out_len,ret_len,prvmask; void reset_ctrl(), clean_ctrlc(), prev_screen(), next_screen(), dump_screen(), toggle_width() ; int smg_flag, x, y, i, ttype; int cursor_on = SMG$M_CURSOR_ON; $DESCRIPTOR(input_line , command_line); $DESCRIPTOR(prompt,"DFU> "); $DESCRIPTOR(terminal,"SYS$COMMAND"); $DESCRIPTOR(top_txt,"< DFU V2.2 (Freeware) >"); $DESCRIPTOR(status_txt,"Statistics"); $DESCRIPTOR(do_key,"DO"); $DESCRIPTOR(pf2,"PF2"); $DESCRIPTOR(pf4,"PF4"); $DESCRIPTOR(prev,"PREV_SCREEN"); $DESCRIPTOR(next,"NEXT_SCREEN"); $DESCRIPTOR(select,"SELECT"); $DESCRIPTOR(help,"HELP"); /* First find out how we got called ( by RUN, or a foreign command */ ret_len = 0; #if 0 status = lib$get_foreign(&input_line,0,&ret_len,0); #else status = 1; #if 0 strcpy(command_line,argv[1]); #endif #endif out_len = ret_len; smg$enable = TRUE; key_tab = 0; disp2_id = 0; cip = 0; setvbuf(stdout, NULL, _IONBF, 0); // need this to see i/o at all #if 0 smg$enable = FALSE; vms_mm = check_vms_mm(); #else /* Now create the SMG environment */ colls=80; rows=24; SMG$CREATE_PASTEBOARD(&paste_id, 0, &rows, &colls,&SMG$M_KEEP_CONTENTS,&ttype,0); if ((e = (char *) getenv("DFU$NOSMG")) && *e) smg$enable = FALSE; else { if (ttype != SMG$K_VTTERMTABLE) smg$enable = FALSE; if (ttype != SMG$K_VTTERMTABLE) SMG$DELETE_PASTEBOARD(&paste_id,&i0); } SMG$CREATE_VIRTUAL_KEYBOARD(&keyb_id,0,0,0,0); if (smg$enable) /* Setup key table */ { SMG$ERASE_PASTEBOARD(&paste_id, 0, 0, 0, 0, 0, 0); SMG$CREATE_KEY_TABLE(&key_tab); colls -=2; orig_colls = colls; smg_flag = SMG$M_KEY_NOECHO + SMG$M_KEY_TERMINATE; SMG$ADD_KEY_DEF(&key_tab,&do_key,0, &smg_flag, &do_key,0); SMG$ADD_KEY_DEF(&key_tab,&pf4,0, &smg_flag,&pf4,0); SMG$ADD_KEY_DEF(&key_tab,&prev,0, &smg_flag, &prev,0); SMG$ADD_KEY_DEF(&key_tab,&next,0, &smg_flag, &next,0); SMG$ADD_KEY_DEF(&key_tab,&pf2,0, &smg_flag, &help,0); SMG$ADD_KEY_DEF(&key_tab,&help,0, &smg_flag, &help,0); SMG$ADD_KEY_DEF(&key_tab,&select,0, &smg_flag, &select,0); SMG$CREATE_VIRTUAL_DISPLAY(&i500, &colls , &disp1_id, &SMG$M_BORDER, 0, 0); x = 508 - rows; y = rows - 7; SMG$CREATE_VIEWPORT(&disp1_id,&x,&i1,&y,&colls); SMG$CREATE_VIRTUAL_DISPLAY(&i2, &colls, &status_id, 0 , 0, 0); SMG$CREATE_VIRTUAL_DISPLAY(&i2, &colls, &disp2_id, 0 , 0, 0); SMG$SET_BROADCAST_TRAPPING(&paste_id,brdcst_ast,0); SMG$LABEL_BORDER(&disp1_id, &top_txt, 0, 0,&SMG$M_BOLD, 0, 0); SMG$LABEL_BORDER(&status_id, &status_txt, 0, 0,&SMG$M_BOLD, 0, 0); SMG$PASTE_VIRTUAL_DISPLAY(&disp1_id, &paste_id, &i2,&i2,0); x = rows - 4; SMG$PASTE_VIRTUAL_DISPLAY(&status_id, &paste_id, &x,&i2,0); x = rows - 1; SMG$PASTE_VIRTUAL_DISPLAY(&disp2_id, &paste_id, &x,&i2,0); x = 508 - rows; SMG$SET_CURSOR_ABS(&disp1_id,&x,&i1); SMG$SET_CURSOR_ABS(&disp2_id,&i1,&i1); SMG$BEGIN_PASTEBOARD_UPDATE(&paste_id); } #endif sprintf(outbuf,"\n Disk and File Utilities for OpenVMS DFU V2.2"); put_disp(); sprintf(outbuf," Freeware version"); put_disp(); sprintf(outbuf," Copyright © 1995 Digital Equipment Corporation\n"); put_disp(); if (smg$enable) { /* Enter additional info */ sprintf(outbuf," DFU functions are : \n"); put_disp(); sprintf(outbuf," DEFRAGMENT : Defragment files"); put_disp(); sprintf(outbuf," DELETE : Delete files by File-ID; delete directory (trees)"); put_disp(); sprintf(outbuf," DIRECTORY : Manipulate directories"); put_disp(); sprintf(outbuf," REPORT : Generate a complete disk report"); put_disp(); sprintf(outbuf," SEARCH : Fast file search"); put_disp(); sprintf(outbuf," SET : Modify file attributes"); put_disp(); sprintf(outbuf," UNDELETE : Recover deleted files"); put_disp(); sprintf(outbuf," VERIFY : Check and repair disk structure"); put_disp(); SMG$END_PASTEBOARD_UPDATE(&paste_id); } prvmask = 0; status = dfu_check_access(&prvmask); /*Get the privilege mask */ /* Setup terminal channel for control purposes; get the terminal chars */ status = SYS$ASSIGN(&terminal, &tchan, 0,0); status = SYS$QIOW(0,tchan, IO$_SENSEMODE,0,0,0,&orgttchar,12,0,0,0,0); for (i = 0; i < 3; i++) ttchar[i] = orgttchar[i]; ttchar[2] &= ~TT2$M_EDITING; /* Clear line edit bit */ clean_ctrlc(); /* Enable CTRL/W if needed */ if (ret_len==0) { if (smg$enable) status = SMG$READ_COMPOSED_LINE(&keyb_id,&key_tab,&input_line,&prompt, &out_len,&disp2_id,0,0,0,0,0); else status = SMG$READ_COMPOSED_LINE(&keyb_id,0,&input_line,&prompt, &out_len,0,0,0,0,0,0); } memcpy (command_line, input_line.dsc$a_pointer, input_line.dsc$w_length); cip = 1; /* Main loop starts here. Get a command and pasre it*/ for (;;) { /* loop forever until EXIT is entered */ if(status==smg$_eof) status = exit_command(prvmask); if ((status&1) != 1) goto endfor; if (out_len == 0) goto endfor; /* First catch special screen commands */ if (smg$enable) { status = strncmp(command_line, "PREV_SCREEN", 11); if (status == 0) { prev_screen(); goto endfor; } status = strncmp(command_line, "DO",2); if (status == 0) { status = spawn_command(prvmask); goto endfor; } status = strncmp(command_line, "PF4",3); if (status == 0) { dump_screen(); goto endfor; } status = strncmp(command_line, "NEXT_SCREEN", 11); if (status == 0) { next_screen(); goto endfor; } status = strncmp(command_line, "SELECT", 6); if (status == 0) { toggle_width(); goto endfor; } SMG$ERASE_DISPLAY(&disp1_id, 0, 0, 0, 0); SMG$ERASE_DISPLAY(&status_id, 0, 0, 0, 0); SMG$CHANGE_VIEWPORT(&disp1_id,&x,&i1,&y,&colls); SMG$SET_CURSOR_ABS(&disp1_id,&x,&i1); } /* Catch the CLI errors do avoid disrupting the SMG screen... */ #if 0 VAXC$ESTABLISH(prim_hand); #endif status = CLI$DCL_PARSE(&input_line,&dfu_tables,0 /* not yet lib$get_input*/,0,&prompt); // check added & before dfu_tables #if 0 VAXC$ESTABLISH(NULL); #endif if (status == CLI$_NOCOMD) singlemsg(0,status); if ((status & 1 ) != 1) goto endfor; else /* Now dispatch if no errors */ { reset_ctrl(); CLI$DISPATCH(prvmask); clean_ctrlc(); cip = 0; status = brdcst_ast(); if (smg$enable) SMG$SET_CURSOR_MODE(&paste_id, &cursor_on); } endfor: if (ret_len !=0) { /* Single command processing , so exit here */ status += 0x10000000; /* Do not echo the error on DCL level */ if (smg$enable) { if (colls != orig_colls) toggle_width(); SMG$SET_CURSOR_ABS(&disp2_id,&i2,&i1); } exit(status); } /* Get next line */ cip = 0; #if 1 if (smg$enable) { SMG$ERASE_LINE(&disp2_id, &i1, &i1); SMG$SET_CURSOR_ABS(&disp2_id,&i1,&i1); status = SMG$READ_COMPOSED_LINE(&keyb_id,&key_tab,&input_line, &prompt,&out_len,&disp2_id,0,0,0,0,0); /*Get next command */ cip = 1; } else status = SMG$READ_COMPOSED_LINE(&keyb_id,0,&input_line, &prompt,&out_len,0,0,0,0,0,0); /*Get next command */ #else printf("%s",prompt.dsc$a_pointer); out_len = read(0,command_line,254); out_len--; command_line[out_len]=0; if (strncmp(command_line,"exit",4)==0) return 0; #endif } } /* END of MAIN */
int main() { desired_sig_t ptr{DISPATCH(&test::callback_one)}; }
* that doesn't exist. * * When a function with these semantics returns a new array, the new array is * already incref'd. In a few cases, an existing array (different than the * source array) may be returned. In this case, the array will already be * incref'd. */ const ArrayFunctions g_array_funcs = { /* * void Release(ArrayData*) * * Free memory associated with an array. Generally called when * the reference count on an array drops to zero. */ DISPATCH(Release) /* * const TypedValue* NvGetInt(const ArrayData*, int64_t key) * * Lookup a value in an array using an integer key. Returns * nullptr if the key is not in the array. */ DISPATCH(NvGetInt) /* * const TypedValue* NvGetStr(const ArrayData*, const StringData*) * * Lookup a value in an array using a string key. The string key * must not be an integer-like string. Returns nullptr if the key * is not in the array.