#include<assert.h>#include<errno.h>#include<stdarg.h>#include<stdio.h>#include<stdlib.h>#include<stdint.h>#include<sys/stat.h>#include"exec_stack.h"#include"bytecode.h"#include"jv_alloc.h"#include"jq_parser.h"#include"locfile.h"#include"jv.h"#include"jq.h"#include"parser.h"#include"builtin.h"#include"util.h"#include"linker.h"structjq_state{void(*nomem_handler)(void*);void*nomem_handler_data;structbytecode*bc;jq_msg_cberr_cb;void*err_cb_data;jverror;structstackstk;stack_ptrcurr_frame;stack_ptrstk_top;stack_ptrfork_top;jvpath;jvvalue_at_path;intsubexp_nest;intdebug_trace_enabled;intinitial_execution;unsignednext_label;inthalted;jvexit_code;jverror_message;jvattrs;jq_input_cbinput_cb;void*input_cb_data;jq_msg_cbdebug_cb;void*debug_cb_data;};structclosure{structbytecode*bc;// jq bytecodestack_ptrenv;// jq stack address of closed frame};// locals for any function called: either a closure or a local variableunionframe_entry{structclosureclosure;jvlocalvar;};// jq function call framestructframe{structbytecode*bc;// jq bytecode for calleestack_ptrenv;// jq stack address of frame to return tostack_ptrretdata;// jq stack address to unwind to on RETuint16_t*retaddr;// jq bytecode return addressunionframe_entryentries[];// nclosures + nlocals};staticintframe_size(structbytecode*bc){returnsizeof(structframe)+sizeof(unionframe_entry)*(bc->nclosures+bc->nlocals);}staticstructframe*frame_current(structjq_state*jq){structframe*fp=stack_block(&jq->stk,jq->curr_frame);stack_ptrnext=*stack_block_next(&jq->stk,jq->curr_frame);if(next){structframe*fpnext=stack_block(&jq->stk,next);structbytecode*bc=fpnext->bc;assert(fp->retaddr>=bc->code&&fp->retaddr<bc->code+bc->codelen);}else{assert(fp->retaddr==0);}returnfp;}staticstack_ptrframe_get_level(structjq_state*jq,intlevel){stack_ptrfr=jq->curr_frame;