Skip to content

Commit

Permalink
Added a way to lazy loading extern superclass at runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
marcobambini committed Jun 5, 2021
1 parent e9ce16c commit 9b78d2f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
12 changes: 12 additions & 0 deletions src/compiler/gravity_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,18 @@ gnode_t *gnode_duplicate (gnode_t *node, bool deep) {
return node;
}

const char *gnode_identifier (gnode_t *node) {
if (NODE_ISA(node, NODE_VARIABLE)) return ((gnode_var_t *)node)->identifier;
if (NODE_ISA(node, NODE_CLASS_DECL)) return ((gnode_class_decl_t *)node)->identifier;
if (NODE_ISA(node, NODE_IDENTIFIER_EXPR)) return ((gnode_identifier_expr_t *)node)->value;

if (NODE_ISA(node, NODE_FUNCTION_DECL)) return ((gnode_function_decl_t *)node)->identifier;
if (NODE_ISA(node, NODE_ENUM_DECL)) return ((gnode_enum_decl_t *)node)->identifier;
if (NODE_ISA(node, NODE_MODULE_DECL)) return ((gnode_module_decl_t *)node)->identifier;

return NULL;
}

// MARK: - AST deallocator -

// STATEMENTS
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/gravity_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ gnode_t *gnode_postfix_expr_create (gtoken_s token, gnode_t *id, gnode_r *list,
gnode_t *gnode_list_expr_create (gtoken_s token, gnode_r *list1, gnode_r *list2, bool ismap, gnode_t *decl);

gnode_t *gnode_duplicate (gnode_t *node, bool deep);
const char *gnode_identifier (gnode_t *node);

gnode_r *gnode_array_create (void);
gnode_r *gnode_array_remove_byindex(gnode_r *list, size_t index);
gupvalue_t *gnode_function_add_upvalue(gnode_function_decl_t *f, gnode_var_t *symbol, uint16_t n);
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/gravity_codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ static void fix_superclasses (gvisitor_t *self) {
}

static const char *lookup_superclass_identifier (gvisitor_t *self, gravity_class_t *c) {
if (c->superlook) return c->superlook;

codegen_t *data = (codegen_t *)self->data;
gnode_class_r *superfix = &data->superfix;

Expand Down Expand Up @@ -1288,10 +1290,10 @@ static void visit_class_decl (gvisitor_t *self, gnode_class_decl_t *node) {
if (!node->superclass) report_error(self, (gnode_t*)node, "Unable to set superclass to non class object.");
}

gnode_class_decl_t *super = (gnode_class_decl_t *)node->superclass;
if (node->super_extern) {
gravity_class_setsuper_extern(c, super->identifier);
gravity_class_setsuper_extern(c, gnode_identifier((gnode_t*)node->superclass));
} else {
gnode_class_decl_t *super = (gnode_class_decl_t *)node->superclass;
if (super->data) {
// means that superclass has already been processed and its runtime representation is available
gravity_class_setsuper(c, (gravity_class_t *)super->data);
Expand Down
16 changes: 16 additions & 0 deletions src/runtime/gravity_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1680,6 +1680,22 @@ static bool class_exec (gravity_vm *vm, gravity_value_t *args, uint16_t nargs, u
// retrieve class (with sanity check)
if (!VALUE_ISA_CLASS(GET_VALUE(0))) RETURN_ERROR("Unable to execute non class object.");
gravity_class_t *c = (gravity_class_t *)GET_VALUE(0).p;

// lazy loading extern superclass
if (c->superlook) {
gravity_class_t *super = NULL;
gravity_value_t supervalue = gravity_vm_getvalue(vm, c->superlook, (int32_t)strlen(c->superlook));
if (VALUE_ISA_CLASS(supervalue)) super = VALUE_AS_CLASS(supervalue);
else RETURN_ERROR("Unable to find superclass %s for class %s.", c->superlook, c->identifier);

mem_free(c->superlook);
c->superlook = NULL;
c->superclass = super;

STATICVALUE_FROM_STRING(key, GRAVITY_INTERNAL_EXEC_NAME, strlen(GRAVITY_INTERNAL_EXEC_NAME));
gravity_closure_t *super_closure = gravity_class_lookup_closure(gravity_class_get_meta(super), key);
if (super_closure) RETURN_CLOSURE(VALUE_FROM_OBJECT(super_closure), rindex);
}

// perform alloc (then check for init)
gravity_gc_setenabled(vm, false);
Expand Down
4 changes: 2 additions & 2 deletions src/shared/gravity_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
extern "C" {
#endif

#define GRAVITY_VERSION "0.8.1" // git tag 0.8.1
#define GRAVITY_VERSION_NUMBER 0x000801 // git push --tags
#define GRAVITY_VERSION "0.8.2" // git tag 0.8.2
#define GRAVITY_VERSION_NUMBER 0x000802 // git push --tags
#define GRAVITY_BUILD_DATE __DATE__

#ifndef GRAVITY_ENABLE_DOUBLE
Expand Down

0 comments on commit 9b78d2f

Please sign in to comment.