Skip to content

Commit

Permalink
Refactor and add tests for coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-byers committed Sep 2, 2024
1 parent 2077478 commit 12dd278
Show file tree
Hide file tree
Showing 49 changed files with 1,250 additions and 1,128 deletions.
2 changes: 1 addition & 1 deletion fuzz/fuzz.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
struct FuzzState fs = fuzz_open(PAW_HEAP_MIN);
struct FuzzState fs = fuzz_open(PAW_HEAP_DEFAULT);
pawL_load_nchunk(fs.P, "fuzz", (const char *)data, size);
fuzz_close(fs);
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ struct Allocator {
uint32_t key_min;
};

_Static_assert(PAW_HEAP_MIN >= HEAP_META_SIZE, "PAW_HEAP_MIN is too small");

uint8_t pawZ_get_flag(const struct Heap *H, uintptr_t uptr)
{
const size_t id = FLAG_BASE(H, uptr);
Expand Down Expand Up @@ -384,6 +382,7 @@ static size_t compute_flag_count(size_t h)
const size_t F = FLAGS_PER_BYTE;
const size_t m = HEAP_META_SIZE;
const size_t p = sizeof(void *);
if (h < m) return 0; // too small
return F * (h - m) / (F * p + 1);
}

Expand All @@ -393,6 +392,7 @@ int pawZ_init(paw_Env *P, void *heap, size_t heap_size, paw_Bool is_owned)
paw_assert(PAW_IS_ALIGNED(heap));
paw_assert(PAW_IS_ALIGNED(heap_size));
const size_t nf = compute_flag_count(heap_size);
if (nf == 0) return PAW_EMEMORY;

// initialize heap manager
struct Heap *H = heap;
Expand Down
100 changes: 65 additions & 35 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
#include "prefix.h"
#include <stdlib.h>

#include "paw.h"
#include "api.h"
#include "alloc.h"
#include "compile.h"
#include "env.h"
#include "gc.h"
#include "lib.h"
#include "parse.h"
#include "paw.h"
#include "rt.h"

static void *default_alloc(void *ud, void *ptr, size_t old_size, size_t new_size)
Expand Down Expand Up @@ -39,8 +40,8 @@ size_t paw_bytes_used(const paw_Env *P)
static void open_aux(paw_Env *P, void *arg)
{
paw_unused(arg);
pawG_init(P);
pawC_init(P);
pawG_init(P);
pawS_init(P);
pawP_init(P);
pawR_init(P);
Expand All @@ -49,12 +50,13 @@ static void open_aux(paw_Env *P, void *arg)
}

#define OR_DEFAULT(a, b) ((a) ? (a) : (b))
#define HEAP_MIN (PAW_ROUND_UP(sizeof(paw_Env)))

paw_Env *paw_open(const struct paw_Options *o)
{
size_t heap_size = OR_DEFAULT(o->heap_size, PAW_HEAP_DEFAULT);
heap_size &= ~(PAW_ALIGN - 1); // round down
if (heap_size < PAW_HEAP_MIN) return NULL;
if (heap_size < HEAP_MIN) return NULL;

void *ud = OR_DEFAULT(o->ud, NULL);
paw_Alloc alloc = OR_DEFAULT(o->alloc, default_alloc);
Expand All @@ -78,7 +80,7 @@ paw_Env *paw_open(const struct paw_Options *o)
if (owns_heap) alloc(ud, ph, zh, 0);
return NULL;
}
if (pawC_try(P, open_aux, NULL)) {
if (pawC_raw_try(P, open_aux, NULL)) {
paw_close(P);
return NULL;
}
Expand Down Expand Up @@ -122,36 +124,41 @@ int paw_lookup_item(paw_Env *P, struct paw_Item *pitem)
void paw_push_value(paw_Env *P, int index)
{
const Value v = *at(P, index);
pawC_pushv(P, v);
*P->top.p = v;
API_INCR_TOP(P, 1);
}

void paw_push_zero(paw_Env *P, int n)
{
for (int i = 0; i < n; ++i) {
pawC_push0(P);
V_SET_0(P->top.p + i);
}
API_INCR_TOP(P, n);
}

void paw_push_boolean(paw_Env *P, paw_Bool b)
{
pawC_pushb(P, b);
V_SET_BOOL(P->top.p, b);
API_INCR_TOP(P, 1);
}

void paw_push_float(paw_Env *P, paw_Float f)
{
pawC_pushf(P, f);
V_SET_FLOAT(P->top.p, f);
API_INCR_TOP(P, 1);
}

void paw_push_int(paw_Env *P, paw_Int i)
{
pawC_pushi(P, i);
V_SET_INT(P->top.p, i);
API_INCR_TOP(P, 1);
}

void paw_new_native(paw_Env *P, paw_Function fn, int nup)
{
Value *pv = pawC_push0(P);
Native *o = pawV_new_native(P, fn, nup);
V_SET_OBJECT(pv, o);
V_SET_OBJECT(P->top.p, o);
API_INCR_TOP(P, 1);

StackPtr top = P->top.p;
const StackPtr base = top - nup - 1;
Expand All @@ -170,8 +177,10 @@ const char *paw_push_string(paw_Env *P, const char *s)

const char *paw_push_nstring(paw_Env *P, const char *s, size_t n)
{
const Value *pv = pawC_pushns(P, s, n);
return V_TEXT(*pv);
String *str = pawS_new_nstr(P, s, n);
V_SET_OBJECT(P->top.p, str);
API_INCR_TOP(P, 1);
return str->text;
}

const char *paw_push_vfstring(paw_Env *P, const char *fmt, va_list arg)
Expand Down Expand Up @@ -221,8 +230,21 @@ paw_Function paw_native(paw_Env *P, int index)

void *paw_userdata(paw_Env *P, int index)
{
const Foreign *f = V_FOREIGN(*at(P, index));
return f->data;
Value v = *at(P, index);
return V_FOREIGN(v)->data;
}

void *paw_pointer(paw_Env *P, int index)
{
// must be an object
Object *o = V_OBJECT(*at(P, index));
if (o->gc_kind == VNATIVE) {
return ERASE_TYPE(CAST_UPTR(O_NATIVE(o)->func));
} else if (o->gc_kind == VFOREIGN) {
return O_FOREIGN(o)->data;
} else {
return o;
}
}

void paw_pop(paw_Env *P, int n)
Expand Down Expand Up @@ -280,7 +302,7 @@ int paw_call(paw_Env *P, int argc)

int paw_get_count(paw_Env *P)
{
return CAST(P->top.p - P->cf->base.p, int);
return CAST(int, P->top.p - P->cf->base.p);
}

void paw_get_typename(paw_Env *P, paw_Type code)
Expand All @@ -294,14 +316,16 @@ void paw_get_typename(paw_Env *P, paw_Type code)

void paw_get_global(paw_Env *P, int gid)
{
*pawC_push0(P) = *pawE_get_val(P, gid);
*P->top.p = *pawE_get_val(P, gid);
API_INCR_TOP(P, 1);
}

void paw_call_global(paw_Env *P, int gid, int argc)
int paw_call_global(paw_Env *P, int gid, int argc)
{
// a1..an f => f a1..an
paw_get_global(P, gid);
paw_insert(P, -argc - 2);
paw_call(P, argc);
paw_insert(P, -argc - 1);
return paw_call(P, argc);
}

static int upvalue_index(int nup, int index)
Expand All @@ -316,23 +340,23 @@ static int upvalue_index(int nup, int index)

void paw_get_upvalue(paw_Env *P, int ifn, int index)
{
Value *pv = pawC_push0(P);
Object *o = at(P, ifn)->o;
switch (o->gc_kind) {
case VNATIVE: {
Native *f = O_NATIVE(o);
*pv = f->up[upvalue_index(f->nup, index)];
*P->top.p = f->up[upvalue_index(f->nup, index)];
break;
}
case VCLOSURE: {
Closure *f = O_CLOSURE(o);
UpValue *u = f->up[upvalue_index(f->nup, index)];
*pv = *u->p.p;
*P->top.p = *u->p.p;
break;
}
default:
pawR_error(P, PAW_ETYPE, "type of object has no upvalues");
}
API_INCR_TOP(P, 1);
}

void paw_new_list(paw_Env *P, int n)
Expand All @@ -347,7 +371,8 @@ void paw_new_map(paw_Env *P, int n)

void *paw_new_foreign(paw_Env *P, size_t size, int nfields)
{
Foreign *ud = pawV_push_foreign(P, size, nfields);
Foreign *ud = pawV_new_foreign(P, size, nfields, P->top.p);
API_INCR_TOP(P, 1);
return ud->data;
}

Expand Down Expand Up @@ -392,7 +417,7 @@ void paw_shift(paw_Env *P, int n)
paw_pop(P, n);
}

#define CAST_ARITH2(op) CAST(op - PAW_ARITH_ADD, enum ArithOp2)
#define CAST_ARITH2(op) CAST(enum ArithOp2, op - PAW_ARITH_ADD)
_Static_assert(ARITH2_ADD == 0, "CAST_ARITH2 is incorrect");

void paw_arithi(paw_Env *P, enum paw_ArithOp op)
Expand Down Expand Up @@ -427,54 +452,59 @@ void paw_arithf(paw_Env *P, enum paw_ArithOp op)

void paw_cmpi(paw_Env *P, enum paw_CmpOp op)
{
pawR_cmpi(P, CAST(op, enum CmpOp));
pawR_cmpi(P, CAST(enum CmpOp, op));
}

void paw_cmpf(paw_Env *P, enum paw_CmpOp op)
{
pawR_cmpf(P, CAST(op, enum CmpOp));
pawR_cmpf(P, CAST(enum CmpOp, op));
}

void paw_cmps(paw_Env *P, enum paw_CmpOp op)
{
pawR_cmps(P, CAST(op, enum CmpOp));
pawR_cmps(P, CAST(enum CmpOp, op));
}

#define CAST_BITW2(op) CAST(op - PAW_BITW_XOR, enum BitwOp2)
#define CAST_BITW2(op) CAST(enum BitwOp2, op - PAW_BITW_XOR)
_Static_assert(BITW2_XOR == 0, "CAST_BITW2 is incorrect");

void paw_bitw(paw_Env *P, enum paw_BitwOp op)
{
switch (op) {
case PAW_BITW_NOT:
pawR_bitwi1(P, BITW1_NOT);
pawR_bitw1(P, BITW1_NOT);
break;
case PAW_BITW_XOR:
case PAW_BITW_AND:
case PAW_BITW_OR:
case PAW_BITW_SHL:
case PAW_BITW_SHR:
pawR_bitwi2(P, CAST_BITW2(op));
pawR_bitw2(P, CAST_BITW2(op));
}
}

void paw_boolop(paw_Env *P, enum paw_BoolOp op)
{
pawR_boolop(P, CAST(op, enum BoolOp));
pawR_boolop(P, CAST(enum BoolOp, op));
}

void paw_strop(paw_Env *P, enum paw_StrOp op)
{
pawR_strop(P, CAST(op, enum StrOp));
pawR_strop(P, CAST(enum StrOp, op));
}

void paw_listop(paw_Env *P, enum paw_ListOp op)
{
pawR_listop(P, CAST(op, enum ListOp));
pawR_listop(P, CAST(enum ListOp, op));
}

void paw_mapop(paw_Env *P, enum paw_MapOp op)
{
pawR_mapop(P, CAST(op, enum MapOp));
pawR_mapop(P, CAST(enum MapOp, op));
}

const char *paw_to_string(paw_Env *P, int index, paw_Type type, size_t *plen)
{
Value *pv = at(P, index);
return pawV_to_string(P, pv, type, plen);
}
22 changes: 21 additions & 1 deletion src/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@
#define PAW_API_H

#include "paw.h"
#include "value.h"
#include "util.h"

// Public API checks based off those in Lua

#if defined(PAW_USE_API_CHECK)
# include <assert.h>
# define API_CHECK(P, e, msg) assert(e)
#else
# define API_CHECK(P, e, msg) ((void)(P), paw_assert((e) && msg))
#endif

#define API_INCR_TOP(P, n) \
((P)->top.p += (n), API_CHECK(P, (P)->top.p <= (P)->cf->top.p, "stack overflow"))

#define API_CHECK_PUSH(P, n) \
API_CHECK(P, (n) < ((P)->top.p - (P)->cf->base.p), \
"stack is too large for push")

#define API_CHECK_POP(P, n) \
API_CHECK(P, (n) < (P)->top.p - (P)->cf->base.p, \
"stack is not large enough for pop")

#endif // PAW_API_H
6 changes: 5 additions & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct AstSegment *pawAst_segment_new(struct Ast *ast)
return pawK_pool_alloc(ENV(ast), &ast->pool, sizeof(struct AstSegment));
}

#if defined(PAW_DEBUG_EXTRA)

typedef struct Printer {
Buffer *buf;
paw_Env *P;
Expand Down Expand Up @@ -128,7 +130,7 @@ static void dump_decl(Printer *P, struct AstDecl *d)
DUMP_FMT(P, "line: %d\n", d->hdr.line);
switch (AST_KINDOF(d)) {
case kAstFuncDecl:
DUMP_FMT(P, "receiver: %p\n", CAST(d->func.receiver, void *));
DUMP_FMT(P, "receiver: %p\n", CAST(void *, d->func.receiver));
DUMP_FMT(P, "name: %s\n", d->func.name->text);
dump_decl_list(P, d->func.generics, "generics");
dump_decl_list(P, d->func.params, "params");
Expand Down Expand Up @@ -376,3 +378,5 @@ void pawAst_dump(struct Ast *ast)
}
pawL_push_result(P, &buf);
}

#endif
6 changes: 3 additions & 3 deletions src/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,9 @@ struct AstDecl *pawAst_new_decl(struct Ast *ast, int line, enum AstDeclKind kind
struct AstExpr *pawAst_new_expr(struct Ast *ast, int line, enum AstExprKind kind);
struct AstStmt *pawAst_new_stmt(struct Ast *ast, int line, enum AstStmtKind kind);

#define AST_CAST_DECL(x) CAST(x, struct AstDecl *)
#define AST_CAST_EXPR(x) CAST(x, struct AstExpr *)
#define AST_CAST_STMT(x) CAST(x, struct AstStmt *)
#define AST_CAST_DECL(x) CAST(struct AstDecl *, x)
#define AST_CAST_EXPR(x) CAST(struct AstExpr *, x)
#define AST_CAST_STMT(x) CAST(struct AstStmt *, x)

DEFINE_LIST(struct Ast, pawAst_decl_list_, AstDeclList, struct AstDecl)
DEFINE_LIST(struct Ast, pawAst_expr_list_, AstExprList, struct AstExpr)
Expand Down
Loading

0 comments on commit 12dd278

Please sign in to comment.