Compare commits

..

No commits in common. "93a09698a95462a0d1d972d81ce06c47630fa1ac" and "c945c5648259765b681f1e31582dc95522e9275e" have entirely different histories.

2 changed files with 51 additions and 81 deletions

View File

@ -4,7 +4,6 @@
#include "cmem.h" #include "cmem.h"
#include "cobj.h" #include "cobj.h"
#include "cvalue.h" #include "cvalue.h"
#include "cvm.h"
typedef struct typedef struct
{ {
@ -14,12 +13,7 @@ typedef struct
int writerStatus; int writerStatus;
} DumpState; } DumpState;
static bool writeCValue(DumpState *dstate, CValue val); static void writeCValue(DumpState *dstate, CValue val);
#define check(e) \
if (!e) { \
return false; \
}
static void initDumpState(CState *state, DumpState *dstate, cosmo_Writer writer, static void initDumpState(CState *state, DumpState *dstate, cosmo_Writer writer,
const void *userData) const void *userData)
@ -30,92 +24,82 @@ static void initDumpState(CState *state, DumpState *dstate, cosmo_Writer writer,
dstate->writerStatus = 0; dstate->writerStatus = 0;
} }
static bool writeBlock(DumpState *dstate, const void *data, size_t size) static void writeBlock(DumpState *dstate, const void *data, size_t size)
{ {
if (dstate->writerStatus == 0) { if (dstate->writerStatus == 0) {
dstate->writerStatus = dstate->writer(dstate->state, data, size, dstate->userData); dstate->writerStatus = dstate->writer(dstate->state, data, size, dstate->userData);
} }
return dstate->writerStatus == 0;
} }
static bool writeu8(DumpState *dstate, uint8_t d) static void writeu8(DumpState *dstate, uint8_t d)
{ {
return writeBlock(dstate, &d, sizeof(uint8_t)); writeBlock(dstate, &d, sizeof(uint8_t));
} }
static bool writeu32(DumpState *dstate, uint32_t d) static void writeu32(DumpState *dstate, uint32_t d)
{ {
return writeBlock(dstate, &d, sizeof(uint32_t)); writeBlock(dstate, &d, sizeof(uint32_t));
} }
static bool writeSize(DumpState *dstate, size_t d) static void writeSize(DumpState *dstate, size_t d)
{ {
return writeBlock(dstate, &d, sizeof(size_t)); writeBlock(dstate, &d, sizeof(size_t));
} }
static bool writeVector(DumpState *dstate, const void *data, size_t size, size_t count) static void writeVector(DumpState *dstate, const void *data, size_t size, size_t count)
{ {
check(writeSize(dstate, count)); writeSize(dstate, count);
check(writeBlock(dstate, data, size * count)); writeBlock(dstate, data, size * count);
return true;
} }
static bool writeHeader(DumpState *dstate) static void writeHeader(DumpState *dstate)
{ {
check(writeBlock(dstate, COSMO_MAGIC, COSMO_MAGIC_LEN)); writeBlock(dstate, COSMO_MAGIC, COSMO_MAGIC_LEN);
/* after the magic, we write some platform information */ /* after the magic, we write some platform information */
check(writeu8(dstate, cosmoD_isBigEndian())); writeu8(dstate, cosmoD_isBigEndian());
check(writeu8(dstate, sizeof(cosmo_Number))); writeu8(dstate, sizeof(cosmo_Number));
check(writeu8(dstate, sizeof(size_t))); writeu8(dstate, sizeof(size_t));
check(writeu8(dstate, sizeof(int))); writeu8(dstate, sizeof(int));
return true;
} }
static bool writeCObjString(DumpState *dstate, CObjString *obj) static void writeCObjString(DumpState *dstate, CObjString *obj)
{ {
if (obj == NULL) { /* this is in case cobjfunction's name or module strings are null */ if (obj == NULL) { /* this is in case cobjfunction's name or module strings are null */
check(writeu32(dstate, 0)); writeu32(dstate, 0);
return true; return;
} }
/* write string length */ /* write string length */
check(writeu32(dstate, obj->length)); writeu32(dstate, obj->length);
/* write string data */ /* write string data */
check(writeBlock(dstate, obj->str, obj->length)); writeBlock(dstate, obj->str, obj->length);
return true;
} }
static bool writeCObjFunction(DumpState *dstate, CObjFunction *obj) static void writeCObjFunction(DumpState *dstate, CObjFunction *obj)
{ {
check(writeCObjString(dstate, obj->name)); writeCObjString(dstate, obj->name);
check(writeCObjString(dstate, obj->module)); writeCObjString(dstate, obj->module);
check(writeu32(dstate, obj->args)); writeu32(dstate, obj->args);
check(writeu32(dstate, obj->upvals)); writeu32(dstate, obj->upvals);
check(writeu8(dstate, obj->variadic)); writeu8(dstate, obj->variadic);
/* write chunk info */ /* write chunk info */
check(writeVector(dstate, obj->chunk.buf, sizeof(uint8_t), obj->chunk.count)); writeVector(dstate, obj->chunk.buf, sizeof(uint8_t), obj->chunk.count);
/* write line info */ /* write line info */
check(writeVector(dstate, obj->chunk.lineInfo, sizeof(int), obj->chunk.count)); writeVector(dstate, obj->chunk.lineInfo, sizeof(int), obj->chunk.count);
/* write constants */ /* write constants */
check(writeSize(dstate, obj->chunk.constants.count)); writeSize(dstate, obj->chunk.constants.count);
for (int i = 0; i < obj->chunk.constants.count; i++) { for (int i = 0; i < obj->chunk.constants.count; i++) {
check(writeCValue(dstate, obj->chunk.constants.values[i])); writeCValue(dstate, obj->chunk.constants.values[i]);
} }
return true;
} }
static bool writeCObj(DumpState *dstate, CObj *obj) static void writeCObj(DumpState *dstate, CObj *obj)
{ {
/* /*
we can kind of cheat here since our parser only emits a few very limited CObjs... we can kind of cheat here since our parser only emits a few very limited CObjs...
@ -133,27 +117,24 @@ static bool writeCObj(DumpState *dstate, CObj *obj)
/* write object payload/body */ /* write object payload/body */
switch (t) { switch (t) {
case COBJ_STRING: case COBJ_STRING:
check(writeCObjString(dstate, (CObjString *)obj)); writeCObjString(dstate, (CObjString *)obj);
break; break;
case COBJ_FUNCTION: case COBJ_FUNCTION:
check(writeCObjFunction(dstate, (CObjFunction *)obj)); writeCObjFunction(dstate, (CObjFunction *)obj);
break; break;
default: default:
cosmoV_error(dstate->state, "invalid cobj type: %d", t); break;
return false;
} }
return true;
} }
#define WRITE_VAR(dstate, type, expression) \ #define WRITE_VAR(dstate, type, expression) \
{ \ { \
type _tmp = expression; \ type _tmp = expression; \
check(writeBlock(dstate, &_tmp, sizeof(_tmp))); \ writeBlock(dstate, &_tmp, sizeof(_tmp)); \
break; \ break; \
} }
static bool writeCValue(DumpState *dstate, CValue val) static void writeCValue(DumpState *dstate, CValue val)
{ {
CosmoType t = GET_TYPE(val); CosmoType t = GET_TYPE(val);
@ -167,16 +148,12 @@ static bool writeCValue(DumpState *dstate, CValue val)
case COSMO_TBOOLEAN: case COSMO_TBOOLEAN:
WRITE_VAR(dstate, bool, cosmoV_readBoolean(val)) WRITE_VAR(dstate, bool, cosmoV_readBoolean(val))
case COSMO_TREF: case COSMO_TREF:
check(writeCObj(dstate, cosmoV_readRef(val))); writeCObj(dstate, cosmoV_readRef(val));
break;
case COSMO_TNIL: /* no body */
break; break;
case COSMO_TNIL: /* fallthrough, no body */
default: default:
cosmoV_error(dstate->state, "invalid value type: %d", t); break;
return false;
} }
return true;
} }
#undef WRITE_VAR #undef WRITE_VAR
@ -197,8 +174,8 @@ int cosmoD_dump(CState *state, CObjFunction *func, cosmo_Writer writer, const vo
DumpState dstate; DumpState dstate;
initDumpState(state, &dstate, writer, userData); initDumpState(state, &dstate, writer, userData);
check(writeHeader(&dstate)); writeHeader(&dstate);
check(writeCObjFunction(&dstate, func)); writeCObjFunction(&dstate, func);
return dstate.writerStatus; return dstate.writerStatus;
} }

View File

@ -17,6 +17,7 @@ static bool readCValue(UndumpState *udstate, CValue *val);
#define check(e) \ #define check(e) \
if (!e) { \ if (!e) { \
printf("FAILED %d\n", __LINE__); \
return false; \ return false; \
} }
@ -32,7 +33,6 @@ static void initUndumpState(CState *state, UndumpState *udstate, cosmo_Reader re
static bool readBlock(UndumpState *udstate, void *data, size_t size) static bool readBlock(UndumpState *udstate, void *data, size_t size)
{ {
if (udstate->readerStatus == 0) { if (udstate->readerStatus == 0) {
/* if reader returns 1, we expect an error was thrown */
udstate->readerStatus = udstate->reader(udstate->state, data, size, udstate->userData); udstate->readerStatus = udstate->reader(udstate->state, data, size, udstate->userData);
} }
@ -74,7 +74,7 @@ static bool checkHeader(UndumpState *udstate)
uint8_t tmp; uint8_t tmp;
/* check header */ /* check header */
check(readBlock(udstate, magic, COSMO_MAGIC_LEN)); readBlock(udstate, magic, COSMO_MAGIC_LEN);
if (memcmp(magic, COSMO_MAGIC, COSMO_MAGIC_LEN) != 0) { if (memcmp(magic, COSMO_MAGIC, COSMO_MAGIC_LEN) != 0) {
cosmoV_error(udstate->state, "bad header!"); cosmoV_error(udstate->state, "bad header!");
return false; return false;
@ -117,9 +117,6 @@ static bool readCObjFunction(UndumpState *udstate, CObjFunction **func)
*func = cosmoO_newFunction(udstate->state); *func = cosmoO_newFunction(udstate->state);
/* make sure our GC can see that we're currently using this function (and the values it uses) */
cosmoV_pushRef(udstate->state, (CObj *)*func);
check(readCObjString(udstate, &(*func)->name)); check(readCObjString(udstate, &(*func)->name));
check(readCObjString(udstate, &(*func)->module)); check(readCObjString(udstate, &(*func)->module));
@ -140,8 +137,6 @@ static bool readCObjFunction(UndumpState *udstate, CObjFunction **func)
addConstant(udstate->state, &(*func)->chunk, val); addConstant(udstate->state, &(*func)->chunk, val);
} }
/* pop function off stack */
cosmoV_pop(udstate->state);
return true; return true;
} }
@ -173,10 +168,10 @@ static bool readCObj(UndumpState *udstate, CObj **obj)
static bool readCValue(UndumpState *udstate, CValue *val) static bool readCValue(UndumpState *udstate, CValue *val)
{ {
uint8_t t; uint8_t type;
check(readu8(udstate, &t)); check(readu8(udstate, &type));
switch (t) { switch (type) {
case COSMO_TNUMBER: case COSMO_TNUMBER:
READ_VAR(udstate, val, cosmo_Number, cosmoV_newNumber) READ_VAR(udstate, val, cosmo_Number, cosmoV_newNumber)
case COSMO_TBOOLEAN: case COSMO_TBOOLEAN:
@ -191,26 +186,24 @@ static bool readCValue(UndumpState *udstate, CValue *val)
*val = cosmoV_newNil(); *val = cosmoV_newNil();
break; break;
default: default:
cosmoV_error(udstate->state, "invalid value type: %d", t); break;
return false;
} }
return true; return true;
} }
#undef READ_VAR
#undef check
int cosmoD_undump(CState *state, cosmo_Reader reader, const void *userData, CObjFunction **func) int cosmoD_undump(CState *state, cosmo_Reader reader, const void *userData, CObjFunction **func)
{ {
UndumpState udstate; UndumpState udstate;
initUndumpState(state, &udstate, reader, userData); initUndumpState(state, &udstate, reader, userData);
if (!checkHeader(&udstate)) { if (!checkHeader(&udstate)) {
cosmoV_pushNil(state);
return 1; return 1;
} }
if (!readCObjFunction(&udstate, func)) { if (!readCObjFunction(&udstate, func)) {
cosmoV_pushNil(state);
return 1; return 1;
} }