📄 exe.c
字号:
case nod_block: switch (request->req_operation) { SLONG count; SAV save_point; case req_evaluate: if (transaction != dbb->dbb_sys_trans) { VIO_start_save_point (tdbb, transaction); save_point = transaction->tra_save_point; count = save_point->sav_number; MOVE_FAST (&count, (SCHAR*) request + node->nod_impure, sizeof (SLONG)); } node = node->nod_arg [e_blk_action]; break; case req_unwind: { VOLATILE NOD handlers, *ptr, *end; if (request->req_flags & req_leave) { /** Although the req_operation is set to req_unwind it is not an error case if req_leave bit is set. req_leave bit indicates that we hit an EXIT statement in the procedure code. Do not perform the error handling stuff. **/ node = node->nod_parent; break; } if (transaction != dbb->dbb_sys_trans) { MOVE_FAST ((SCHAR*) request + node->nod_impure, &count, sizeof (SLONG)); /* Since there occurred an error (req_unwind), undo all savepoints up to, but not including, the savepoint of this block. The savepoint of this block will be dealt with below. */ for (save_point = transaction->tra_save_point; save_point && count < save_point->sav_number; save_point = transaction->tra_save_point) { ++transaction->tra_save_point->sav_verb_count; VERB_CLEANUP; } } if (handlers = node->nod_arg [e_blk_handlers]) { ULONG prev_req_error_handler; node = node->nod_parent; for (ptr = handlers->nod_arg, end = ptr + handlers->nod_count; ptr < end; ptr++) if (test_error (tdbb, (*ptr)->nod_arg [e_err_conditions])) { request->req_operation = req_evaluate; node = (*ptr)->nod_arg [e_err_action]; error_pending = FALSE; /* On entering looper old_request etc. are saved. On recursive calling we will loose the actual old request for that invocation of looper. Avoid this. */ tdbb->tdbb_default = old_pool; tdbb->tdbb_request = old_request; /* Save the previous state of req_error_handler bit. We need to restore it later. This is necessary if the error handler is deeply nested. */ prev_req_error_handler = request->req_flags & req_error_handler; request->req_flags |= req_error_handler; node = looper (tdbb, request, node); request->req_flags &= ~(req_error_handler); request->req_flags |= prev_req_error_handler; /* Note: Previously the above call "node = looper (tdbb, request, node);" never returned back till the node tree was executed completely. Now that the looper has changed its behaviour such that it returns back after handling error. This makes it necessary that the jmpbuf be reset so that looper can proceede with the preocessing of execution tree. If this is not done then anymore errors will take the engine out of looper there by abruptly terminating the processing. */ tdbb->tdbb_setjmp = (UCHAR*) env; tdbb->tdbb_default = request->req_pool; tdbb->tdbb_request = request; /* The error is dealt with by the application, cleanup this block's savepoint. */ if (transaction != dbb->dbb_sys_trans) { for (save_point = transaction->tra_save_point; save_point && count <= save_point->sav_number; save_point = transaction->tra_save_point) VERB_CLEANUP; } } } else node = node->nod_parent; /* If the application didn't have an error handler, then the error will still be pending. Undo the block by using its savepoint. */ if (error_pending && transaction != dbb->dbb_sys_trans) { ++transaction->tra_save_point->sav_verb_count; VERB_CLEANUP; } } break; case req_return: if (transaction != dbb->dbb_sys_trans) { MOVE_FAST ((SCHAR*) request + node->nod_impure, &count, sizeof (SLONG)); for (save_point = transaction->tra_save_point; save_point && count <= save_point->sav_number; save_point = transaction->tra_save_point) VERB_CLEANUP; } default: node = node->nod_parent; } break; case nod_error_handler: if (request->req_flags & req_error_handler && !error_pending) { tdbb->tdbb_setjmp = (UCHAR*) old_env; return node; } node = node->nod_parent; node = node->nod_parent; if (request->req_operation == req_unwind) node = node->nod_parent; break; case nod_label: switch (request->req_operation) { case req_evaluate: node = node->nod_arg [e_lbl_statement]; break; case req_unwind: if (request->req_label == (USHORT) node->nod_arg [e_lbl_label]) { request->req_flags &= ~req_leave; request->req_operation = req_return; } default: node = node->nod_parent; } break; case nod_leave: request->req_flags |= req_leave; request->req_operation = req_unwind; request->req_label = (USHORT) node->nod_arg [0]; node = node->nod_parent; break; case nod_list: impure = (STA) ((SCHAR*) request + node->nod_impure); switch (request->req_operation) { case req_evaluate: impure->sta_state = 0; case req_return: case req_sync: if (impure->sta_state < node->nod_count) { request->req_operation = req_evaluate; node = node->nod_arg [impure->sta_state++]; break; } request->req_operation = req_return; default : node = node->nod_parent; } break; case nod_loop: switch (request->req_operation) { case req_evaluate: case req_return: node = node->nod_arg [0]; request->req_operation = req_evaluate; break; default: node = node->nod_parent; } break; case nod_if: if (request->req_operation == req_evaluate) if (EVL_boolean (tdbb, node->nod_arg [e_if_boolean])) { node = node->nod_arg [e_if_true]; break; } else if (node->nod_arg [e_if_false]) { node = node->nod_arg [e_if_false]; break; } else request->req_operation = req_return; node = node->nod_parent; break; case nod_modify: impure = (STA) ((SCHAR*) request + node->nod_impure); if ((request->req_operation == req_return) && (!impure->sta_state) && (node->nod_arg[e_mod_sub_mod])) { if (!top_node) { top_node = node; which_mod_trig = PRE_TRIG; } prev_node = node; node = modify (tdbb, node, which_mod_trig); if (which_mod_trig == PRE_TRIG) { node = prev_node->nod_arg[e_mod_sub_mod]; node->nod_parent = prev_node; } if (top_node == prev_node && which_mod_trig == POST_TRIG) { top_node = NULL; which_mod_trig = ALL_TRIGS; } else request->req_operation = req_evaluate; } else { prev_node = node; node = modify (tdbb, node, ALL_TRIGS); if (!(prev_node->nod_arg[e_mod_sub_mod]) && which_mod_trig == PRE_TRIG) which_mod_trig = POST_TRIG; } break; case nod_nop: request->req_operation = req_return; node = node->nod_parent; break; case nod_receive: node = receive_msg (tdbb, node); break; case nod_exec_sql: if (request->req_operation == req_unwind) { node = node->nod_parent; break; } exec_sql (request, tdbb, EVL_expr (tdbb, node->nod_arg [0])); if (request->req_operation == req_evaluate) request->req_operation = req_return; node = node->nod_parent; break; case nod_post: DFW_post_work (transaction, dfw_post_event, EVL_expr (tdbb, node->nod_arg [0]), 0); /* for an autocommit transaction, events can be posted * without any updates */ if (transaction->tra_flags & TRA_autocommit) transaction->tra_flags |= TRA_perform_autocommit; case nod_message: if (request->req_operation == req_evaluate) request->req_operation = req_return; node = node->nod_parent; break; case nod_stall: node = stall (tdbb, node); break; case nod_select: node = selct (tdbb, node); break; case nod_send: node = send_msg (tdbb, node); break; case nod_store: impure = (STA) ((SCHAR*) request + node->nod_impure); if ((request->req_operation == req_return) && (!impure->sta_state) && (node->nod_arg[e_sto_sub_store])) { if (!top_node) { top_node = node; which_sto_trig = PRE_TRIG; } prev_node = node; node = store (tdbb, node, which_sto_trig); if (which_sto_trig == PRE_TRIG) { node = prev_node->nod_arg[e_sto_sub_store]; node->nod_parent = prev_node; } if (top_node == prev_node && which_sto_trig == POST_TRIG) { top_node = NULL; which_sto_trig = ALL_TRIGS; } else request->req_operation = req_evaluate; } else { prev_node = node; node = store (tdbb, node, ALL_TRIGS); if (!(prev_node->nod_arg[e_sto_sub_store]) && which_sto_trig == PRE_TRIG) which_sto_trig = POST_TRIG; } break;#ifdef SCROLLABLE_CURSORS case nod_seek: node = seek_rse (tdbb, request, node); break;#endif#ifdef PC_ENGINE case nod_stream: node = stream (tdbb, node); break; case nod_find: node = find (tdbb, node); break; case nod_find_dbkey: case nod_find_dbkey_version: node = find_dbkey (tdbb, node); break; case nod_set_index: node = set_index (tdbb, node); break; case nod_set_bookmark: node = set_bookmark (tdbb, node); break; case nod_release_bookmark: node = release_bookmark (tdbb, node); break; case nod_end_range: node = RNG_end (node); break; case nod_delete_range: node = RNG_delete (node); break; case nod_delete_ranges: if (request->req_operation == req_evaluate) { RNG_delete_ranges (request); request->req_operation = req_return; } node = node->nod_parent; break; case nod_range_relation: node = RNG_add_relation (node); break; case nod_release_lock: if (request->req_operation == req_evaluate) { DSC *desc; desc = EVL_expr (tdbb, node->nod_arg [e_rellock_lock]);#if !defined(HAS_64BIT_POINTERS) RLCK_release_lock (*(LCK*) desc->dsc_address);#else { ATT attachment; LCK lock; ULONG slot; VEC vector; attachment = tdbb->tdbb_attachment; lock = NULL; slot = *(ULONG*) desc->dsc_address; if ((vector = attachment->att_lck_quick_ref) && slot < vector->vec_count) lock = (LCK) vector->vec_object [slot]; RLCK_release_lock (lock); vector->vec_object [slot] = NULL; }#endif request->req_operation = req_return; } node = node->nod_parent; break; case nod_release_locks: if (request->req_operation == req_evaluate) { RLCK_release_locks (request->req_attachment); request->req_operation = req_return; } node = node->nod_parent; break; case nod_force_crack: if (request->req_operation == req_evaluate) { RSE_MARK_CRACK (tdbb, *(RSB*) node->nod_arg [1], irsb_crack | irsb_forced_crack); request->req_operation = req_return; } node = node->nod_parent; break; case nod_reset_stream: if (request->req_operation == req_evaluate) { RSE_reset_position (tdbb, *(RSB*) node->nod_arg [e_reset_from_rsb], request->req_rpb + (USHORT) node->nod_arg [e_reset_to_stream]); request->req_operation = req_return; } node = node->nod_parent; break;#endif case nod_set_generator: if (request->req_operation == req_evaluate) { DSC *desc; desc = EVL_expr (tdbb, node->nod_arg [e_gen_value]); (void) DPM_gen_id (tdbb, (SLONG) node->nod_arg [e_gen_id], 1, MOV_get_int64 (desc, 0)); request->req_operation = req_return; } node = node->nod_parent; break; case nod_set_generator2: if (request->req_operation == req_evaluate) { DSC *desc; desc = EVL_expr (tdbb, node->nod_arg [e_gen_value]); (void) DPM_gen_id (tdbb, (SLONG) node->nod_arg [e_gen_id], 1, MOV_get_int64 (desc, 0)); request->req_operation = req_return; } node = node->nod_parent; break; default: BUGCHECK (168); /* msg 168 looper: action not yet implemented */ }#ifdef HSDEBUGSTACK TestStack ();#endif#if defined(DEBUG_GDS_ALLOC) && defined(PROD_BUILD) memory_count++; if ((memory_count % memory_debug) == 0) ALL_check_memory ();#endif }/* if there is no node, assume we have finished processing the request unless we are in the middle of processing an asynchronous message */if (!node#ifdef SCROLLABLE_CURSORS && !(request->req_flags & req_async_processing)#endif) { request->req_flags &= ~(req_active | req_reserved); request->req_timestamp = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -