compress_flc(char *name) { int x; Open_FLC (name); charcolors[0]=0; charcolors[1]=0x7fff; Get_first_frame (); Decompress_frame (); curcolor=0;bar(0,0,639,479); open_frame(); create_mgif_lzw(); reserve_track(); close_frame();write_frame_size(last_frame_size,max_colors); show_screen(); for (x=2; x<=h_flc.frames; x++) { Get_next_frame (); Decompress_frame (); open_frame(); create_mgif_delta(); reserve_track(); close_frame(); write_frame_size(last_frame_size,max_colors); if (last_frame_size>MAX_FRAME) hdiff++; else if (last_frame_size<MIN_FRAME && hranice>0) hdiff--; else if (hdiff>0) hdiff--;else if(hdiff<0) hdiff++; show_screen (); } Close_FLC(); }
VNGError VngoClear3D::flip() { if (frame_is_open) close_frame(); flush(); #ifndef RENDER_FRONT //#if 0 // rendering to primary for Bruce. if (FrontBuffer->IsLost() == DDERR_SURFACELOST) FrontBuffer->Restore(); if (BackBuffer->IsLost() == DDERR_SURFACELOST) BackBuffer->Restore(); if (Primary->IsLost() == DDERR_SURFACELOST) Primary->Restore(); if (lflags & VNGO_TRUE_FLIP) { Primary->Flip(NULL,DDFLIP_WAIT); } else { #if 1 RECT rcRect; rcRect.left = 0; rcRect.top = 0; rcRect.right = width; rcRect.bottom = height; #endif RECT srcRect; srcRect.left = startx + damage_rect.left; srcRect.top = starty + damage_rect.top; srcRect.right = startx + damage_rect.right; srcRect.bottom = starty + damage_rect.bottom; while (1) { HRESULT ddrval = Primary->Blt(&rcRect, BackBuffer, // &damage_rect, &rcRect, 0, NULL); if (ddrval == DD_OK) { break; } if (ddrval != DDERR_WASSTILLDRAWING) { return VNGO_INTERNAL_ERROR; } } } #endif return VngoScreenManager::flip(); }
compress_pcx(char *name) { int x=0; get_palette_ptr=flc_paleta; curcolor=0;bar(0,0,639,479); //prepare_for_mjpg(); while (get_pcx_frame(name,x)) { open_frame(); if (x) create_mgif_delta();else create_mgif_lzw(); reserve_track(); //create_jpg_frame(); close_frame(); curcolor=0;bar(0,400,639,430); write_frame_name(name,x); write_frame_size(last_frame_size,max_colors); if (last_frame_size>MAX_FRAME) {difdif=difdif<=0?1:difdif+1;hdiff+=difdif;} else if (last_frame_size<MIN_FRAME && hranice>0) {difdif=difdif>=0?-1:difdif-1;hdiff+=difdif;} else if (hdiff>0) {difdif=difdif>=0?-1:difdif-1;hdiff+=difdif;}else if(hdiff<0) hdiff=0; show_screen (); if (statpic) statpic--;else x+=frame_step; global_frame_counter++; } }
// Transfers the arguments from the top of the previous piece (which the frame // points to) to the bottom of the new stack segment. static void transfer_top_arguments(value_t new_piece, frame_t *frame, size_t arg_count) { frame_t new_frame = frame_empty(); open_stack_piece(new_piece, &new_frame); for (size_t i = 0; i < arg_count; i++) { value_t value = frame_peek_value(frame, arg_count - i - 1); frame_push_value(&new_frame, value); } close_frame(&new_frame); }
void prereserve_tracks() { int size; int celk; size=SOUND_SPEED/speed; size&=~1; celk=PRE_SOUND; while (celk-size>0) { open_frame(); create_sound_track(size); close_frame(); celk-=size; } if (celk) { open_frame(); create_sound_track(celk); close_frame(); } }
void convert_image(char *in,char *out) { IMAGE2D src,dst; int npix[2]; double start[2],step[2]; if (open_frame(&src,in,"I")<0) { print_error("Cannot open input file %s",in); exit_session(ERR_OPEN); } else { npix[0]=src.nx; npix[1]=src.ny; start[0]=src.startx; start[1]=src.starty; step[0]=src.stepx; step[1]=src.stepy; if (create_frame(&dst,out,npix,start,step,src.data_type,src.ident,src.cunit)<0) { close_frame(&src); print_error("Cannot create output file %s",out); exit_session(ERR_CREAT); } else { int i,j; for (i=0;i<src.nx;i++) for (j=0;j<src.ny;j++) WR_frame(&dst,i,j,RD_frame(&src,i,j)); CP_non_std_desc(&src,&dst); close_frame(&dst); close_frame(&src); } } printf("\n"); }
static void push_stack_piece_bottom_frame(runtime_t *runtime, value_t stack_piece, value_t arg_map) { frame_t bottom = frame_empty(); value_t code_block = ROOT(runtime, stack_piece_bottom_code_block); // The transferred arguments are going to appear as if they were arguments // passed from this frame so we have to "allocate" enough room for them on // the stack. open_stack_piece(stack_piece, &bottom); size_t arg_count = get_array_length(arg_map); bool pushed = try_push_new_frame(&bottom, get_code_block_high_water_mark(code_block) + arg_count, ffSynthetic | ffStackPieceBottom, false); CHECK_TRUE("pushing bottom frame", pushed); frame_set_code_block(&bottom, code_block); frame_set_argument_map(&bottom, arg_map); close_frame(&bottom); }
value_t push_stack_frame(runtime_t *runtime, value_t stack, frame_t *frame, size_t frame_capacity, value_t arg_map) { CHECK_FAMILY(ofStack, stack); value_t top_piece = get_stack_top_piece(stack); CHECK_FALSE("stack piece closed", is_stack_piece_closed(top_piece)); if (!try_push_new_frame(frame, frame_capacity, ffOrganic, false)) { // There wasn't room to push this frame onto the top stack piece so // allocate a new top piece that definitely has room. size_t default_capacity = get_stack_default_piece_capacity(stack); size_t transfer_arg_count = get_array_length(arg_map); size_t required_capacity = frame_capacity // the new frame's locals + kFrameHeaderSize // the new frame's header + 1 // the synthetic bottom frame's one local + kFrameHeaderSize // the synthetic bottom frame's header + transfer_arg_count; // any arguments to be copied onto the piece size_t new_capacity = max_size(default_capacity, required_capacity); // Create and initialize the new stack segment. The frame struct is still // pointing to the old frame. TRY_DEF(new_piece, new_heap_stack_piece(runtime, new_capacity, top_piece, stack)); push_stack_piece_bottom_frame(runtime, new_piece, arg_map); transfer_top_arguments(new_piece, frame, transfer_arg_count); set_stack_top_piece(stack, new_piece); // Close the previous stack piece, recording the frame state. close_frame(frame); // Finally, create a new frame on the new stack which includes updating the // struct. The required_capacity calculation ensures that this call will // succeed. open_stack_piece(new_piece, frame); bool pushed_stack_piece = try_push_new_frame(frame, frame_capacity, ffOrganic, false); if (!pushed_stack_piece) try_push_new_frame(frame, frame_capacity, ffOrganic, false); CHECK_TRUE("pushing on new piece failed", pushed_stack_piece); } frame_set_argument_map(frame, arg_map); return success(); }
value_t run_code_block(safe_value_t s_ambience, safe_value_t code) { runtime_t *runtime = get_ambience_runtime(deref(s_ambience)); CREATE_SAFE_VALUE_POOL(runtime, 4, pool); E_BEGIN_TRY_FINALLY(); // Build a stack to run the code on. E_S_TRY_DEF(s_stack, protect(pool, new_heap_stack(runtime, 1024))); { frame_t frame = open_stack(deref(s_stack)); // Set up the initial frame. size_t frame_size = get_code_block_high_water_mark(deref(code)); E_TRY(push_stack_frame(runtime, deref(s_stack), &frame, frame_size, ROOT(runtime, empty_array))); frame_set_code_block(&frame, deref(code)); close_frame(&frame); } // Run until completion. E_RETURN(run_stack_until_signal(s_ambience, s_stack)); E_FINALLY(); DISPOSE_SAFE_VALUE_POOL(pool); E_END_TRY_FINALLY(); }
value_t run_code_block_until_condition(value_t ambience, value_t code) { // Create the stack to run the code on. runtime_t *runtime = get_ambience_runtime(ambience); TRY_DEF(stack, new_heap_stack(runtime, 1024)); // Push an activation onto the empty stack to get execution going. size_t frame_size = get_code_block_high_water_mark(code); frame_t frame = open_stack(stack); TRY(push_stack_frame(runtime, stack, &frame, frame_size, ROOT(runtime, empty_array))); frame_set_code_block(&frame, code); close_frame(&frame); // Run the stack. loop: do { value_t result = run_stack_until_condition(ambience, stack); if (in_condition_cause(ccForceValidate, result)) { runtime_t *runtime = get_ambience_runtime(ambience); runtime_validate(runtime, result); goto loop; } return result; } while (false); }
// Runs the given stack within the given ambience until a condition is // encountered or evaluation completes. This function also bails on and leaves // it to the surrounding code to report error messages. static value_t run_stack_pushing_signals(value_t ambience, value_t stack) { CHECK_FAMILY(ofAmbience, ambience); CHECK_FAMILY(ofStack, stack); runtime_t *runtime = get_ambience_runtime(ambience); frame_t frame = open_stack(stack); code_cache_t cache; code_cache_refresh(&cache, &frame); E_BEGIN_TRY_FINALLY(); while (true) { opcode_t opcode = (opcode_t) read_short(&cache, &frame, 0); TOPIC_INFO(Interpreter, "Opcode: %s (%i)", get_opcode_name(opcode), opcode_counter++); IF_EXPENSIVE_CHECKS_ENABLED(MAYBE_INTERRUPT()); switch (opcode) { case ocPush: { value_t value = read_value(&cache, &frame, 1); frame_push_value(&frame, value); frame.pc += kPushOperationSize; break; } case ocPop: { size_t count = read_short(&cache, &frame, 1); for (size_t i = 0; i < count; i++) frame_pop_value(&frame); frame.pc += kPopOperationSize; break; } case ocCheckStackHeight: { size_t expected = read_short(&cache, &frame, 1); size_t height = frame.stack_pointer - frame.frame_pointer; CHECK_EQ("stack height", expected, height); frame.pc += kCheckStackHeightOperationSize; break; } case ocNewArray: { size_t length = read_short(&cache, &frame, 1); E_TRY_DEF(array, new_heap_array(runtime, length)); for (size_t i = 0; i < length; i++) { value_t element = frame_pop_value(&frame); set_array_at(array, length - i - 1, element); } frame_push_value(&frame, array); frame.pc += kNewArrayOperationSize; break; } case ocInvoke: { // Look up the method in the method space. value_t tags = read_value(&cache, &frame, 1); CHECK_FAMILY(ofCallTags, tags); value_t fragment = read_value(&cache, &frame, 2); CHECK_FAMILY(ofModuleFragment, fragment); value_t helper = read_value(&cache, &frame, 3); CHECK_FAMILY(ofSignatureMap, helper); value_t arg_map; value_t method = lookup_method_full(ambience, fragment, tags, &frame, helper, &arg_map); if (in_condition_cause(ccLookupError, method)) { log_lookup_error(method, tags, &frame); E_RETURN(method); } // The lookup may have failed with a different condition. Check for that. E_TRY(method); E_TRY_DEF(code_block, ensure_method_code(runtime, method)); // We should now have done everything that can fail so we advance the // pc over this instruction. In reality we haven't, the frame push op // below can fail so we should really push the next frame before // storing the pc for this one. Laters. frame.pc += kInvokeOperationSize; // Push a new activation. E_TRY(push_stack_frame(runtime, stack, &frame, get_code_block_high_water_mark(code_block), arg_map)); frame_set_code_block(&frame, code_block); code_cache_refresh(&cache, &frame); break; } case ocSignalContinue: case ocSignalEscape: { // Look up the method in the method space. value_t tags = read_value(&cache, &frame, 1); CHECK_FAMILY(ofCallTags, tags); frame.pc += kSignalEscapeOperationSize; value_t arg_map = whatever(); value_t handler = whatever(); value_t method = lookup_signal_handler_method(ambience, tags, &frame, &handler, &arg_map); bool is_escape = (opcode == ocSignalEscape); if (in_condition_cause(ccLookupError, method)) { if (is_escape) { // There was no handler for this so we have to escape out of the // interpreter altogether. Push the signal frame onto the stack to // record the state of it for the enclosing code. E_TRY(push_stack_frame(runtime, stack, &frame, 1, nothing())); // The stack tracing code expects all frames to have a valid code block // object. The rest makes less of a difference. frame_set_code_block(&frame, ROOT(runtime, empty_code_block)); E_RETURN(new_signal_condition(is_escape)); } else { // There was no handler but this is not an escape so we skip over // the post-handler goto to the default block. CHECK_EQ("signal not followed by goto", ocGoto, read_short(&cache, &frame, 0)); frame.pc += kGotoOperationSize; } } else { // We found a method. Invoke it. E_TRY(method); E_TRY_DEF(code_block, ensure_method_code(runtime, method)); E_TRY(push_stack_frame(runtime, stack, &frame, get_code_block_high_water_mark(code_block), arg_map)); frame_set_code_block(&frame, code_block); CHECK_TRUE("subject not null", is_null(frame_get_argument(&frame, 0))); frame_set_argument(&frame, 0, handler); code_cache_refresh(&cache, &frame); } break; } case ocGoto: { size_t delta = read_short(&cache, &frame, 1); frame.pc += delta; break; } case ocDelegateToLambda: case ocDelegateToBlock: { // This op only appears in the lambda and block delegator methods. // They should never be executed because the delegation happens during // method lookup. If we hit here something's likely wrong with the // lookup process. UNREACHABLE("delegate to lambda"); return new_condition(ccWat); } case ocBuiltin: { value_t wrapper = read_value(&cache, &frame, 1); builtin_method_t impl = (builtin_method_t) get_void_p_value(wrapper); builtin_arguments_t args; builtin_arguments_init(&args, runtime, &frame); E_TRY_DEF(result, impl(&args)); frame_push_value(&frame, result); frame.pc += kBuiltinOperationSize; break; } case ocBuiltinMaybeEscape: { value_t wrapper = read_value(&cache, &frame, 1); builtin_method_t impl = (builtin_method_t) get_void_p_value(wrapper); builtin_arguments_t args; builtin_arguments_init(&args, runtime, &frame); value_t result = impl(&args); if (in_condition_cause(ccSignal, result)) { // The builtin failed. Find the appropriate signal handler and call // it. The invocation record is at the top of the stack. value_t tags = frame_pop_value(&frame); CHECK_FAMILY(ofCallTags, tags); value_t arg_map = whatever(); value_t handler = whatever(); value_t method = lookup_signal_handler_method(ambience, tags, &frame, &handler, &arg_map); if (in_condition_cause(ccLookupError, method)) { // Push the record back onto the stack to it's available to back // tracing. frame_push_value(&frame, tags); frame.pc += kBuiltinMaybeEscapeOperationSize; // There was no handler for this so we have to escape out of the // interpreter altogether. Push the signal frame onto the stack to // record the state of it for the enclosing code. E_TRY(push_stack_frame(runtime, stack, &frame, 1, nothing())); // The stack tracing code expects all frames to have a valid code block // object. The rest makes less of a difference. frame_set_code_block(&frame, ROOT(runtime, empty_code_block)); E_RETURN(new_signal_condition(true)); } // Either found a signal or encountered a different condition. E_TRY(method); // Skip forward to the point we want the signal to return to, the // leave-or-fire-barrier op that will do the leaving. size_t dest_offset = read_short(&cache, &frame, 2); frame.pc += dest_offset; // Run the handler. E_TRY_DEF(code_block, ensure_method_code(runtime, method)); E_TRY(push_stack_frame(runtime, stack, &frame, get_code_block_high_water_mark(code_block), arg_map)); frame_set_code_block(&frame, code_block); CHECK_TRUE("subject not null", is_null(frame_get_argument(&frame, 0))); frame_set_argument(&frame, 0, handler); code_cache_refresh(&cache, &frame); } else { // The builtin didn't cause a condition so we can just keep going. E_TRY(result); frame_push_value(&frame, result); frame.pc += kBuiltinMaybeEscapeOperationSize; } break; } case ocReturn: { value_t result = frame_pop_value(&frame); frame_pop_within_stack_piece(&frame); code_cache_refresh(&cache, &frame); frame_push_value(&frame, result); break; } case ocStackBottom: { value_t result = frame_pop_value(&frame); validate_stack_on_normal_exit(&frame); E_RETURN(result); } case ocStackPieceBottom: { value_t top_piece = frame.stack_piece; value_t result = frame_pop_value(&frame); value_t next_piece = get_stack_piece_previous(top_piece); set_stack_top_piece(stack, next_piece); frame = open_stack(stack); code_cache_refresh(&cache, &frame); frame_push_value(&frame, result); break; } case ocSlap: { value_t value = frame_pop_value(&frame); size_t argc = read_short(&cache, &frame, 1); for (size_t i = 0; i < argc; i++) frame_pop_value(&frame); frame_push_value(&frame, value); frame.pc += kSlapOperationSize; break; } case ocNewReference: { // Create the reference first so that if it fails we haven't clobbered // the stack yet. E_TRY_DEF(ref, new_heap_reference(runtime, nothing())); value_t value = frame_pop_value(&frame); set_reference_value(ref, value); frame_push_value(&frame, ref); frame.pc += kNewReferenceOperationSize; break; } case ocSetReference: { value_t ref = frame_pop_value(&frame); CHECK_FAMILY(ofReference, ref); value_t value = frame_peek_value(&frame, 0); set_reference_value(ref, value); frame.pc += kSetReferenceOperationSize; break; } case ocGetReference: { value_t ref = frame_pop_value(&frame); CHECK_FAMILY(ofReference, ref); value_t value = get_reference_value(ref); frame_push_value(&frame, value); frame.pc += kGetReferenceOperationSize; break; } case ocLoadLocal: { size_t index = read_short(&cache, &frame, 1); value_t value = frame_get_local(&frame, index); frame_push_value(&frame, value); frame.pc += kLoadLocalOperationSize; break; } case ocLoadGlobal: { value_t ident = read_value(&cache, &frame, 1); CHECK_FAMILY(ofIdentifier, ident); value_t fragment = read_value(&cache, &frame, 2); CHECK_FAMILY(ofModuleFragment, fragment); value_t module = get_module_fragment_module(fragment); E_TRY_DEF(value, module_lookup_identifier(runtime, module, get_identifier_stage(ident), get_identifier_path(ident))); frame_push_value(&frame, value); frame.pc += kLoadGlobalOperationSize; break; } case ocLoadArgument: { size_t param_index = read_short(&cache, &frame, 1); value_t value = frame_get_argument(&frame, param_index); frame_push_value(&frame, value); frame.pc += kLoadArgumentOperationSize; break; } case ocLoadRefractedArgument: { size_t param_index = read_short(&cache, &frame, 1); size_t block_depth = read_short(&cache, &frame, 2); value_t subject = frame_get_argument(&frame, 0); frame_t home = frame_empty(); get_refractor_refracted_frame(subject, block_depth, &home); value_t value = frame_get_argument(&home, param_index); frame_push_value(&frame, value); frame.pc += kLoadRefractedArgumentOperationSize; break; } case ocLoadRefractedLocal: { size_t index = read_short(&cache, &frame, 1); size_t block_depth = read_short(&cache, &frame, 2); value_t subject = frame_get_argument(&frame, 0); frame_t home = frame_empty(); get_refractor_refracted_frame(subject, block_depth, &home); value_t value = frame_get_local(&home, index); frame_push_value(&frame, value); frame.pc += kLoadRefractedLocalOperationSize; break; } case ocLoadLambdaCapture: { size_t index = read_short(&cache, &frame, 1); value_t subject = frame_get_argument(&frame, 0); CHECK_FAMILY(ofLambda, subject); value_t value = get_lambda_capture(subject, index); frame_push_value(&frame, value); frame.pc += kLoadLambdaCaptureOperationSize; break; } case ocLoadRefractedCapture: { size_t index = read_short(&cache, &frame, 1); size_t block_depth = read_short(&cache, &frame, 2); value_t subject = frame_get_argument(&frame, 0); frame_t home = frame_empty(); get_refractor_refracted_frame(subject, block_depth, &home); value_t lambda = frame_get_argument(&home, 0); CHECK_FAMILY(ofLambda, lambda); value_t value = get_lambda_capture(lambda, index); frame_push_value(&frame, value); frame.pc += kLoadRefractedLocalOperationSize; break; } case ocLambda: { value_t space = read_value(&cache, &frame, 1); CHECK_FAMILY(ofMethodspace, space); size_t capture_count = read_short(&cache, &frame, 2); value_t captures; E_TRY_DEF(lambda, new_heap_lambda(runtime, space, nothing())); if (capture_count == 0) { captures = ROOT(runtime, empty_array); frame.pc += kLambdaOperationSize; } else { E_TRY_SET(captures, new_heap_array(runtime, capture_count)); // The pc gets incremented here because it is after we've done all // the allocation but before anything has been popped off the stack. // This way all the above is idempotent, and the below is guaranteed // to succeed. frame.pc += kLambdaOperationSize; for (size_t i = 0; i < capture_count; i++) set_array_at(captures, i, frame_pop_value(&frame)); } set_lambda_captures(lambda, captures); frame_push_value(&frame, lambda); break; } case ocCreateBlock: { value_t space = read_value(&cache, &frame, 1); CHECK_FAMILY(ofMethodspace, space); // Create the block object. E_TRY_DEF(block, new_heap_block(runtime, nothing())); // Create the stack section that describes the block. value_t section = frame_alloc_derived_object(&frame, get_genus_descriptor(dgBlockSection)); set_barrier_state_payload(section, block); refraction_point_init(section, &frame); set_block_section_methodspace(section, space); set_block_section(block, section); value_validate(block); value_validate(section); // Push the block object. frame_push_value(&frame, block); frame.pc += kCreateBlockOperationSize; break; } case ocCreateEnsurer: { value_t code_block = read_value(&cache, &frame, 1); value_t section = frame_alloc_derived_object(&frame, get_genus_descriptor(dgEnsureSection)); set_barrier_state_payload(section, code_block); refraction_point_init(section, &frame); value_validate(section); frame_push_value(&frame, section); frame.pc += kCreateEnsurerOperationSize; break; } case ocCallEnsurer: { value_t value = frame_pop_value(&frame); value_t shard = frame_pop_value(&frame); frame_push_value(&frame, value); frame_push_value(&frame, shard); CHECK_GENUS(dgEnsureSection, shard); value_t code_block = get_barrier_state_payload(shard); CHECK_FAMILY(ofCodeBlock, code_block); // Unregister the barrier before calling it, otherwise if we leave // by escaping we'll end up calling it over again. barrier_state_unregister(shard, stack); frame.pc += kCallEnsurerOperationSize; value_t argmap = ROOT(runtime, array_of_zero); push_stack_frame(runtime, stack, &frame, get_code_block_high_water_mark(code_block), argmap); frame_set_code_block(&frame, code_block); code_cache_refresh(&cache, &frame); break; } case ocDisposeEnsurer: { // Discard the result of the ensure block. If an ensure blocks needs // to return a useful value it can do it via an escape. frame_pop_value(&frame); value_t shard = frame_pop_value(&frame); CHECK_GENUS(dgEnsureSection, shard); value_t value = frame_pop_value(&frame); frame_destroy_derived_object(&frame, get_genus_descriptor(dgEnsureSection)); frame_push_value(&frame, value); frame.pc += kDisposeEnsurerOperationSize; break; } case ocInstallSignalHandler: { value_t space = read_value(&cache, &frame, 1); CHECK_FAMILY(ofMethodspace, space); size_t dest_offset = read_short(&cache, &frame, 2); // Allocate the derived object that's going to hold the signal handler // state. value_t section = frame_alloc_derived_object(&frame, get_genus_descriptor(dgSignalHandlerSection)); // Initialize the handler. set_barrier_state_payload(section, space); refraction_point_init(section, &frame); // Bring the frame state to the point we'll want to escape to (modulo // the destination offset). frame_push_value(&frame, section); frame.pc += kInstallSignalHandlerOperationSize; // Finally capture the escape state. capture_escape_state(section, &frame, dest_offset); value_validate(section); break; } case ocUninstallSignalHandler: { // The result has been left at the top of the stack. value_t value = frame_pop_value(&frame); value_t section = frame_pop_value(&frame); CHECK_GENUS(dgSignalHandlerSection, section); barrier_state_unregister(section, stack); frame_destroy_derived_object(&frame, get_genus_descriptor(dgSignalHandlerSection)); frame_push_value(&frame, value); frame.pc += kUninstallSignalHandlerOperationSize; break; } case ocCreateEscape: { size_t dest_offset = read_short(&cache, &frame, 1); // Create an initially empty escape object. E_TRY_DEF(escape, new_heap_escape(runtime, nothing())); // Allocate the escape section on the stack, hooking the barrier into // the barrier chain. value_t section = frame_alloc_derived_object(&frame, get_genus_descriptor(dgEscapeSection)); // Point the state and object to each other. set_barrier_state_payload(section, escape); set_escape_section(escape, section); // Get execution ready for the next operation. frame_push_value(&frame, escape); frame.pc += kCreateEscapeOperationSize; // This is the execution state the escape will escape to (modulo the // destination offset) so this is what we want to capture. capture_escape_state(section, &frame, dest_offset); break; } case ocLeaveOrFireBarrier: { size_t argc = read_short(&cache, &frame, 1); // At this point the handler has been set as the subject of the call // to the handler method. Above the arguments are also two scratch // stack entries. value_t handler = frame_peek_value(&frame, argc + 2); CHECK_GENUS(dgSignalHandlerSection, handler); if (maybe_fire_next_barrier(&cache, &frame, runtime, stack, handler)) { // Pop the scratch entries off. frame_pop_value(&frame); frame_pop_value(&frame); // Pop the value off. value_t value = frame_pop_value(&frame); // Escape to the handler's home. restore_escape_state(&frame, stack, handler); code_cache_refresh(&cache, &frame); // Push the value back on, now in the handler's home frame. frame_push_value(&frame, value); } else { // If a barrier was fired we'll want to let the interpreter loop // around again so just break without touching .pc. } break; } case ocFireEscapeOrBarrier: { value_t escape = frame_get_argument(&frame, 0); CHECK_FAMILY(ofEscape, escape); value_t section = get_escape_section(escape); // Fire the next barrier or, if there are no more barriers, apply the // escape. if (maybe_fire_next_barrier(&cache, &frame, runtime, stack, section)) { value_t value = frame_get_argument(&frame, 2); restore_escape_state(&frame, stack, section); code_cache_refresh(&cache, &frame); frame_push_value(&frame, value); } else { // If a barrier was fired we'll want to let the interpreter loop // around again so just break without touching .pc. } break; } case ocDisposeEscape: { value_t value = frame_pop_value(&frame); value_t escape = frame_pop_value(&frame); CHECK_FAMILY(ofEscape, escape); value_t section = get_escape_section(escape); value_validate(section); barrier_state_unregister(section, stack); on_escape_section_exit(section); frame_destroy_derived_object(&frame, get_genus_descriptor(dgEscapeSection)); frame_push_value(&frame, value); frame.pc += kDisposeEscapeOperationSize; break; } case ocDisposeBlock: { value_t value = frame_pop_value(&frame); value_t block = frame_pop_value(&frame); CHECK_FAMILY(ofBlock, block); value_t section = get_block_section(block); barrier_state_unregister(section, stack); on_block_section_exit(section); frame_destroy_derived_object(&frame, get_genus_descriptor(dgBlockSection)); frame_push_value(&frame, value); frame.pc += kDisposeBlockOperationSize; break; } default: ERROR("Unexpected opcode %i", opcode); UNREACHABLE("unexpected opcode"); break; } } E_FINALLY(); close_frame(&frame); E_END_TRY_FINALLY(); }
VNGError VngoDirect3D::term() { close_frame(); if ((lflags & VNGO_SET_RESOLUTION) && dd != NULL) dd->RestoreDisplayMode(); if (d3dViewport) { d3dViewport->Release(); d3dViewport = NULL; } if (d3dDevice) { d3dDevice->Release(); d3dDevice = NULL; } if (SurfaceManager) { delete SurfaceManager; SurfaceManager = NULL; } if (ZBuffer) { ZBuffer->Release(); ZBuffer = NULL; } if (FrontBuffer) { if (BackBuffer && (FrontBuffer != BackBuffer)) { FrontBuffer->Release(); FrontBuffer = NULL; } } if (BackBuffer) { if (BackBuffer == Primary) Primary = NULL; BackBuffer->Release(); BackBuffer = NULL; } if (Primary) { Primary->Release(); Primary = NULL; } if (VgSystem->D3DTx) { delete VgSystem->D3DTx; VgSystem->D3DTx = NULL; } if (d3d) { d3d->Release(); d3d=NULL; } if (dd) { // Restore the normal cooperative level. dd->SetCooperativeLevel(hWndClient,DDSCL_NORMAL); dd->Release(); dd = NULL; } return VNGO_NO_ERROR; }