Skip to content

Commit

Permalink
Add serialisation of compiler objects
Browse files Browse the repository at this point in the history
This is preliminary work for incremental and separate compilation. The
AST and reachability map (and all associated data structures) can now
be serialised.
  • Loading branch information
Benoit Vey authored and SeanTAllen committed Jun 21, 2017
1 parent 9b85180 commit b90ec8f
Show file tree
Hide file tree
Showing 40 changed files with 2,089 additions and 134 deletions.
261 changes: 261 additions & 0 deletions src/libponyc/ast/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
#include "token.h"
#include "stringtab.h"
#include "printbuf.h"
#include "../expr/literal.h"
#include "../pass/pass.h"
#include "../pkg/program.h"
#include "../pkg/package.h"
#include "../../libponyrt/gc/serialise.h"
#include "../../libponyrt/mem/pool.h"
#include "ponyassert.h"
#include <stdbool.h>
Expand Down Expand Up @@ -1674,6 +1676,265 @@ void ast_extract_children(ast_t* parent, size_t child_count,
}
}

static void ast_serialise_trace_data(pony_ctx_t* ctx, ast_t* ast)
{
if(ast->data == NULL)
return;

switch(ast_id(ast))
{
case TK_USE:
case TK_NOMINAL:
case TK_NEW:
case TK_BE:
case TK_FUN:
case TK_TYPEPARAM:
case TK_TYPEPARAMREF:
case TK_REFERENCE:
case TK_PACKAGEREF:
case TK_TYPEREF:
case TK_PARAMREF:
case TK_VARREF:
case TK_LETREF:
case TK_FVARREF:
case TK_FLETREF:
case TK_EMBEDREF:
case TK_NEWREF:
case TK_NEWBEREF:
case TK_BEREF:
case TK_FUNREF:
case TK_NEWAPP:
case TK_BEAPP:
case TK_FUNAPP:
case TK_BECHAIN:
case TK_FUNCHAIN:
case TK_DOT:
case TK_FFICALL:
case TK_LITERALBRANCH:
pony_traceknown(ctx, ast->data, ast_pony_type(), PONY_TRACE_MUTABLE);
break;

case TK_ID:
case TK_OBJECT:
string_trace(ctx, (const char*)ast->data);
break;

case TK_PROGRAM:
pony_traceknown(ctx, ast->data, program_pony_type(), PONY_TRACE_MUTABLE);
break;

case TK_PACKAGE:
pony_traceknown(ctx, ast->data, package_pony_type(), PONY_TRACE_MUTABLE);
break;

case TK_MODULE:
pony_traceknown(ctx, ast->data, source_pony_type(), PONY_TRACE_MUTABLE);
break;

default: {}
}
}

static void ast_serialise_data(pony_ctx_t* ctx, ast_t* ast, ast_t* dst)
{
switch(ast_id(ast))
{
case TK_USE:
case TK_NOMINAL:
case TK_NEW:
case TK_BE:
case TK_FUN:
case TK_TYPEPARAM:
case TK_TYPEPARAMREF:
case TK_REFERENCE:
case TK_PACKAGEREF:
case TK_TYPEREF:
case TK_PARAMREF:
case TK_VARREF:
case TK_LETREF:
case TK_FVARREF:
case TK_FLETREF:
case TK_EMBEDREF:
case TK_NEWREF:
case TK_NEWBEREF:
case TK_BEREF:
case TK_FUNREF:
case TK_NEWAPP:
case TK_BEAPP:
case TK_FUNAPP:
case TK_BECHAIN:
case TK_FUNCHAIN:
case TK_DOT:
case TK_FFICALL:
case TK_LITERALBRANCH:
case TK_ID:
case TK_OBJECT:
case TK_PROGRAM:
case TK_PACKAGE:
case TK_MODULE:
dst->data = (void*)pony_serialise_offset(ctx, ast->data);
break;

case TK_OPERATORLITERAL:
operatorliteral_serialise_data(ast, dst);
break;

default:
dst->data = NULL;
break;
}
}

static void ast_deserialise_data(pony_ctx_t* ctx, ast_t* ast)
{
switch(ast_id(ast))
{
case TK_USE:
case TK_NOMINAL:
case TK_NEW:
case TK_BE:
case TK_FUN:
case TK_TYPEPARAM:
case TK_TYPEPARAMREF:
case TK_REFERENCE:
case TK_PACKAGEREF:
case TK_TYPEREF:
case TK_PARAMREF:
case TK_VARREF:
case TK_LETREF:
case TK_FVARREF:
case TK_FLETREF:
case TK_EMBEDREF:
case TK_NEWREF:
case TK_NEWBEREF:
case TK_BEREF:
case TK_FUNREF:
case TK_NEWAPP:
case TK_BEAPP:
case TK_FUNAPP:
case TK_BECHAIN:
case TK_FUNCHAIN:
case TK_DOT:
case TK_FFICALL:
case TK_LITERALBRANCH:
ast->data = pony_deserialise_offset(ctx, ast_pony_type(),
(uintptr_t)ast->data);
break;

case TK_ID:
case TK_OBJECT:
ast->data = (void*)string_deserialise_offset(ctx, (uintptr_t)ast->data);
break;

case TK_PROGRAM:
ast->data = pony_deserialise_offset(ctx, program_pony_type(),
(uintptr_t)ast->data);
break;

case TK_PACKAGE:
ast->data = pony_deserialise_offset(ctx, package_pony_type(),
(uintptr_t)ast->data);
break;

case TK_MODULE:
ast->data = pony_deserialise_offset(ctx, source_pony_type(),
(uintptr_t)ast->data);
break;

case TK_OPERATORLITERAL:
operatorliteral_deserialise_data(ast);
break;

default: {}
}
}

static void ast_serialise_trace(pony_ctx_t* ctx, void* object)
{
ast_t* ast = (ast_t*)object;

pony_traceknown(ctx, ast->t, token_pony_type(), PONY_TRACE_MUTABLE);
ast_serialise_trace_data(ctx, ast);

if(ast->symtab != NULL)
pony_traceknown(ctx, ast->symtab, symtab_pony_type(), PONY_TRACE_MUTABLE);

if(ast->parent != NULL)
pony_traceknown(ctx, ast->parent, ast_pony_type(), PONY_TRACE_MUTABLE);

if(ast->child != NULL)
pony_traceknown(ctx, ast->child, ast_pony_type(), PONY_TRACE_MUTABLE);

if(ast->sibling != NULL)
pony_traceknown(ctx, ast->sibling, ast_pony_type(), PONY_TRACE_MUTABLE);

if(ast->annotation_type != NULL)
pony_traceknown(ctx, ast->annotation_type, ast_pony_type(), PONY_TRACE_MUTABLE);
}

static void ast_serialise(pony_ctx_t* ctx, void* object, void* buf,
size_t offset, int mutability)
{
(void)mutability;

ast_t* ast = (ast_t*)object;
ast_t* dst = (ast_t*)((uintptr_t)buf + offset);

dst->t = (token_t*)pony_serialise_offset(ctx, ast->t);
ast_serialise_data(ctx, ast, dst);
dst->symtab = (symtab_t*)pony_serialise_offset(ctx, ast->symtab);
dst->parent = (ast_t*)pony_serialise_offset(ctx, ast->parent);
dst->child = (ast_t*)pony_serialise_offset(ctx, ast->child);
dst->sibling = (ast_t*)pony_serialise_offset(ctx, ast->sibling);
dst->annotation_type = (ast_t*)pony_serialise_offset(ctx, ast->annotation_type);
dst->flags = ast->flags;
}

static void ast_deserialise(pony_ctx_t* ctx, void* object)
{
ast_t* ast = (ast_t*)object;

ast->t = (token_t*)pony_deserialise_offset(ctx, token_pony_type(),
(uintptr_t)ast->t);
ast_deserialise_data(ctx, ast);
ast->symtab = (symtab_t*)pony_deserialise_offset(ctx, symtab_pony_type(),
(uintptr_t)ast->symtab);
ast->parent = (ast_t*)pony_deserialise_offset(ctx, ast_pony_type(),
(uintptr_t)ast->parent);
ast->child = (ast_t*)pony_deserialise_offset(ctx, ast_pony_type(),
(uintptr_t)ast->child);
ast->sibling = (ast_t*)pony_deserialise_offset(ctx, ast_pony_type(),
(uintptr_t)ast->sibling);
ast->annotation_type = (ast_t*)pony_deserialise_offset(ctx, ast_pony_type(),
(uintptr_t)ast->annotation_type);
}

static pony_type_t ast_pony =
{
0,
sizeof(ast_t),
0,
0,
NULL,
NULL,
ast_serialise_trace,
ast_serialise,
ast_deserialise,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL,
NULL
};

pony_type_t* ast_pony_type()
{
return &ast_pony;
}

void unattached_asts_init(unattached_asts_t* asts)
{
asts->storage = (ast_t**)ponyint_pool_alloc_size(16 * sizeof(ast_t*));
Expand Down
2 changes: 2 additions & 0 deletions src/libponyc/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ void ast_extract_children(ast_t* parent, size_t child_count,
children); \
}

pony_type_t* ast_pony_type();

typedef struct unattached_asts_t
{
ast_t** storage;
Expand Down
60 changes: 60 additions & 0 deletions src/libponyc/ast/source.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "source.h"
#include "error.h"
#include "stringtab.h"
#include "../../libponyrt/gc/serialise.h"
#include "../../libponyrt/mem/pool.h"
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -72,3 +73,62 @@ void source_close(source_t* source)

POOL_FREE(source_t, source);
}


static void source_serialise_trace(pony_ctx_t* ctx, void* object)
{
source_t* source = (source_t*)object;

if(source->file != NULL)
string_trace(ctx, source->file);

pony_serialise_reserve(ctx, source->m, source->len);
}

static void source_serialise(pony_ctx_t* ctx, void* object, void* buf,
size_t offset, int mutability)
{
(void)mutability;

source_t* source = (source_t*)object;
source_t* dst = (source_t*)((uintptr_t)buf + offset);

dst->file = (const char*)pony_serialise_offset(ctx, (char*)source->file);
dst->m = (char*)pony_serialise_offset(ctx, source->m);
dst->len = source->len;
}

static void source_deserialise(pony_ctx_t* ctx, void* object)
{
source_t* source = (source_t*)object;

source->file = string_deserialise_offset(ctx, (uintptr_t)source->file);
source->m = (char*)pony_deserialise_block(ctx, (uintptr_t)source->m,
source->len);
}

static pony_type_t source_pony =
{
0,
sizeof(source_t),
0,
0,
NULL,
NULL,
source_serialise_trace,
source_serialise,
source_deserialise,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
NULL,
NULL
};

pony_type_t* source_pony_type()
{
return &source_pony;
}
4 changes: 4 additions & 0 deletions src/libponyc/ast/source.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

PONY_EXTERN_C_BEGIN

typedef const struct _pony_type_t pony_type_t;

typedef struct source_t
{
const char* file; // NULL => from string, not file
Expand All @@ -32,6 +34,8 @@ source_t* source_open_string(const char* source_code);
*/
void source_close(source_t* source);

pony_type_t* source_pony_type();

PONY_EXTERN_C_END

#endif
Loading

0 comments on commit b90ec8f

Please sign in to comment.