mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-12-04 22:46:31 +00:00
Compare commits
6 Commits
f116efa02c
...
c945c56482
Author | SHA1 | Date | |
---|---|---|---|
c945c56482 | |||
89d443d767 | |||
54a959438b | |||
355842989b | |||
45f36e6e87 | |||
819e76b711 |
8
Makefile
8
Makefile
@ -1,8 +1,8 @@
|
|||||||
# make clean && make && ./bin/cosmo
|
# make clean && make && ./bin/cosmo
|
||||||
|
|
||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS=-fPIE -Wall -O3 -Isrc -std=c99
|
CFLAGS=-fPIE -Wall -O0 -Isrc -std=c99 -g
|
||||||
LDFLAGS=-lm #-fsanitize=address
|
LDFLAGS=-lm -fsanitize=address
|
||||||
OUT=bin/cosmo
|
OUT=bin/cosmo
|
||||||
|
|
||||||
CHDR=\
|
CHDR=\
|
||||||
@ -19,6 +19,8 @@ CHDR=\
|
|||||||
src/cvm.h\
|
src/cvm.h\
|
||||||
src/cobj.h\
|
src/cobj.h\
|
||||||
src/cbaselib.h\
|
src/cbaselib.h\
|
||||||
|
src/cdump.h\
|
||||||
|
src/cundump.h\
|
||||||
|
|
||||||
CSRC=\
|
CSRC=\
|
||||||
src/cchunk.c\
|
src/cchunk.c\
|
||||||
@ -33,6 +35,8 @@ CSRC=\
|
|||||||
src/cvm.c\
|
src/cvm.c\
|
||||||
src/cobj.c\
|
src/cobj.c\
|
||||||
src/cbaselib.c\
|
src/cbaselib.c\
|
||||||
|
src/cdump.c\
|
||||||
|
src/cundump.c\
|
||||||
main.c\
|
main.c\
|
||||||
|
|
||||||
COBJ=$(CSRC:.c=.o)
|
COBJ=$(CSRC:.c=.o)
|
||||||
|
11
src/cdump.c
11
src/cdump.c
@ -1,5 +1,6 @@
|
|||||||
#include "cdump.h"
|
#include "cdump.h"
|
||||||
|
|
||||||
|
#include "cdebug.h"
|
||||||
#include "cmem.h"
|
#include "cmem.h"
|
||||||
#include "cobj.h"
|
#include "cobj.h"
|
||||||
#include "cvalue.h"
|
#include "cvalue.h"
|
||||||
@ -45,10 +46,10 @@ static void writeSize(DumpState *dstate, size_t d)
|
|||||||
writeBlock(dstate, &d, sizeof(size_t));
|
writeBlock(dstate, &d, sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeVector(DumpState *dstate, const void *data, size_t size)
|
static void writeVector(DumpState *dstate, const void *data, size_t size, size_t count)
|
||||||
{
|
{
|
||||||
writeSize(dstate, size);
|
writeSize(dstate, count);
|
||||||
writeBlock(dstate, data, size);
|
writeBlock(dstate, data, size * count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeHeader(DumpState *dstate)
|
static void writeHeader(DumpState *dstate)
|
||||||
@ -86,10 +87,10 @@ static void writeCObjFunction(DumpState *dstate, CObjFunction *obj)
|
|||||||
writeu8(dstate, obj->variadic);
|
writeu8(dstate, obj->variadic);
|
||||||
|
|
||||||
/* write chunk info */
|
/* write chunk info */
|
||||||
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 */
|
||||||
writeVector(dstate, obj->chunk.lineInfo, sizeof(int) * obj->chunk.count);
|
writeVector(dstate, obj->chunk.lineInfo, sizeof(int), obj->chunk.count);
|
||||||
|
|
||||||
/* write constants */
|
/* write constants */
|
||||||
writeSize(dstate, obj->chunk.constants.count);
|
writeSize(dstate, obj->chunk.constants.count);
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
#define COSMO_MAGIC "COS\x12"
|
#define COSMO_MAGIC "COS\x12"
|
||||||
#define COSMO_MAGIC_LEN 4
|
#define COSMO_MAGIC_LEN 4
|
||||||
|
|
||||||
typedef int (*cosmo_Writer)(CState *state, const void *data, size_t size, const void *ud);
|
|
||||||
|
|
||||||
bool cosmoD_isBigEndian();
|
bool cosmoD_isBigEndian();
|
||||||
|
|
||||||
/* returns non-zero on error */
|
/* returns non-zero on error */
|
||||||
|
@ -45,6 +45,9 @@ typedef struct CObjClosure CObjClosure;
|
|||||||
|
|
||||||
typedef uint8_t INSTRUCTION;
|
typedef uint8_t INSTRUCTION;
|
||||||
|
|
||||||
|
typedef int (*cosmo_Reader)(CState *state, void *data, size_t size, const void *ud);
|
||||||
|
typedef int (*cosmo_Writer)(CState *state, const void *data, size_t size, const void *ud);
|
||||||
|
|
||||||
#define COSMOMAX_UPVALS 80
|
#define COSMOMAX_UPVALS 80
|
||||||
#define FRAME_MAX 64
|
#define FRAME_MAX 64
|
||||||
#define STACK_MAX (256 * FRAME_MAX)
|
#define STACK_MAX (256 * FRAME_MAX)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include "cdump.h"
|
|
||||||
#include "cundump.h"
|
#include "cundump.h"
|
||||||
#include "cvm.h"
|
|
||||||
#include "cchunk.h"
|
#include "cchunk.h"
|
||||||
|
#include "cdump.h"
|
||||||
|
#include "cmem.h"
|
||||||
|
#include "cvm.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -11,7 +13,13 @@ typedef struct
|
|||||||
int readerStatus;
|
int readerStatus;
|
||||||
} UndumpState;
|
} UndumpState;
|
||||||
|
|
||||||
#define check(e) if (!e) return false;
|
static bool readCValue(UndumpState *udstate, CValue *val);
|
||||||
|
|
||||||
|
#define check(e) \
|
||||||
|
if (!e) { \
|
||||||
|
printf("FAILED %d\n", __LINE__); \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
static void initUndumpState(CState *state, UndumpState *udstate, cosmo_Reader reader,
|
static void initUndumpState(CState *state, UndumpState *udstate, cosmo_Reader reader,
|
||||||
const void *userData)
|
const void *userData)
|
||||||
@ -36,9 +44,9 @@ static bool readu8(UndumpState *udstate, uint8_t *d)
|
|||||||
return readBlock(udstate, d, sizeof(uint8_t));
|
return readBlock(udstate, d, sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readu16(UndumpState *udstate, uint16_t *d)
|
static bool readu32(UndumpState *udstate, uint32_t *d)
|
||||||
{
|
{
|
||||||
return readBlock(udstate, d, sizeof(uint16_t));
|
return readBlock(udstate, d, sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readSize(UndumpState *udstate, size_t *d)
|
static bool readSize(UndumpState *udstate, size_t *d)
|
||||||
@ -46,21 +54,22 @@ static bool readSize(UndumpState *udstate, size_t *d)
|
|||||||
return readBlock(udstate, d, sizeof(size_t));
|
return readBlock(udstate, d, sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readVector(UndumpState *udstate, void **data, size_t *size)
|
static bool readVector(UndumpState *udstate, void **data, size_t size, size_t *count)
|
||||||
{
|
{
|
||||||
check(readSize(udstate, size));
|
check(readSize(udstate, count));
|
||||||
*data = cosmoM_malloc(udstate->state, *size);
|
*data = cosmoM_xmalloc(udstate->state, (*count) * size);
|
||||||
return readBlock(udstate, *data, *size);
|
return readBlock(udstate, *data, (*count) * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define checku8(udstate, d, tmp) \
|
#define checku8(udstate, d, tmp) \
|
||||||
check(readu8(udstate, &tmp)); \
|
check(readu8(udstate, &tmp)); \
|
||||||
if (d != tmp) { \
|
if (d != tmp) { \
|
||||||
cosmoV_error(udstate->state, "bad header!"); \
|
cosmoV_error(udstate->state, "bad header!"); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool checkHeader(UndumpState *udstate) {
|
static bool checkHeader(UndumpState *udstate)
|
||||||
|
{
|
||||||
char magic[COSMO_MAGIC_LEN];
|
char magic[COSMO_MAGIC_LEN];
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
|
|
||||||
@ -84,42 +93,46 @@ static bool checkHeader(UndumpState *udstate) {
|
|||||||
|
|
||||||
static bool readCObjString(UndumpState *udstate, CObjString **str)
|
static bool readCObjString(UndumpState *udstate, CObjString **str)
|
||||||
{
|
{
|
||||||
size_t size;
|
uint32_t size;
|
||||||
char *data;
|
char *data;
|
||||||
|
|
||||||
check(readu32(udstate, &size));
|
check(readu32(udstate, (uint32_t *)&size));
|
||||||
if (size == 0) { /* empty string */
|
if (size == 0) { /* empty string */
|
||||||
*str = NULL;
|
*str = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*data = cosmoM_malloc(udstate->state, size+1);
|
data = cosmoM_xmalloc(udstate->state, size + 1);
|
||||||
check(readBlock(udstate, (void *)&data, size));
|
check(readBlock(udstate, (void *)data, size));
|
||||||
data[size] = '\0'; /* add NULL-terminator */
|
data[size] = '\0'; /* add NULL-terminator */
|
||||||
|
|
||||||
*str = cosmoO_takeString(udstate->state, data, size);
|
*str = cosmoO_takeString(udstate->state, data, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readCObjFunction(UndumpState *udstate, CObjFunction **func) {
|
static bool readCObjFunction(UndumpState *udstate, CObjFunction **func)
|
||||||
|
{
|
||||||
|
size_t constants;
|
||||||
|
CValue val;
|
||||||
|
|
||||||
*func = cosmoO_newFunction(udstate->state);
|
*func = cosmoO_newFunction(udstate->state);
|
||||||
|
|
||||||
check(readCObjString(udstate, &(*func)->name));
|
check(readCObjString(udstate, &(*func)->name));
|
||||||
check(readCObjString(udstate, &(*func)->module));
|
check(readCObjString(udstate, &(*func)->module));
|
||||||
|
|
||||||
check(readu32(udstate, &(*func)->args));
|
check(readu32(udstate, (uint32_t *)&(*func)->args));
|
||||||
check(readu32(udstate, &(*func)->upvals));
|
check(readu32(udstate, (uint32_t *)&(*func)->upvals));
|
||||||
check(readu8(udstate, &(*func)->variadic));
|
check(readu8(udstate, (uint8_t *)&(*func)->variadic));
|
||||||
|
|
||||||
/* read chunk info */
|
/* read chunk info */
|
||||||
check(readVector(udstate, (void **)&(*func)->chunk.buf, &(*func)->chunk.count));
|
check(
|
||||||
check(readVector(udstate, (void **)&(*func)->chunk.lineInfo, &(*func)->chunk.count));
|
readVector(udstate, (void **)&(*func)->chunk.buf, sizeof(uint8_t), &(*func)->chunk.count));
|
||||||
|
check(
|
||||||
|
readVector(udstate, (void **)&(*func)->chunk.lineInfo, sizeof(int), &(*func)->chunk.count));
|
||||||
|
|
||||||
/* read constants */
|
/* read constants */
|
||||||
size_t constants;
|
|
||||||
check(readSize(udstate, &constants));
|
check(readSize(udstate, &constants));
|
||||||
for (int i = 0; i < constants; i++) {
|
for (int i = 0; i < constants; i++) {
|
||||||
CValue val;
|
|
||||||
check(readCValue(udstate, &val));
|
check(readCValue(udstate, &val));
|
||||||
addConstant(udstate->state, &(*func)->chunk, val);
|
addConstant(udstate->state, &(*func)->chunk, val);
|
||||||
}
|
}
|
||||||
@ -145,15 +158,16 @@ static bool readCObj(UndumpState *udstate, CObj **obj)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define READ_VAR(udstate, val, type, creator) \
|
#define READ_VAR(udstate, val, type, creator) \
|
||||||
{ \
|
{ \
|
||||||
type _tmp; \
|
type _tmp; \
|
||||||
check(readBlock(udstate, &_tmp, sizeof(type))); \
|
check(readBlock(udstate, &_tmp, sizeof(type))); \
|
||||||
*val = creator(_tmp); \
|
*val = creator(_tmp); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool readCValue(UndumpState *udstate, CValue *val) {
|
static bool readCValue(UndumpState *udstate, CValue *val)
|
||||||
|
{
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
check(readu8(udstate, &type));
|
check(readu8(udstate, &type));
|
||||||
|
|
||||||
@ -178,17 +192,21 @@ static bool readCValue(UndumpState *udstate, CValue *val) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cosmoD_undump(CState *state, CObjFunction *func, cosmo_Reader writer, const void *userData) {
|
int cosmoD_undump(CState *state, cosmo_Reader reader, const void *userData, CObjFunction **func)
|
||||||
|
{
|
||||||
UndumpState udstate;
|
UndumpState udstate;
|
||||||
initUndumpState(state, &udstate, writer, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cosmoV_pushRef(state, (CObj *)*func);
|
||||||
return udstate.readerStatus;
|
return udstate.readerStatus;
|
||||||
}
|
}
|
@ -6,9 +6,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef int (*cosmo_Reader)(CState *state, void *data, size_t size, const void *ud);
|
|
||||||
|
|
||||||
/* returns non-zero on error */
|
/* returns non-zero on error */
|
||||||
int cosmoD_undump(CState *state, CObjFunction *func, cosmo_Reader writer, const void *userData);
|
int cosmoD_undump(CState *state, cosmo_Reader reader, const void *userData, CObjFunction **func);
|
||||||
|
|
||||||
#endif
|
#endif
|
25
src/cvm.c
25
src/cvm.c
@ -4,6 +4,7 @@
|
|||||||
#include "cmem.h"
|
#include "cmem.h"
|
||||||
#include "cparse.h"
|
#include "cparse.h"
|
||||||
#include "cstate.h"
|
#include "cstate.h"
|
||||||
|
#include "cundump.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -30,6 +31,28 @@ COSMO_API void cosmo_insert(CState *state, int indx, CValue val)
|
|||||||
state->top++;
|
state->top++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COSMO_API bool cosmoV_undump(CState *state, cosmo_Reader reader, const void *ud)
|
||||||
|
{
|
||||||
|
CObjFunction *func;
|
||||||
|
|
||||||
|
if (cosmoD_undump(state, reader, ud, &func)) {
|
||||||
|
// fail recovery
|
||||||
|
state->panic = false;
|
||||||
|
cosmoV_pushRef(state, (CObj *)state->error);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef VM_DEBUG
|
||||||
|
disasmChunk(&func->chunk, func->name ? func->name->str : UNNAMEDCHUNK, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// push function onto the stack so it doesn't it cleaned up by the GC, at the same stack
|
||||||
|
// location put our closure
|
||||||
|
cosmoV_pushRef(state, (CObj *)func);
|
||||||
|
*(cosmoV_getTop(state, 0)) = cosmoV_newRef(cosmoO_newClosure(state, func));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *name)
|
COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *name)
|
||||||
{
|
{
|
||||||
CObjFunction *func;
|
CObjFunction *func;
|
||||||
@ -46,7 +69,7 @@ COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fail
|
// fail recovery
|
||||||
state->panic = false;
|
state->panic = false;
|
||||||
cosmoV_pushRef(state, (CObj *)state->error);
|
cosmoV_pushRef(state, (CObj *)state->error);
|
||||||
return false;
|
return false;
|
||||||
|
12
src/cvm.h
12
src/cvm.h
@ -38,7 +38,7 @@ COSMO_API void cosmo_insert(CState *state, int indx, CValue val);
|
|||||||
COSMO_API bool cosmoV_registerProtoObject(CState *state, CObjType objType, CObjObject *obj);
|
COSMO_API bool cosmoV_registerProtoObject(CState *state, CObjType objType, CObjObject *obj);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
compiles string into a <closure>, if successful, <closure> will be pushed onto the stack
|
compiles string into a <closure>. if successful, <closure> will be pushed onto the stack
|
||||||
otherwise the <error> will be pushed.
|
otherwise the <error> will be pushed.
|
||||||
|
|
||||||
returns:
|
returns:
|
||||||
@ -47,6 +47,16 @@ COSMO_API bool cosmoV_registerProtoObject(CState *state, CObjType objType, CObjO
|
|||||||
*/
|
*/
|
||||||
COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *name);
|
COSMO_API bool cosmoV_compileString(CState *state, const char *src, const char *name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
loads a <closure> from a dump. if successful, <closure> will be pushed onto the stack
|
||||||
|
otherwise the <error> will be pushed.
|
||||||
|
|
||||||
|
returns:
|
||||||
|
false : <error> is at the top of the stack
|
||||||
|
true : <closure> is at the top of the stack
|
||||||
|
*/
|
||||||
|
COSMO_API bool cosmoV_undump(CState *state, cosmo_Reader reader, const void *ud);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
expects object to be pushed, then the key.
|
expects object to be pushed, then the key.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user