Skip to content

Commit 58134fe

Browse files
committed
fixed: over-cloning things that don't need to be cloned
1 parent cb54655 commit 58134fe

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

compiler/include/astnodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,7 @@ typedef struct CheckerData {
19561956
typedef struct ClonerData {
19571957
u32 clone_depth;
19581958
b32 dont_copy_structs;
1959+
b32 cloning_code_block; // HACK
19591960

19601961
bh_arr(AstNode *) captured_entities;
19611962
} ClonerData;

compiler/src/checker.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3267,19 +3267,12 @@ CHECK_FUNC(insert_directive, AstDirectiveInsert** pinsert, b32 expected_expressi
32673267
ERROR(code_block->token->pos, "Here is the code block being unquoted.");
32683268
}
32693269

3270-
3271-
// HACK when cloning the inner part of a code block, we have to be able to handle
3272-
// inline functions (lambdas) that are polymorphic or have captures. With either
3273-
// of these things, we have to clone the functions so any closures/polyvars referenced
3274-
// in them can be resolved correctly. To do this tho, we have to artificially increase
3275-
// the clone depth to make the cloner think we are one layer deeper than we actually
3276-
// are to fall into the code path where we clone the body of the function.
3277-
context->cloner.clone_depth++;
3270+
context->cloner.cloning_code_block = 1;
32783271
bh_arr(AstNode *) captured_entities = NULL;
3279-
bh_arr_new(context->ast_alloc, captured_entities, 2);
3272+
bh_arr_new(context->gp_alloc, captured_entities, 2);
32803273
AstNode* cloned_block = ast_clone_with_captured_entities(context, code_block->code, &captured_entities);
32813274
cloned_block->next = insert->next;
3282-
context->cloner.clone_depth--;
3275+
context->cloner.cloning_code_block = 0;
32833276

32843277
bh_arr_each(AstNode *, pnode, captured_entities) {
32853278
add_entities_for_node(
@@ -3291,6 +3284,8 @@ CHECK_FUNC(insert_directive, AstDirectiveInsert** pinsert, b32 expected_expressi
32913284
);
32923285
}
32933286

3287+
bh_arr_free(captured_entities);
3288+
32943289
i32 skip_scope_index = get_expression_integer_value(context, insert->skip_scope_index, NULL);
32953290
Scope *scope_for_cloned_block = NULL;
32963291
if (skip_scope_index > 0) {

compiler/src/clone.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,16 @@ AstNode* ast_clone(Context *context, void* n) {
507507
AstFunction* df = (AstFunction *) nn;
508508
AstFunction* sf = (AstFunction *) node;
509509

510+
// If we cloning a code block, we do not need to clone the
511+
// function body unless there are captures, we could be related
512+
// to the code block bindings.
513+
if (context->cloner.cloning_code_block) {
514+
if (!sf->captures) {
515+
context->cloner.clone_depth--;
516+
return node;
517+
}
518+
}
519+
510520
// Check if we are cloning a function inside of a function.
511521
if (context->cloner.clone_depth > 1) {
512522
// If we are, and the inner function has a scope, this means that

0 commit comments

Comments
 (0)