|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "types.h"
|
|
|
|
extern long memory[MEM_SIZE];
|
|
extern int sp;
|
|
extern int bp;
|
|
extern int pc;
|
|
extern long ax;
|
|
extern int return_flag;
|
|
extern Symbol locals[VAR_MAX];
|
|
extern int loc_cnt;
|
|
|
|
ExecutionContext* context_create() {
|
|
ExecutionContext *ctx = (ExecutionContext*)calloc(1, sizeof(ExecutionContext));
|
|
if (!ctx) return NULL;
|
|
|
|
ctx->memory_size = MEM_SIZE;
|
|
ctx->memory = (long*)calloc(MEM_SIZE, sizeof(long));
|
|
if (!ctx->memory) {
|
|
free(ctx);
|
|
return NULL;
|
|
}
|
|
|
|
ctx->loc_capacity = VAR_MAX;
|
|
ctx->locals = (Symbol*)calloc(VAR_MAX, sizeof(Symbol));
|
|
if (!ctx->locals) {
|
|
free(ctx->memory);
|
|
free(ctx);
|
|
return NULL;
|
|
}
|
|
|
|
ctx->pc = 0;
|
|
ctx->sp = 0;
|
|
ctx->bp = 0;
|
|
ctx->ax = 0;
|
|
ctx->return_flag = 0;
|
|
ctx->loc_cnt = 0;
|
|
|
|
return ctx;
|
|
}
|
|
|
|
void context_destroy(ExecutionContext *ctx) {
|
|
if (!ctx) return;
|
|
|
|
if (ctx->memory) {
|
|
free(ctx->memory);
|
|
}
|
|
if (ctx->locals) {
|
|
free(ctx->locals);
|
|
}
|
|
free(ctx);
|
|
}
|
|
|
|
ExecutionContext* context_snapshot() {
|
|
ExecutionContext *ctx = context_create();
|
|
if (!ctx) return NULL;
|
|
|
|
int safe_sp = sp;
|
|
if (safe_sp < 0) safe_sp = 0;
|
|
if (safe_sp > MEM_SIZE) safe_sp = MEM_SIZE;
|
|
|
|
for (int i = 0; i < safe_sp; i++) {
|
|
ctx->memory[i] = memory[i];
|
|
}
|
|
|
|
int safe_loc_cnt = loc_cnt;
|
|
if (safe_loc_cnt < 0) safe_loc_cnt = 0;
|
|
if (safe_loc_cnt > VAR_MAX) safe_loc_cnt = VAR_MAX;
|
|
|
|
for (int i = 0; i < safe_loc_cnt; i++) {
|
|
ctx->locals[i] = locals[i];
|
|
}
|
|
|
|
ctx->pc = pc;
|
|
ctx->sp = safe_sp;
|
|
ctx->bp = bp;
|
|
ctx->ax = ax;
|
|
ctx->return_flag = return_flag;
|
|
ctx->loc_cnt = safe_loc_cnt;
|
|
|
|
return ctx;
|
|
}
|
|
|
|
void context_restore(ExecutionContext *ctx) {
|
|
if (!ctx) return;
|
|
|
|
int safe_sp = ctx->sp;
|
|
if (safe_sp < 0) safe_sp = 0;
|
|
if (safe_sp > MEM_SIZE) safe_sp = MEM_SIZE;
|
|
|
|
for (int i = 0; i < safe_sp; i++) {
|
|
memory[i] = ctx->memory[i];
|
|
}
|
|
|
|
int safe_loc_cnt = ctx->loc_cnt;
|
|
if (safe_loc_cnt < 0) safe_loc_cnt = 0;
|
|
if (safe_loc_cnt > VAR_MAX) safe_loc_cnt = VAR_MAX;
|
|
|
|
for (int i = 0; i < safe_loc_cnt; i++) {
|
|
locals[i] = ctx->locals[i];
|
|
}
|
|
|
|
pc = ctx->pc;
|
|
sp = safe_sp;
|
|
bp = ctx->bp;
|
|
ax = ctx->ax;
|
|
return_flag = ctx->return_flag;
|
|
loc_cnt = safe_loc_cnt;
|
|
}
|