void add_stack_frame(offset return_PC, unsigned num_locals, zword *locals, unsigned num_args, int result_var) { unsigned n; /* Don't increment the frame yet because we have error messages yet to show which need to receive a valid frame to output local variables */ if(frame_count+1 >= frame_max) { frame_max *= 2; if(stacklimit && frame_max > stacklimit) { frame_max = stacklimit; if(frame_count+1 >= frame_max) { n_show_fatal(E_STACK, "recursed deeper than allowed", frame_count+1); } } stack_frames = (Stack_frame *) n_realloc(stack_frames, sizeof(*stack_frames) * frame_max); n_show_port(E_STACK, "deep recursion not available on some 'terps", frame_max); } frame_count++; stack_frames[frame_count].stack_stack_start = stack_pointer; stack_frames[frame_count].return_PC = return_PC; stack_frames[frame_count].num_locals = num_locals; stack_frames[frame_count].arguments = num_args; stack_frames[frame_count].result_variable = result_var; check_stack_stack(num_locals); for(n = 0; n < num_locals; n++) stack_stack[stack_pointer++] = locals[n]; stack_min = stack_pointer; local_vars = stack_stack + stack_frames[frame_count].stack_stack_start; }
/* Insure we have at least addsize more zwords available on the stack, and * if not, allocate more space */ static void check_stack_stack(offset addsize) { if(stack_pointer + addsize >= stack_max) { stack_max *= 2; stack_stack = (zword *) n_realloc(stack_stack, sizeof(*stack_stack) * stack_max); n_show_port(E_STACK, "stack larger than available on some interps", stack_max); local_vars = stack_stack + stack_frames[frame_count].stack_stack_start; } }
void op_save5(void) { unsigned i; char filename[256]; unsigned length; strid_t file = NULL; offset end; switch(numoperands) { case 0: op_save4(); return; case 1: n_show_error(E_INSTR, "call save with bad number of operands", numoperands); mop_store_result(0); return; case 2: file = n_file_prompt(fileusage_Data | fileusage_BinaryMode, filemode_Write); break; default: length = LOBYTE(operand[2]); if(length > 13) n_show_port(E_INSTR, "save with filename > 13 characters", length); for(i = 0; i < length; i++) filename[i] = glk_char_to_upper(LOBYTE(operand[2] + 1 + i)); filename[length] = 0; file = n_file_name(fileusage_Data | fileusage_BinaryMode, filemode_Write, filename); break; } if(!file) { mop_store_result(0); return; } end = ((offset) operand[0]) + operand[1]; if(end > 65535 || end > total_size) { n_show_error(E_MEMORY, "attempt to save data out of range", end); mop_store_result(0); return; } w_glk_put_buffer_stream(file, (char *) z_memory + operand[0], operand[1]); glk_stream_close(file, NULL); mop_store_result(1); }