aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/primitives.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-17 12:51:51 +0200
committerBad Diode <bd@badd10de.dev>2021-10-17 12:51:51 +0200
commitdbeab0d63b21c14e9c462c08c8f776e9428b853c (patch)
tree12f0964fbe6257182f90a40de3a76abef9404ac3 /src/bootstrap/primitives.c
parent54060b06acd084f75bfda00517479902a5652391 (diff)
downloadbdl-dbeab0d63b21c14e9c462c08c8f776e9428b853c.tar.gz
bdl-dbeab0d63b21c14e9c462c08c8f776e9428b853c.zip
Add stack protection for recursive funcs
Diffstat (limited to 'src/bootstrap/primitives.c')
-rw-r--r--src/bootstrap/primitives.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c
index a814e40..0403e3a 100644
--- a/src/bootstrap/primitives.c
+++ b/src/bootstrap/primitives.c
@@ -5,6 +5,7 @@ Object * proc_if(Environment *env, Object *obj);
5Object * 5Object *
6eval(Environment *env, Object *root) { 6eval(Environment *env, Object *root) {
7 Object* lambda; 7 Object* lambda;
8 Object* ret = NULL;
8 bool recursion_active = false; 9 bool recursion_active = false;
9eval_start: 10eval_start:
10 switch (root->type) { 11 switch (root->type) {
@@ -15,7 +16,8 @@ eval_start:
15 case OBJ_TYPE_BOOL: 16 case OBJ_TYPE_BOOL:
16 case OBJ_TYPE_NIL: 17 case OBJ_TYPE_NIL:
17 case OBJ_TYPE_STRING: { 18 case OBJ_TYPE_STRING: {
18 return root; 19 ret = root;
20 goto eval_success;
19 } break; 21 } break;
20 case OBJ_TYPE_SYMBOL: { 22 case OBJ_TYPE_SYMBOL: {
21 Object *val = env_lookup(env, root); 23 Object *val = env_lookup(env, root);
@@ -26,7 +28,8 @@ eval_start:
26 }); 28 });
27 return obj_err; 29 return obj_err;
28 } 30 }
29 return val; 31 ret = val;
32 goto eval_success;
30 } break; 33 } break;
31 case OBJ_TYPE_PAIR: { 34 case OBJ_TYPE_PAIR: {
32 if (root->car->type == OBJ_TYPE_SYMBOL) { 35 if (root->car->type == OBJ_TYPE_SYMBOL) {
@@ -64,7 +67,8 @@ eval_start:
64 } 67 }
65 goto eval_start; 68 goto eval_start;
66 } 69 }
67 return val->proc(env, root->cdr); 70 ret = val->proc(env, root->cdr);
71 goto eval_success;
68 } 72 }
69 if (val->type == OBJ_TYPE_LAMBDA) { 73 if (val->type == OBJ_TYPE_LAMBDA) {
70 lambda = val; 74 lambda = val;
@@ -86,8 +90,12 @@ eval_lambda:
86 args = root->cdr; 90 args = root->cdr;
87 Object *params = lambda->params; 91 Object *params = lambda->params;
88 if (!recursion_active) { 92 if (!recursion_active) {
89 env = env_extend(lambda->env, env);
90 recursion_active = true; 93 recursion_active = true;
94 // Protect current stack.
95 Environment *tmp = env_create(lambda->env);
96 push_active_env(tmp);
97 // Extend environment.
98 env = env_extend(tmp, env);
91 } 99 }
92 while (params != obj_nil) { 100 while (params != obj_nil) {
93 if (args == obj_nil) { 101 if (args == obj_nil) {
@@ -138,6 +146,12 @@ eval_lambda:
138 .value = ERR_UNKNOWN_OBJ_TYPE, 146 .value = ERR_UNKNOWN_OBJ_TYPE,
139 }); 147 });
140 return obj_err; 148 return obj_err;
149eval_success:
150 if (recursion_active) {
151 // Remove stack protector.
152 pop_active_env();
153 }
154 return ret;
141} 155}
142 156
143Object * 157Object *