Permalink
Browse files

Update the internal interpretter data storage to match the spec.

Update the internal storage mechanism to allow indexing into the callframe to
work correctly. Also, add ARGC and ARGV to the interpetter data array.

This is required to pass the poke_caller and args tests.
  • Loading branch information...
1 parent c1973c0 commit 3d278b2826dceda68c6085e1ffa99cc7f7ac4e2f @nbrown nbrown committed Apr 9, 2012
Showing with 83 additions and 40 deletions.
  1. +25 −10 src/m0/c/include/m0_interp_structures.h
  2. +16 −5 src/m0/c/m0_interp.c
  3. +24 −20 src/m0/c/m0_mob.c
  4. +18 −5 src/m0/c/m0_ops.c
@@ -2,21 +2,14 @@
# include "m0_mob_structures.h"
# include <stdint.h>
-typedef struct {
- unsigned short mob_version;
- unsigned short ireg_size;
- unsigned short nreg_size;
- unsigned short opcode_t_size;
- unsigned short pointer_size;
- unsigned short endianness;
- M0_Chunk *first_chunk;
- M0_Chunk *last_chunk;
-} M0_Interp;
+typedef uint64_t M0_Config[8];
typedef struct {
uint64_t registers[256];
} M0_CallFrame;
+typedef uint64_t M0_Interp[8];
+
enum CF_NAMED_REGS {
CF,
PCF,
@@ -32,6 +25,28 @@ enum CF_NAMED_REGS {
SPILLCF
};
+enum M0_INTERP_DATA {
+ OP_FUNCS,
+ CHUNKS,
+ CHUNK_INFO,
+ CHUNK_MAP,
+ CALL_FRAMES,
+ CONFIG,
+ ARGC,
+ ARGV
+};
+
+enum M0_CONFIG_DATA {
+ CFG_M0V,
+ CFG_REGSZ,
+ CFG_CFSZ,
+ CFG_IREGSZ,
+ CFG_NREGSZ,
+ CFG_OPCODESZ,
+ CFG_PTRSZ,
+ CFG_ENDIANNESS
+};
+
typedef enum {
INVALID,
NAMED,
View
@@ -39,6 +39,9 @@ main( int argc, const char *argv[]) {
if (!interp)
exit(1);
+ (*interp)[ARGC] = argc - 1;
+ (*interp)[ARGV] = (uint64_t)argv;
+
if (argc < 2) {
fprintf( stderr, "Usage: m0 <filename.mob>\n" );
interp_free( interp );
@@ -63,7 +66,13 @@ main( int argc, const char *argv[]) {
M0_Interp *
new_interp() {
- return calloc( 1, sizeof (M0_Interp) );
+ M0_Interp *interp = calloc( 1, sizeof (M0_Interp) );
+ M0_Config *config = calloc( 1, sizeof (M0_Config) );
+ (*config)[CFG_REGSZ] = 8;
+ (*config)[CFG_CFSZ] = sizeof( M0_CallFrame );
+
+ (*interp)[CONFIG] = (uint64_t)config;
+ return interp;
}
M0_CallFrame *
@@ -74,9 +83,11 @@ new_call_frame( M0_Interp *interp ) {
frame->registers[i] = (uint64_t)0;
/* this is a silly minimal hack for now */
- frame->registers[CHUNK] = (uint64_t)interp->first_chunk;
+ frame->registers[CHUNK] = (uint64_t)(*interp)[CHUNKS];
frame->registers[PC] = (uint64_t)0;
- frame->registers[CONSTS] = (uint64_t)interp->first_chunk->constants;
+ frame->registers[CONSTS] = (uint64_t)((M0_Chunk*) ((*interp)[CHUNKS]))->constants;
+ frame->registers[CF] = (uint64_t)frame;
+ frame->registers[INTERP] = (uint64_t)interp;
return frame;
}
@@ -89,14 +100,14 @@ call_frame_free( M0_Interp *interp, M0_CallFrame *cf ) {
void
interp_free( M0_Interp *interp ) {
- M0_Chunk *chunk = interp->first_chunk;
+ M0_Chunk *chunk = (M0_Chunk*)((*interp)[CHUNKS]);
while (chunk) {
M0_Chunk *next = chunk->next;
m0_chunk_free( chunk );
chunk = next;
}
-
+ free( ((void *)(*interp)[CONFIG]) );
free( interp );
}
View
@@ -19,9 +19,10 @@ parse_mob_dirseg( M0_Interp *interp, FILE *stream );
static int
parse_mob_chunks( M0_Interp *interp, FILE *stream );
-static void
+static M0_Interp *
add_chunk( M0_Interp *interp, const char *name,
- unsigned long chunk_id, unsigned long name_length );
+ unsigned long chunk_id, unsigned long name_length,
+ M0_Chunk *chunk);
static M0_Constants_Segment *
parse_mob_constants_segment( M0_Interp *interp, FILE *stream );
@@ -117,7 +118,7 @@ validate_mob_version( M0_Interp *interp, FILE *stream ) {
int version = read_int_from_stream( stream );
if (version == 0) {
- interp->mob_version = 0;
+ ((uint64_t*)(*interp)[CONFIG])[CFG_M0V] = 0;
return 1;
}
@@ -127,11 +128,11 @@ validate_mob_version( M0_Interp *interp, FILE *stream ) {
int
parse_header_config( M0_Interp *interp, FILE *stream ) {
- interp->ireg_size = read_int_from_stream( stream );
- interp->nreg_size = read_int_from_stream( stream );
- interp->opcode_t_size = read_int_from_stream( stream );
- interp->pointer_size = read_int_from_stream( stream );
- interp->endianness = read_int_from_stream( stream );
+ ((uint64_t*)(*interp)[CONFIG])[CFG_IREGSZ] = read_int_from_stream( stream );
+ ((uint64_t*)(*interp)[CONFIG])[CFG_NREGSZ] = read_int_from_stream( stream );
+ ((uint64_t*)(*interp)[CONFIG])[CFG_OPCODESZ] = read_int_from_stream( stream );
+ ((uint64_t*)(*interp)[CONFIG])[CFG_PTRSZ] = read_int_from_stream( stream );
+ ((uint64_t*)(*interp)[CONFIG])[CFG_ENDIANNESS] = read_int_from_stream( stream );
return 1;
}
@@ -144,6 +145,7 @@ parse_mob_dirseg( M0_Interp *interp, FILE *stream ) {
const unsigned long seg_entry_count = read_long_from_stream( stream );
const unsigned long seg_byte_count = read_long_from_stream( stream );
unsigned long chunks_found = 0;
+ M0_Chunk *last_chunk = NULL;
UNUSED(seg_byte_count);
for (; chunks_found < seg_entry_count; chunks_found++) {
@@ -154,31 +156,33 @@ parse_mob_dirseg( M0_Interp *interp, FILE *stream ) {
UNUSED(seg_offset);
- add_chunk( interp, name, chunks_found, name_length);
+ last_chunk = add_chunk( interp, name, chunks_found, name_length, last_chunk);
}
}
/* XXX: is m0b invalid if it has no chunks? */
return 1;
}
-void
+M0_Interp *
add_chunk( M0_Interp *interp, const char *name, unsigned long chunk_id,
- unsigned long name_length) {
- M0_Chunk *chunk = malloc( sizeof (M0_Chunk) );
+ unsigned long name_length,
+ M0_Chunk *chunk) {
+ if (!chunk) {
+ chunk = malloc( sizeof (M0_Chunk) );
+ } else {
+ chunk->next = malloc( sizeof (M0_Chunk) );
+ chunk = chunk->next;
+ }
chunk->id = chunk_id;
chunk->name = name;
chunk->name_length = name_length;
chunk->next = NULL;
- if (!interp->first_chunk) {
- interp->first_chunk = chunk;
- interp->last_chunk = chunk;
- }
- else {
- interp->last_chunk->next = chunk;
- interp->last_chunk = chunk;
+ if (!(*interp)[CHUNKS]) {
+ (*interp)[CHUNKS] = (uint64_t)chunk;
}
+ return chunk;
}
int
@@ -190,7 +194,7 @@ validate_segment_identifier( M0_Interp *interp, FILE *stream,
int
parse_mob_chunks( M0_Interp *interp, FILE *stream ) {
- M0_Chunk *chunk = interp->first_chunk;
+ M0_Chunk *chunk = (M0_Chunk*)(*interp)[CHUNKS];
while (chunk) {
chunk->constants = parse_mob_constants_segment( interp, stream );
View
@@ -32,11 +32,13 @@ m0_op_deref( M0_CallFrame *frame, const unsigned char *ops )
break;
}
default:
- if( ops[3] == 0) {
- frame->registers[ ops[1] ] = (*(uint64_t*)(frame->registers[ ops[2] ]));
- }
+ {
+ unsigned long offset = frame->registers[ ops[3] ];
+ uint64_t * src = (uint64_t*)(frame->registers[ ops[2] ]);
+ frame->registers[ ops[1] ] = src[offset];
/* XXX: the rest of the system has non-uniform array handling */
break;
+ }
}
}
@@ -214,7 +216,7 @@ static void
m0_op_goto_chunk(M0_Interp *interp, M0_CallFrame *frame, const unsigned char *ops )
{
uint64_t new_pc = frame->registers[ops[2]];
- M0_Chunk *chunk = interp->first_chunk;
+ M0_Chunk *chunk = (M0_Chunk*)((*interp)[CHUNKS]);
while(chunk) {
if( strncmp( chunk->name, (char *)frame->registers[ops[1]], chunk->name_length) == 0) {
frame->registers[CHUNK] = (uint64_t)chunk;
@@ -295,6 +297,14 @@ m0_op_gc_alloc( M0_CallFrame *frame, const unsigned char *ops )
frame->registers[ops[1]] = (uint64_t) ptr;
}
+static void
+m0_op_set_ref( M0_CallFrame *frame, const unsigned char *ops )
+{
+ uint64_t *ptr = (uint64_t *)frame->registers[ops[1]];
+ const int offset = frame->registers[ops[2]];
+ ptr[offset] = frame->registers[ops[3]];
+}
+
int
run_ops( M0_Interp *interp, M0_CallFrame *cf ) {
UNUSED(interp);
@@ -440,6 +450,9 @@ run_ops( M0_Interp *interp, M0_CallFrame *cf ) {
m0_op_gc_alloc( cf, &ops[pc]);
break;
+ case (M0_SET_REF):
+ m0_op_set_ref( cf, &ops[pc]);
+ break;
case (M0_EXIT):
m0_op_exit( interp, cf, &ops[pc]);
break;
@@ -450,7 +463,7 @@ run_ops( M0_Interp *interp, M0_CallFrame *cf ) {
break;
}
}
-
+ cf = (M0_CallFrame*)cf->registers[CF];
/* only branching ops definitely change the pc */
if (pc == (const unsigned long)cf->registers[PC])
cf->registers[PC] += 4;

0 comments on commit 3d278b2

Please sign in to comment.