#ifndef RAVA_FASTFRAME_H
#define RAVA_FASTFRAME_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "nanbox.h"
#include "../ir/ir.h"
#define RAVA_MAX_CALL_DEPTH 1024
#define RAVA_MAX_LOCALS_FIXED 64
#define RAVA_MAX_STACK_FIXED 512
#define RAVA_INLINE_FRAME_LOCALS 8
#define RAVA_INLINE_FRAME_STACK 16
typedef struct {
RavaMethod_t* method;
RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED];
RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED];
size_t stack_top;
size_t pc;
bool has_this;
RavaNanboxValue_t this_ref;
} FastFrame_t;
typedef struct {
RavaNanboxValue_t locals[RAVA_INLINE_FRAME_LOCALS];
RavaNanboxValue_t stack[RAVA_INLINE_FRAME_STACK];
int sp;
} RavaInlineFrame_t;
extern FastFrame_t rava_frame_pool[RAVA_MAX_CALL_DEPTH];
extern size_t rava_frame_depth;
void rava_fastframe_init(void);
FastFrame_t* rava_fastframe_push(RavaMethod_t* method, int local_count);
void rava_fastframe_pop(void);
FastFrame_t* rava_fastframe_current(void);
size_t rava_fastframe_get_depth(void);
void rava_fastframe_reset(void);
static inline void rava_fastframe_stack_push(FastFrame_t* frame, RavaNanboxValue_t v) {
if (frame->stack_top < RAVA_MAX_STACK_FIXED) {
frame->stack[frame->stack_top++] = v;
}
}
static inline RavaNanboxValue_t rava_fastframe_stack_pop(FastFrame_t* frame) {
if (frame->stack_top > 0) {
return frame->stack[--frame->stack_top];
}
return rava_nanbox_null();
}
static inline RavaNanboxValue_t rava_fastframe_stack_peek(FastFrame_t* frame) {
if (frame->stack_top > 0) {
return frame->stack[frame->stack_top - 1];
}
return rava_nanbox_null();
}
static inline void rava_fastframe_stack_clear(FastFrame_t* frame) {
frame->stack_top = 0;
}
static inline bool rava_fastframe_stack_is_empty(FastFrame_t* frame) {
return frame->stack_top == 0;
}
#endif