EVAL_INLINE void fstack_enter_frame(enum frame_type_t ft) { CURRENT_TIB()->count_enter_frame++; fstack_push((lref_t)(CURRENT_TIB()->frame)); CURRENT_TIB()->frame = CURRENT_TIB()->fsp; fstack_push((lref_t)ft); }
int f_mngRestoreFactoryDone(unsigned *pMsg) { func_t func; switch(((msg_t *)pMsg)->msgType) { case CACT_OVER: break; case CMSG_INIT: //DISP_menu_MNGSYS_line2nd_RestoreDoing(); DISP_menu_MNGSYS_line3rd_succ(5); vp_stor(CVOPID_RESTORE); vp_stor(CVOPID_SUCESS); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); break; case CMSG_TMR: if(g_tick++ >= 10) { g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); fstack_init(&g_fstack); func.func = f_idle; fstack_push(&g_fstack, &func); } break; case CPMT_OVER: promptInit(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); fstack_init(&g_fstack); func.func = f_idle; fstack_push(&g_fstack, &func); break; default: /** 可能的错误 **/ break; } return 0; }
EVAL_INLINE lref_t subr_apply(lref_t function, size_t argc, lref_t argv[], lref_t * env, lref_t * retval) { lref_t arg1; lref_t args; size_t ii; UNREFERENCED(env); fstack_enter_frame(FRAME_SUBR); fstack_push((lref_t)function); switch (SUBR_TYPE(function)) { case SUBR_0: *retval = (SUBR_F0(function) ()); break; case SUBR_1: *retval = (SUBR_F1(function) (_ARGV(0))); break; case SUBR_2: *retval = (SUBR_F2(function) (_ARGV(0), _ARGV(1))); break; case SUBR_3: *retval = (SUBR_F3(function) (_ARGV(0), _ARGV(1), _ARGV(2))); break; case SUBR_4: *retval = (SUBR_F4(function) (_ARGV(0), _ARGV(1), _ARGV(2), _ARGV(3))); break; case SUBR_2N: arg1 = _ARGV(0); arg1 = SUBR_F2(function) (arg1, _ARGV(1)); for (ii = 2; ii < argc; ii++) arg1 = SUBR_F2(function) (arg1, _ARGV(ii)); *retval = arg1; break; case SUBR_ARGC: *retval = (SUBR_FARGC(function) (argc, argv)); break; case SUBR_N: args = arg_list_from_buffer(argc, argv); *retval = (SUBR_F1(function) (args)); break; } fstack_leave_frame(); return NIL; }
/******************************************************************************* * Description: 开锁操作完成后,是否要查低电压报警 * 低电报警 *******************************************************************************/ int f_LowPowerAlarm(unsigned *pMsg) { // msg_t msg; func_t func; switch(((msg_t *)pMsg)->msgType) { case CMSG_TMR: /** 低电报警提示计时 **/ g_tick++; if(g_tick >= 10) { GOTO_ALLOFF: promptInit(); fstack_init(&g_fstack); func.func = f_idle; fstack_push(&g_fstack, &func); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); //SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_INIT); All_Screen(0); DISP_idle(); /*******************************************************************/ } break; case CMSG_INIT: promptInit(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); if(g_flag & (1 << 9)){ /** 查低电报警 **/ /** 报警提示 **/ vp_stor(CVOPID_POWERLOW); promptDelay(TIMER_500MS); DISP_lowPower(); } else { goto GOTO_ALLOFF; /** 无报警动作,直接结束 **/ } break; case CPMT_OVER: /** 锁体操作过程结束 **/ promptInit(); bbbeep(); promptDelay(TIMER_500MS); break; default: break; } return 0; }
/** Initialize a request. * * This handles setting up a request for curl. It is preferable to call this * once for multiple requests to help curl reuse connections when possible. * Use the other set and reset methods to change things for multiple requests. * * @request struct request_t* the request_t to initialize * @uri struct str_t* the uri for the initial request * @header_count size_t the number of elements in headers[] * @headers struct str_t[] the headers, if any, for this request * @msg const char* a message for POST, NULL if not POST * @type enum request_type the type of the request, GET, POST, ... */ int ci_init(struct request_t* request, struct str_t* uri, size_t header_count, const struct str_t const headers[], const char const* msg, enum request_type_e type) { // TODO: Errors union func_u func; int ret = 0; memset(request, 0, sizeof(struct request_t)); fstack_init(&request->cleanup, 10); CURL* handle = curl_easy_init(); func.func1 = curl_easy_cleanup; fstack_push(&request->cleanup, handle, &func, 1); curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); curl_easy_setopt(handle, CURLOPT_USE_SSL, CURLUSESSL_ALL); // SSL curl_easy_setopt(handle, CURLOPT_HEADER, 1); // Enable headers, necessary? // set curl_post_callback for parsing the server response curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ci_callback_controller); // set curl_post_callback's last parameter to state curl_easy_setopt(handle, CURLOPT_WRITEDATA, &request->response); if(header_count) { ret = ci_create_header(request, header_count, headers); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, request->headers); // Set headers } curl_easy_setopt(handle, CURLOPT_USERAGENT, "darkcloud/0.1"); switch(type) { case GET: break; case POST: curl_easy_setopt(handle, CURLOPT_POSTFIELDS, msg); break; default: break; } request->handle = handle; ret = ci_set_uri(request, uri); return ret; }
/** Create the header for a request from an array of str_ts. * * Takes an array of str_ts and creates a header from them. * This has currently only been tested for header_count = 2. * * @request struct request_t* the request we want to set headers for. * @header_count size_t the number of headers in headers[] * @headers struct str_t[] the strings for the headers. */ int ci_create_header(struct request_t* request, size_t header_count, const struct str_t headers[]) { union func_u func; struct curl_slist *header_list = NULL; size_t count = 0; for(; count < header_count; ++count) { printf("%s\n", headers[count].str); header_list = curl_slist_append(header_list, headers[count].str); } request->headers = header_list; func.func1 = curl_slist_free_all; fstack_push(&request->cleanup, header_list, &func, 1); return 0; }
int dci_init(struct dci_state *state) { union func_u func; str_init_create(&plus, "+", 0); str_init_create(&, "&", 0); str_init_create(&que, "?", 0); str_init_create(&slash, "/", 0); struct stack_t *estack = (struct stack_t*)malloc(sizeof(struct stack_t)); if(!estack) return 1; if(fstack_init(estack, 20)) return 1; struct stack_t *gstack = (struct stack_t*)malloc(sizeof(struct stack_t)); if(!gstack) return 1; if(fstack_init(gstack, 20)) return 1; state->stack = estack; state->head = NULL; state->tail = NULL; state->callback_error = 0; state->num_files = 0; // init the socket stuff // if(curl_global_init(CURL_GLOBAL_SSL) != 0) goto init_fail; func.func2 = curl_global_cleanup; fstack_push(estack, NULL, &func, 2); state->curlmulti = curl_multi_init(); // if(state->curlmulti == NULL) // goto init_fail; // func.func3 = curl_global_cleanup; // fstack_push(estack, state->curlmulti, &func, 3); //dci_get_file_list("/", state); goto init_success; init_fail: while(estack->size) fstack_pop(estack); while(gstack->size) fstack_pop(gstack); fstack_destroy(estack); free(estack); fstack_destroy(gstack); free(gstack); return 1; init_success: while(gstack->size) fstack_pop(gstack); fstack_destroy(gstack); free(gstack); return 0; }
/******************************************************************************* * 设置时间日期 *******************************************************************************/ int f_mngDatetime(unsigned *pMsg) { #define CDATETIME_MIN 0 #define CDATETIME_MAX (MTABSIZE(boundary_datetime) - 1) func_t func; switch(((msg_t *)pMsg)->msgType) { case CMSG_INIT: g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); All_Screen(0); //OLED_cleanPages(5, 5); MDATETIME_READ("读出时间,存入到g_u8password[]中"); g_u8menuNO = CDATETIME_MIN; //数值索引 MDATETIME_COOKED(g_u8menuNO); MDATETIME_GET(g_u8menuNO, g_u8pswordSel); g_u8pswordSel = MBCD2HEX(g_u8pswordSel); DISP_GetOrSetDateTime(1); DISP_line3rd_menu_select(); //第三行 break; case CMSG_TMR: //SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); DISP_SetDateTime_Blink(g_u8menuNO, (g_tick & 0x01), MHEX2BCD(g_u8pswordSel)); g_tick++; if(g_tick > 10) { promptInit(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); fstack_pop(&g_fstack); } break; case CMSG_DKEY: /** 检测到按键按下 **/ switch(((msg_t *)pMsg)->msgValue) { case CKEY_2: ledPrompt(2, TIMER_100MS); promptInit(); beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); g_u8pswordSel = value_dec(g_u8pswordSel, boundary_datetime[g_u8menuNO][1], boundary_datetime[g_u8menuNO][0]); DISP_SetDateTime_Blink(g_u8menuNO, 0, MHEX2BCD(g_u8pswordSel)); break; case CKEY_8: ledPrompt(8, TIMER_100MS); promptInit(); beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); g_u8pswordSel = value_inc(g_u8pswordSel, boundary_datetime[g_u8menuNO][1], boundary_datetime[g_u8menuNO][0]); DISP_SetDateTime_Blink(g_u8menuNO, 0, MHEX2BCD(g_u8pswordSel)); break; case CKEY_asterisk: ledPrompt(10, TIMER_100MS); promptInit(); beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); fstack_pop(&g_fstack); break; case CKEY_pound: ledPrompt(12, TIMER_100MS); promptInit(); beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); MDATETIME_STORE(g_u8menuNO, MHEX2BCD(g_u8pswordSel)); DISP_SetDateTime_Blink(g_u8menuNO, 0, MHEX2BCD(g_u8pswordSel)); datetime_ByteWrite(boundary_datetime[g_u8menuNO][3], MHEX2BCD(g_u8pswordSel)); g_u8menuNO++; if(g_u8menuNO < CDATETIME_MAX) { MDATETIME_COOKED(g_u8menuNO); MDATETIME_GET(g_u8menuNO, g_u8pswordSel); g_u8pswordSel = MBCD2HEX(g_u8pswordSel); DISP_SetDateTime_Blink(g_u8menuNO, 0, MHEX2BCD(g_u8pswordSel)); } else { MDATETIME_WRITE("写入到芯片"); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); func.func = f_mngDatetimeDone; fstack_push(&g_fstack, &func); } break; default: /** 可能的错误 **/ break; } default: /** 可能的错误 **/ break; } return 0; #undef CDATETIME_MIN #undef CDATETIME_MAX }
/******************************************************************************* * 系统设置 *******************************************************************************/ int f_mngSystem(unsigned *pMsg) { #define CSYS_MIN 0 #define CSYS_MAX (MTABSIZE(mngSystemTab) - 1) func_t func; switch(((msg_t *)pMsg)->msgType) { case CACT_OVER: break; case CMSG_INIT: g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); g_u8menuNO = CSYS_MIN; DISP_menu_MNGSYS_line1st(); //第一行 DISP_L2_menu_sysmng(g_u8menuNO); //第二行 OLED_cleanPages(5, 5); DISP_line3rd_menu_select(); //第三行 break; case CMSG_DKEY: /** 检测到按键按下 **/ switch(((msg_t *)pMsg)->msgValue) { case CKEY_2: ledPrompt(2, TIMER_100MS); //for test only beep(); g_u8menuNO = value_dec(g_u8menuNO, CSYS_MAX, CSYS_MIN); DISP_L2_menu_sysmng(g_u8menuNO); //第二行 break; case CKEY_8: ledPrompt(8, TIMER_100MS); //for test only beep(); g_u8menuNO = value_inc(g_u8menuNO, CSYS_MAX, CSYS_MIN); DISP_L2_menu_sysmng(g_u8menuNO); //第二行 break; case CKEY_asterisk: ledPrompt(10, TIMER_100MS); //for test only beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_BACK); //SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); fstack_pop(&g_fstack); break; case CKEY_pound: ledPrompt(10, TIMER_100MS); //for test only beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_INIT); func.func = mngSystemTab[g_u8menuNO]; fstack_push(&g_fstack, &func); break; default: /** 可能的错误 **/ break; } default: /** 可能的错误 **/ break; } return 0; #undef CSYS_MIN #undef CSYS_MAX }
/******************************************************************************* * 开锁方式 *******************************************************************************/ int f_mngOpenMode(unsigned *pMsg) { #define COPENMODE_MIN 0 #define COPENMODE_MAX 2 func_t func; switch(((msg_t *)pMsg)->msgType) { case CMSG_INIT: g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); g_u8menuNO = COPENMODE_MIN; All_Screen(0); DISP_menu_MNGSYS_line1st_OpenMode(); //第一行 DISP_L2_menu_OpenModemng(g_u8menuNO); //第二行 OLED_cleanPages(5, 5); DISP_line3rd_menu_select(); //第三行 break; case CMSG_DKEY: /** 检测到按键按下 **/ switch(((msg_t *)pMsg)->msgValue) { case CKEY_2: ledPrompt(2, TIMER_100MS); promptInit(); beep(); g_u8menuNO = value_dec(g_u8menuNO, COPENMODE_MAX, COPENMODE_MIN); DISP_L2_menu_OpenModemng(g_u8menuNO); break; case CKEY_8: ledPrompt(8, TIMER_100MS); promptInit(); beep(); g_u8menuNO = value_inc(g_u8menuNO, COPENMODE_MAX, COPENMODE_MIN); DISP_L2_menu_OpenModemng(g_u8menuNO); break; case CKEY_asterisk: ledPrompt(10, TIMER_100MS); promptInit(); beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); fstack_pop(&g_fstack); break; case CKEY_pound: ledPrompt(12, TIMER_100MS); promptInit(); beep(); OpenMode_setValue(g_u8menuNO); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); func.func = f_mngOpenModeDone; fstack_push(&g_fstack, &func); break; default: /** 可能的错误 **/ break; } default: /** 可能的错误 **/ break; } return 0; #undef COPENMODE_MIN #undef COPENMODE_MAX }
/******************************************************************************* * 恢复出厂值 *******************************************************************************/ int f_mngRestoreFactory(unsigned *pMsg) { func_t func; switch(((msg_t *)pMsg)->msgType) { case CMSG_INIT: OLED_cleanPages(0, 1); //第1行 DISP_menu_MNGSYS_line2nd_RestoreConfirm(); //恢复出厂? DISP_line3rd_menu_confirm(6); /** (否(*) 是(#) ) **/ g_u8pswordNO = 0; break; case CPMT_OVER: promptInit(); break; case CFIGER_INIT: g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_300MS, CFIGER_INIT); FP_INIT(); break; case CMSG_FGINIT: //完成指纹传感器初始化. 可以进行删除了 g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_3SEC, CMSG_FGINIT); g_u8pswordNO = 0; //MFP_DelAll(); //删除全部指纹 FP_DelAll(); //删除全部指纹 break; case CMSG_FGOPFAIL: /** 如果清除全部指纹失败,意味着什么? 该怎么办? **/ break; case CMSG_FGDERG: //完成指纹模板删除 promptInit(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_100MS, CMSG_INIT); MFPOWER_OFF(); //指纹传感器断电 func.func = f_mngRestoreFactoryDone; fstack_push(&g_fstack, &func); break; case CMSG_DKEY: /** 检测到按键按下 **/ switch(((msg_t *)pMsg)->msgValue) { case CKEY_asterisk: ledPrompt(10, TIMER_100MS); promptInit(); beep(); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_INIT); fstack_pop(&g_fstack); break; case CKEY_pound: ledPrompt(12, TIMER_100MS); promptInit(); beep(); g_u8pswordNO++; if(g_u8pswordNO == 1) { //第n次按下#号 DISP_menu_MNGSYS_line2nd_RestoreDoing(); //恢复出厂 //DISP_menu_MNGSYS_line3rd_RestoreDoing(6); OLED_cleanPages(5, 5); DISP_menu_MNGSYS_line3rd_Waiting(6); //请稍等 MFPOWER_ON(); //指纹传感器供电 psword_delAll(); //全部密码 bluetoothEntry_delAll(); //全部蓝牙设备 fingerTab_clean(); //指纹索引表 record_clean(); //开锁记录 g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_300MS, CFIGER_INIT); } break; default: /** 可能的错误 **/ break; } default: /** 可能的错误 **/ break; } return 0; }
int main() { int i; msg_t msg; func_t func; /** 外设初始化开始 **/ Peripheral_Init(); /** 外设初始化结束 **/ charQueueInit(&g_com1TxQue); //charQueueInit(&g_com2TxQue); MFPACK_FIFO_CLEAN("清空指纹传感器缓冲区"); MBTACK_FIFO_CLEAN("清空蓝牙接收缓冲区"); actionQueueInit(&g_actionQueue, &(g_timer[1]), CACT_TOUT, CACT_OVER); actionQueueInit(&g_promptQueue, &(g_timer[2]), CPMT_TOUT, CPMT_OVER); actionQueueInit(&g_blinkQueue, &(g_timer[3]), CBLK_TOUT, CBLK_OVER); adcSample_Init(&g_adcData, &(g_timer[4]), CADC_TOUT, TIMER_300MS); for(i = 0; i < TIMER_NUM; i++) { ClrTimer(&g_timer[i]); } //SetTimer(&g_timer[0], TIMER_1SEC, CMSG_TMR); msgq_init(&g_msgq); #if 1 msg.msgType = CMSG_PWON; msgq_in(&g_msgq, &msg); fstack_init(&g_fstack); func.func = f_idle; fstack_push(&g_fstack, &func); #endif AWU_Config(); //enableInterrupts(); IRQ_enable(); //MIRQ_disable(); /* Infinite loop */ while(1) { //IWDG_ReloadCounter(); //Refresh_WWDG_Window(); //Test_WWDGReset(); keyscan(); //vop_busy(); //fingerCheck(); PeripheralInput_Check(); DAEMON_USART1_Send(&g_com1TxQue); /** output to fingerprint **/ DAEMON_USART3_Send(&g_com3TxQue); /** output to bluetooth **/ //DAEMON_USART1_Recive(&g_comRevBuf); actionDoing(&g_actionQueue); actionDoing(&g_promptQueue); actionDoing(&g_blinkQueue); if(msgq_out_irq(&g_msgq, &msg) == FALSE) { /** 有消息吗? **/ continue; } if(sysProcess(&msg) == TRUE) { /** 是系统消息吗? **/ continue; } if(fstack_top(&g_fstack, &func) == FALSE) { /** 当前处于工作状态吗? **/ /** something wrong happend, Power Down or recover it **/ fstack_init(&g_fstack); func.func = f_idle; fstack_push(&g_fstack, &func); g_tick = 0; SetTimer_irq(&g_timer[0], TIMER_1SEC, CMSG_TMR); continue; } func.func((unsigned *)&msg); } }
static lref_t execute_fast_op(lref_t fop, lref_t env) { lref_t retval = NIL; lref_t sym; lref_t binding; lref_t fn; lref_t args; size_t argc; lref_t argv[ARG_BUF_LEN]; lref_t after; lref_t tag; lref_t cell; lref_t escape_retval; lref_t *jmpbuf_ptr; jmp_buf *jmpbuf; STACK_CHECK(&fop); fstack_enter_frame(FRAME_EVAL); fstack_push((lref_t)&fop); fstack_push((lref_t)fop); fstack_push((lref_t)env); while(!NULLP(fop)) { CURRENT_TIB()->count_fop++; _process_interrupts(); #if defined(WITH_FOPLOG_SUPPORT) if (CURRENT_TIB()->foplog_enable) { CURRENT_TIB()->foplog[CURRENT_TIB()->foplog_index] = fop; CURRENT_TIB()->foplog_index = (CURRENT_TIB()->foplog_index + 1) % FOPLOG_SIZE; } #endif switch(fop->header.opcode) { case FOP_LITERAL: retval = fop->as.fast_op.arg1; fop = fop->as.fast_op.next; break; case FOP_GLOBAL_REF: sym = fop->as.fast_op.arg1; binding = SYMBOL_VCELL(sym); if (UNBOUND_MARKER_P(binding)) vmerror_unbound(sym); retval = binding; fop = fop->as.fast_op.next; break; case FOP_GLOBAL_SET: sym = fop->as.fast_op.arg1; binding = SYMBOL_VCELL(sym); if (UNBOUND_MARKER_P(binding)) vmerror_unbound(sym); SET_SYMBOL_VCELL(sym, retval); fop = fop->as.fast_op.next; break; case FOP_LOCAL_REF: sym = fop->as.fast_op.arg1; binding = lenvlookup(sym, env); retval = CAR(binding); fop = fop->as.fast_op.next; break; case FOP_LOCAL_SET: sym = fop->as.fast_op.arg1; binding = lenvlookup(sym, env); SET_CAR(binding, retval); fop = fop->as.fast_op.next; break; case FOP_APPLY_GLOBAL: sym = fop->as.fast_op.arg1; fn = SYMBOL_VCELL(sym); if (UNBOUND_MARKER_P(fn)) vmerror_unbound(sym); argc = 0; args = fop->as.fast_op.arg2; while (CONSP(args)) { if (argc >= ARG_BUF_LEN) { vmerror_unsupported(_T("too many actual arguments")); break; } argv[argc] = execute_fast_op(CAR(args), env); args = CDR(args); argc++; } if (!NULLP(args)) vmerror_arg_out_of_range(fop->as.fast_op.arg2, _T("bad formal argument list")); fop = apply(fn, argc, argv, &env, &retval); break; case FOP_APPLY: argc = 0; fn = execute_fast_op(fop->as.fast_op.arg1, env); args = fop->as.fast_op.arg2; while (CONSP(args)) { if (argc >= ARG_BUF_LEN) { vmerror_unsupported(_T("too many actual arguments")); break; } argv[argc] = execute_fast_op(CAR(args), env); args = CDR(args); argc++; } if (!NULLP(args)) vmerror_arg_out_of_range(fop->as.fast_op.arg2, _T("bad formal argument list")); fop = apply(fn, argc, argv, &env, &retval); break; case FOP_IF_TRUE: if (TRUEP(retval)) fop = fop->as.fast_op.arg1; else fop = fop->as.fast_op.arg2; break; case FOP_RETVAL: fop = fop->as.fast_op.next; break; case FOP_SEQUENCE: retval = execute_fast_op(fop->as.fast_op.arg1, env); fop = fop->as.fast_op.arg2; break; case FOP_THROW: tag = execute_fast_op(fop->as.fast_op.arg1, env); escape_retval = execute_fast_op(fop->as.fast_op.arg2, env); dscwritef(DF_SHOW_THROWS, (_T("; DEBUG: throw ~a :~a\n"), tag, escape_retval)); CURRENT_TIB()->escape_frame = find_matching_escape(CURRENT_TIB()->frame, tag); CURRENT_TIB()->escape_value = escape_retval; if (CURRENT_TIB()->escape_frame == NULL) { /* If we don't find a matching catch for the throw, we have a * problem and need to invoke a trap. */ vmtrap(TRAP_UNCAUGHT_THROW, (enum vmt_options_t)(VMT_MANDATORY_TRAP | VMT_HANDLER_MUST_ESCAPE), 2, tag, escape_retval); } unwind_stack_for_throw(); fop = fop->as.fast_op.next; break; case FOP_CATCH: tag = execute_fast_op(fop->as.fast_op.arg1, env); fstack_enter_frame(FRAME_ESCAPE); fstack_push((lref_t)tag); fstack_push((lref_t)CURRENT_TIB()->frame); fstack_push(NIL); jmpbuf_ptr = CURRENT_TIB()->fsp; jmpbuf = (jmp_buf *)fstack_alloca(sizeof(jmp_buf)); *(jmpbuf_ptr) = (lref_t)jmpbuf; if (setjmp(*jmpbuf) == 0) { retval = execute_fast_op(fop->as.fast_op.arg2, env); } else { dscwritef(DF_SHOW_THROWS, (_T("; DEBUG: catch retval =~a\n"), CURRENT_TIB()->escape_value)); retval = CURRENT_TIB()->escape_value; CURRENT_TIB()->escape_value = NIL; } fstack_leave_frame(); fop = fop->as.fast_op.next; break; case FOP_WITH_UNWIND_FN: fstack_enter_frame(FRAME_UNWIND); fstack_push((lref_t)execute_fast_op(fop->as.fast_op.arg1, env)); retval = execute_fast_op(fop->as.fast_op.arg2, env); after = CURRENT_TIB()->frame[FOFS_UNWIND_AFTER]; fstack_leave_frame(); apply1(after, 0, NULL); fop = fop->as.fast_op.next; break; case FOP_CLOSURE: retval = lclosurecons(env, lcons(lcar(fop->as.fast_op.arg1), fop->as.fast_op.arg2), lcdr(fop->as.fast_op.arg1)); fop = fop->as.fast_op.next; break; case FOP_CAR: retval = lcar(retval); fop = fop->as.fast_op.next; break; case FOP_CDR: retval = lcdr(retval); fop = fop->as.fast_op.next; break; case FOP_NOT: retval = boolcons(!TRUEP(retval)); fop = fop->as.fast_op.next; break; case FOP_NULLP: retval = boolcons(NULLP(retval)); fop = fop->as.fast_op.next; break; case FOP_EQP: retval = boolcons(EQ(execute_fast_op(fop->as.fast_op.arg1, env), execute_fast_op(fop->as.fast_op.arg2, env))); fop = fop->as.fast_op.next; break; case FOP_GET_ENV: retval = env; fop = fop->as.fast_op.next; break; case FOP_GLOBAL_DEF: // three args, third was genv, but currently unused retval = lidefine_global(fop->as.fast_op.arg1, fop->as.fast_op.arg2); fop = fop->as.fast_op.next; break; case FOP_GET_FSP: retval = fixcons((fixnum_t)CURRENT_TIB()->fsp); fop = fop->as.fast_op.next; break; case FOP_GET_FRAME: retval = fixcons((fixnum_t)CURRENT_TIB()->frame); fop = fop->as.fast_op.next; break; case FOP_GET_HFRAMES: retval = CURRENT_TIB()->handler_frames; fop = fop->as.fast_op.next; break; case FOP_SET_HFRAMES: CURRENT_TIB()->handler_frames = execute_fast_op(fop->as.fast_op.arg1, env); fop = fop->as.fast_op.next; break; case FOP_GLOBAL_PRESERVE_FRAME: sym = fop->as.fast_op.arg1; binding = SYMBOL_VCELL(sym); if (UNBOUND_MARKER_P(binding)) vmerror_unbound(sym); SET_SYMBOL_VCELL(sym, fixcons((fixnum_t)CURRENT_TIB()->frame)); retval = execute_fast_op(fop->as.fast_op.arg2, env); fop = fop->as.fast_op.next; break; case FOP_STACK_BOUNDARY: sym = execute_fast_op(fop->as.fast_op.arg1, env); fstack_enter_frame(FRAME_STACK_BOUNDARY); fstack_push((lref_t)sym); retval = execute_fast_op(fop->as.fast_op.arg2, env); fstack_leave_frame(); fop = fop->as.fast_op.next; break; case FOP_FAST_ENQUEUE_CELL: retval = execute_fast_op(fop->as.fast_op.arg2, env); cell = execute_fast_op(fop->as.fast_op.arg1, env); SET_CDR(CAR(retval), cell); SET_CAR(retval, cell); fop = fop->as.fast_op.next; break; case FOP_WHILE_TRUE: while(TRUEP(execute_fast_op(fop->as.fast_op.arg1, env))) { retval = execute_fast_op(fop->as.fast_op.arg2, env); } fop = fop->as.fast_op.next; break; default: panic("Unsupported fast-op"); } } fstack_leave_frame(); return retval; }