Skip to content

Commit

Permalink
Merge pull request #5 from inobulles/bugfix/double-scope-on-stack-whe…
Browse files Browse the repository at this point in the history
…n-calling-on-instance

Fix double scope on stack when calling on instance
  • Loading branch information
obiwac authored Dec 20, 2024
2 parents 7750e12 + b8f0dd7 commit c1d882a
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 13 deletions.
18 changes: 6 additions & 12 deletions flamingo/call.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ static int call(
flamingo_val_t** rv,
flamingo_arg_list_t* args
) {
// Note about calling functions on instances: we don't actually need to add its scope to the environment, because the environment on its callable already has that scope on the scope stack.
// If we ever need to know whether or not we're calling on an instance, the following check can be used: accessed_val != NULL && accessed_val->kind == FLAMINGO_VAL_KIND_INST

bool const is_class = callable->fn.kind == FLAMINGO_FN_KIND_CLASS;
bool const on_inst = accessed_val != NULL && accessed_val->kind == FLAMINGO_VAL_KIND_INST;
bool const is_extern = callable->fn.kind == FLAMINGO_FN_KIND_EXTERN;
bool const is_ptm = callable->fn.kind == FLAMINGO_FN_KIND_PTM;

Expand All @@ -107,19 +109,15 @@ static int call(
// Switch context's current environment to the one closed over by the function.

flamingo_env_t* const prev_env = flamingo->env;
flamingo->env = callable->fn.env == NULL ? prev_env : callable->fn.env;

// If calling on an instance, add that instance's scope to the scope stack.
// We do this before the arguments scope because we want parameters to shadow stuff in the instance's scope.

if (on_inst) {
env_gently_attach_scope(flamingo->env, accessed_val->inst.scope);
if (callable->fn.env != NULL) {
flamingo->env = callable->fn.env;
}

// Create a new scope for the function for the argument assignments.
// It's important to set 'scope->class_scope' to false for functions as new scopes will copy the 'class_scope' property from their parents otherwise.

flamingo_scope_t* scope = env_push_scope(flamingo->env);
flamingo_scope_t* const scope = env_push_scope(flamingo->env);
scope->class_scope = is_class;

if (is_ptm) {
Expand Down Expand Up @@ -193,10 +191,6 @@ static int call(

env_pop_scope(flamingo->env);

if (on_inst) {
env_gently_detach_scope(flamingo->env);
}

flamingo->src = prev_src;
flamingo->src_size = prev_src_size;

Expand Down
2 changes: 2 additions & 0 deletions flamingo/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ static flamingo_scope_t* env_cur_scope(flamingo_env_t* env) {
}

static void env_gently_attach_scope(flamingo_env_t* env, flamingo_scope_t* scope) {
assert(env->scope_stack_size == 0 || env->scope_stack[env->scope_stack_size - 1] != scope);

env->scope_stack = realloc(env->scope_stack, ++env->scope_stack_size * sizeof *env->scope_stack);
assert(env->scope_stack != NULL);

Expand Down
2 changes: 1 addition & 1 deletion tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ for test in $(ls -p tests | grep -v /); do
continue
fi

echo -n "Running test $test... "
printf "Running test $test... "
bin/flamingo tests/$test > /dev/null

if [ $? = 0 ]; then
Expand Down

0 comments on commit c1d882a

Please sign in to comment.