Skip to content

Commit 40bffaa

Browse files
committed
Fix fiberspawn() bug
1 parent d75b82c commit 40bffaa

File tree

5 files changed

+119
-32
lines changed

5 files changed

+119
-32
lines changed

playground/umka.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/umka_expr.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ static void parseBuiltinFiberCall(Compiler *comp, Type **type, Const *constant,
14701470

14711471
if (builtin == BUILTIN_FIBERSPAWN)
14721472
{
1473+
// Child fiber closure
14731474
Type *fnType = typeAdd(&comp->types, &comp->blocks, TYPE_FN);
14741475
typeAddParam(&comp->types, &fnType->sig, comp->anyType, "__upvalues");
14751476
typeAddParam(&comp->types, &fnType->sig, comp->fiberType, "parent");
@@ -1482,7 +1483,9 @@ static void parseBuiltinFiberCall(Compiler *comp, Type **type, Const *constant,
14821483
Type *fiberClosureType = expectedFiberClosureType;
14831484
parseExpr(comp, &fiberClosureType, constant);
14841485
doAssertImplicitTypeConv(comp, expectedFiberClosureType, &fiberClosureType, NULL);
1485-
genChangeRefCnt(&comp->gen, TOK_PLUSPLUS, expectedFiberClosureType);
1486+
1487+
// Child fiber closure type (hidden parameter)
1488+
genPushGlobalPtr(&comp->gen, fiberClosureType);
14861489

14871490
*type = comp->fiberType;
14881491
}

src/umka_vm.c

+13-5
Original file line numberDiff line numberDiff line change
@@ -2634,7 +2634,8 @@ static FORCE_INLINE void doBuiltinKeys(Fiber *fiber, HeapPages *pages, Error *er
26342634
// fn fiberspawn(childFunc: fn(parent: fiber)): fiber
26352635
static FORCE_INLINE void doBuiltinFiberspawn(Fiber *fiber, HeapPages *pages, Error *error)
26362636
{
2637-
Closure *childClosure = (Closure *)(fiber->top++)->ptrVal;
2637+
Type *childClosureType = (Type *)(fiber->top++)->ptrVal;
2638+
Closure *childClosure = (Closure *)(fiber->top++)->ptrVal;
26382639

26392640
if (!childClosure || childClosure->entryOffset <= 0)
26402641
error->runtimeHandler(error->context, VM_RUNTIME_ERROR, "Called function is not defined");
@@ -2646,15 +2647,22 @@ static FORCE_INLINE void doBuiltinFiberspawn(Fiber *fiber, HeapPages *pages, Err
26462647
child->stack = chunkAlloc(pages, child->stackSize * sizeof(Slot), NULL, NULL, true, error);
26472648
child->top = child->base = child->stack + child->stackSize - 1;
26482649

2649-
// Call child fiber closure
2650+
Signature *childClosureSig = &childClosureType->field[0]->type->sig;
26502651

26512652
// Push upvalues
26522653
child->top -= sizeof(Interface) / sizeof(Slot);
26532654
*(Interface *)child->top = childClosure->upvalue;
2655+
doBasicChangeRefCnt(child, pages, child->top, childClosureSig->param[0]->type, TOK_PLUSPLUS);
26542656

2655-
(--child->top)->ptrVal = fiber; // Push parent fiber pointer
2656-
(--child->top)->intVal = VM_RETURN_FROM_FIBER; // Push 'return from fiber' signal instead of return address
2657-
child->ip = childClosure->entryOffset; // Call
2657+
// Push parent fiber pointer
2658+
(--child->top)->ptrVal = fiber;
2659+
doBasicChangeRefCnt(child, pages, child->top->ptrVal, childClosureSig->param[1]->type, TOK_PLUSPLUS);
2660+
2661+
// Push 'return from fiber' signal instead of return address
2662+
(--child->top)->intVal = VM_RETURN_FROM_FIBER;
2663+
2664+
// Call child fiber closure
2665+
child->ip = childClosure->entryOffset;
26582666

26592667
// Return child fiber pointer
26602668
(--fiber->top)->ptrVal = child;

tests/expected.log

+73-15
Original file line numberDiff line numberDiff line change
@@ -183,21 +183,79 @@ Left & right trimming
183183

184184
>>> Fibers
185185

186-
Parent fiber: i = 0 buf = 0.00
187-
Child fiber: i = 0 buf = 0.00
188-
Parent fiber: i = 1 buf = 0.00
189-
Child fiber: i = 1 buf = 7.00
190-
Parent fiber: i = 2 buf = 3.00
191-
Child fiber: i = 2 buf = 14.00
192-
Parent fiber: i = 3 buf = 6.00
193-
Child fiber: i = 3 buf = 21.00
194-
Parent fiber: i = 4 buf = 9.00
195-
Child fiber: i = 4 buf = 28.00
196-
Parent fiber: i = 5 buf = 12.00
197-
Parent fiber: i = 6 buf = 12.00
198-
Parent fiber: i = 7 buf = 12.00
199-
Parent fiber: i = 8 buf = 12.00
200-
Parent fiber: i = 9 buf = 12.00
186+
Parent: i=0 b=0
187+
Child: i=0 a=0 d=0
188+
Grandchild: i=0 a=0 c=0
189+
Child: i=0 a=0 d=0
190+
Grandchild: i=1 a=0 c=19
191+
Child: i=0 a=0 d=11
192+
Grandchild: i=2 a=0 c=38
193+
Child: i=0 a=0 d=22
194+
Grandchild: i=3 a=0 c=57
195+
Child: i=0 a=0 d=33
196+
Grandchild: i=4 a=0 c=76
197+
Child: i=0 a=0 d=44
198+
Grandchild: i=5 a=0 c=95
199+
Child: i=0 a=0 d=55
200+
Grandchild: i=6 a=0 c=114
201+
Child: i=0 a=0 d=66
202+
Grandchild: i=7 a=0 c=133
203+
Child: i=0 a=0 d=77
204+
Grandchild: i=8 a=0 c=152
205+
Child: i=0 a=0 d=88
206+
Grandchild: i=9 a=0 c=171
207+
Parent: i=1 b=0
208+
Child: i=1 a=7 d=99
209+
Grandchild: i=10 a=7 c=0
210+
Child: i=1 a=7 d=110
211+
Grandchild: i=11 a=7 c=19
212+
Child: i=1 a=7 d=121
213+
Grandchild: i=12 a=7 c=38
214+
Child: i=1 a=7 d=132
215+
Child: i=1 a=7 d=132
216+
Child: i=1 a=7 d=132
217+
Child: i=1 a=7 d=132
218+
Child: i=1 a=7 d=132
219+
Child: i=1 a=7 d=132
220+
Child: i=1 a=7 d=132
221+
Parent: i=2 b=3
222+
Child: i=2 a=14 d=132
223+
Child: i=2 a=14 d=132
224+
Child: i=2 a=14 d=132
225+
Child: i=2 a=14 d=132
226+
Child: i=2 a=14 d=132
227+
Child: i=2 a=14 d=132
228+
Child: i=2 a=14 d=132
229+
Child: i=2 a=14 d=132
230+
Child: i=2 a=14 d=132
231+
Child: i=2 a=14 d=132
232+
Parent: i=3 b=6
233+
Child: i=3 a=21 d=132
234+
Child: i=3 a=21 d=132
235+
Child: i=3 a=21 d=132
236+
Child: i=3 a=21 d=132
237+
Child: i=3 a=21 d=132
238+
Child: i=3 a=21 d=132
239+
Child: i=3 a=21 d=132
240+
Child: i=3 a=21 d=132
241+
Child: i=3 a=21 d=132
242+
Child: i=3 a=21 d=132
243+
Parent: i=4 b=9
244+
Child: i=4 a=28 d=132
245+
Child: i=4 a=28 d=132
246+
Child: i=4 a=28 d=132
247+
Child: i=4 a=28 d=132
248+
Child: i=4 a=28 d=132
249+
Child: i=4 a=28 d=132
250+
Child: i=4 a=28 d=132
251+
Child: i=4 a=28 d=132
252+
Child: i=4 a=28 d=132
253+
Child: i=4 a=28 d=132
254+
Parent: i=5 b=12
255+
Parent: i=6 b=12
256+
Parent: i=7 b=12
257+
Parent: i=8 b=12
258+
Parent: i=9 b=12
201259

202260

203261
>>> Functional tools

tests/fibers.um

+28-10
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
1-
import "std.um"
2-
31
fn test*() {
4-
buf := make([]real, 2)
2+
a := new(int)
3+
b := new(int)
4+
5+
child := fiberspawn(|a, b| {
56

6-
child := fiberspawn(|buf| {
7+
c := new(int)
8+
d := new(int)
9+
10+
grandchild := fiberspawn(|a, b, c, d| {
11+
for i := 0; i < 13; i++ {
12+
printf(" Grandchild: i=%d a=%d c=%d\n", i, a^, c^)
13+
d^ = i * 11
14+
fibercall(parent)
15+
}
16+
})
17+
718
for i := 0; i < 5; i++ {
8-
std::println("Child fiber: i = " + std::itoa(i) + " buf = " + std::ftoa(buf[0], 2))
9-
buf[1] = i * 3
19+
for j := 0; j < 10; j++ {
20+
printf(" Child: i=%d a=%d d=%d\n", i, a^, d^)
21+
c^ = j * 19
22+
if fiberalive(grandchild) {
23+
fibercall(grandchild)
24+
}
25+
}
26+
27+
b^ = i * 3
1028
fibercall(parent)
1129
}
1230
})
1331

1432
for i := 0; i < 10; i++ {
15-
std::println("Parent fiber: i = " + std::itoa(i) + " buf = " + std::ftoa(buf[1], 2))
16-
buf[0] = i * 7
33+
printf("Parent: i=%d b=%d\n", i, b^)
34+
a^ = i * 7
1735
if fiberalive(child) {
1836
fibercall(child)
1937
}
20-
}
21-
}
38+
}
39+
}
2240

2341
fn main() {
2442
test()

0 commit comments

Comments
 (0)