1
2 //--metadoc State copyright Steve Dekorte 2002
3 //--metadoc State license BSD revised
4
5 #define IOSTATE_C 1
6 #include "IoState.h"
7 #undef IOSTATE_C
8
9 #include "IoObject.h"
10 #include "IoCall.h"
11 #include "IoCoroutine.h"
12 #include "IoSeq.h"
13 #include "IoNumber.h"
14 #include "IoCFunction.h"
15 #include "IoBlock.h"
16 #include "IoList.h"
17 #include "IoMap.h"
18 //#include "IoRange.h"
19 #include "IoFile.h"
20 #include "IoDate.h"
21 #include "IoDuration.h"
22 #include "IoSeq.h"
23 #include "IoMessage_parser.h"
24 #include "IoDynLib.h"
25 #include "IoWeakLink.h"
26 #include "IoError.h"
27
28 #include "IoSystem.h"
29 #include "IoCompiler.h"
30 #include "IoDebugger.h"
31 #include "IoCollector.h"
32 #include "IoSandbox.h"
33 #include "IoDirectory.h"
34 #include "IoProfiler.h"
35 //#include "IoEditLine.h"
36
37 #include <stdlib.h>
38
39 void IoVMCodeInit(IoObject *context);
40
IoState_new_atAddress(void * address)41 void IoState_new_atAddress(void *address)
42 {
43 IoState *self = (IoState *)address;
44 IoCFunction *cFunctionProto;
45 IoSeq *seqProto;
46
47 self->randomGen = RandomGen_new();
48 RandomGen_setSeed(self->randomGen, 754905204); // no particular reason for this seed
49 // collector
50
51 self->collector = Collector_new();
52 IoState_pushCollectorPause(self);
53
54 Collector_setMarkFunc_(self->collector, (CollectorMarkFunc *)IoObject_mark);
55 Collector_setWillFreeFunc_(self->collector, (CollectorWillFreeFunc *)IoObject_willFree);
56 Collector_setFreeFunc_(self->collector, (CollectorFreeFunc *)IoObject_free);
57
58 self->mainArgs = MainArgs_new();
59 self->primitives = PointerHash_new();
60
61 self->recycledObjects = List_new();
62 self->maxRecycledObjects = IOSTATE_DEFAULT_MAX_RECYCLED_OBJECTS;
63
64 // Sandbox
65
66 self->messageCount = 0;
67 self->messageCountLimit = 0;
68 self->endTime = 0;
69
70 // symbol table
71
72 self->symbols = CHash_new();
73
74 CHash_setEqualFunc_(self->symbols, (CHashEqualFunc *)UArray_equals_);
75 CHash_setHash1Func_(self->symbols, (CHashHashFunc *)UArray_evenHash);
76 CHash_setHash2Func_(self->symbols, (CHashHashFunc *)UArray_oddHash);
77
78 /*
79 Problem:
80 - there are some interdependencies here:
81 - creating instances requires a retain stack
82 - we need a Coroutine to use for our retainStack
83 - defining any primitive methods requires Strings and CFunctions
84
85 Solution:
86 - create a temporary fake stack
87 - create Object, CFunction and String protos sans methods.
88 - then add methods to Object, CFunction and String
89 */
90
91 self->currentIoStack = Stack_new(); // temp retain stack until coro is up
92
93 self->objectProto = IoObject_proto(self); // need to do this first, so we have a retain stack
94 //IoState_retain_(self, self->objectProto);
95
96 self->mainCoroutine = IoCoroutine_proto(self);
97 Stack_free(self->currentIoStack);
98 self->currentIoStack = NULL;
99
100 IoState_setCurrentCoroutine_(self, self->mainCoroutine);
101
102 seqProto = IoSeq_proto(self);
103
104 IoState_setupQuickAccessSymbols(self);
105
106 IoObject_rawSetProto_(seqProto, self->objectProto);
107
108 cFunctionProto = IoCFunction_proto(self);
109 self->localsUpdateSlotCFunc = IoState_retain_(self,
110 IoCFunction_newWithFunctionPointer_tag_name_(self,
111 IoObject_localsUpdateSlot, NULL, "localsUpdate"));
112
113 IoSeq_protoFinish(seqProto);
114 IoObject_protoFinish(self);
115 IoCFunction_protoFinish(self);
116 IoCoroutine_protoFinish(self->mainCoroutine);
117
118 self->setSlotBlock = IoState_retain_(self, IoObject_getSlot_(self->objectProto, SIOSYMBOL("setSlot")));
119
120 // setup lobby
121
122 {
123 IoObject *objectProto = self->objectProto;
124 IoObject *protos = IOCLONE(objectProto);
125 IoObject *core = IOCLONE(objectProto);
126
127 self->core = core;
128 self->lobby = IOCLONE(objectProto);
129 IoState_retain_(self, self->lobby);
130 IoState_retain_(self, self->core);
131
132 // setup namespace
133
134 IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Lobby"), self->lobby);
135 IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Protos"), protos);
136 IoObject_setSlot_to_(protos, SIOSYMBOL("Core"), core);
137 IoObject_setSlot_to_(protos, SIOSYMBOL("Addons"), IOCLONE(objectProto));
138
139 IoObject_setSlot_to_(core, SIOSYMBOL("Compiler"), IoCompiler_proto(self));
140 IoObject_setSlot_to_(core, SIOSYMBOL("Collector"), IoCollector_proto(self));
141 IoObject_setSlot_to_(core, SIOSYMBOL("Exception"), IOCLONE(objectProto));
142
143 // setup proto chain
144
145 IoObject_rawSetProto_(objectProto, self->lobby);
146 IoObject_rawSetProto_(self->lobby, protos);
147 IoObject_rawSetProto_(protos, core);
148
149 // add protos to namespace
150
151 IoObject_setSlot_to_(core, SIOSYMBOL("Object"), objectProto);
152 IoObject_setSlot_to_(core, SIOSYMBOL("Sequence"), seqProto);
153 IoObject_setSlot_to_(core, SIOSYMBOL("Number"), IoNumber_proto(self));
154
155 IoState_setupCachedNumbers(self);
156
157 {
158 IoObject *systemProto = IoSystem_proto(self);
159 IoObject_setSlot_to_(core, SIOSYMBOL("System"), systemProto);
160 }
161
162 IoState_setupSingletons(self);
163 IoState_setupCachedMessages(self);
164
165 {
166 self->debugger = IoState_retain_(self, IoDebugger_proto(self));
167 IoObject_setSlot_to_(core, SIOSYMBOL("Debugger"), self->debugger);
168
169 self->vmWillSendMessage = IoMessage_newWithName_(self, SIOSYMBOL("vmWillSendMessage"));
170 IoMessage_rawSetCachedResult_(self->nilMessage, self->ioNil);
171 IoState_retain_(self, self->vmWillSendMessage);
172 }
173
174 IoObject_setSlot_to_(core, SIOSYMBOL("Block"), IoBlock_proto(self));
175 IoObject_setSlot_to_(core, SIOSYMBOL("List"), IoList_proto(self));
176 IoObject_setSlot_to_(core, SIOSYMBOL("Map"), IoMap_proto(self));
177 //IoObject_setSlot_to_(core, SIOSYMBOL("Range"), IoRange_proto(self));
178 IoObject_setSlot_to_(core, SIOSYMBOL("Coroutine"), self->mainCoroutine);
179 IoObject_setSlot_to_(core, SIOSYMBOL("Error"), IoError_proto(self));
180 IoObject_setSlot_to_(core, SIOSYMBOL("File"), IoFile_proto(self));
181 IoObject_setSlot_to_(core, SIOSYMBOL("Directory"), IoDirectory_proto(self));
182 IoObject_setSlot_to_(core, SIOSYMBOL("Date"), IoDate_proto(self));
183 IoObject_setSlot_to_(core, SIOSYMBOL("Duration"), IoDuration_proto(self));
184 IoObject_setSlot_to_(core, SIOSYMBOL("WeakLink"), IoWeakLink_proto(self));
185 IoObject_setSlot_to_(core, SIOSYMBOL("Sandbox"), IoSandbox_proto(self));
186 //IoObject_setSlot_to_(core, SIOSYMBOL("EditLine"), IoEditLine_proto(self));
187
188 #if !defined(__SYMBIAN32__)
189 IoObject_setSlot_to_(core, SIOSYMBOL("DynLib"), IoDynLib_proto(self));
190 #endif
191
192 //self->store =
193 //IoObject_setSlot_to_(core, SIOSYMBOL("Store"), self->store);
194 IoObject_setSlot_to_(core, SIOSYMBOL("CFunction"), cFunctionProto);
195 IoObject_setSlot_to_(core, SIOSYMBOL("Profiler"), IoProfiler_proto(self));
196
197 self->localsProto = IoState_retain_(self, IoObject_localsProto(self));
198 IoObject_setSlot_to_(core, SIOSYMBOL("Locals"), self->localsProto);
199
200 self->stopStatus = MESSAGE_STOP_STATUS_NORMAL;
201 self->returnValue = self->ioNil;
202
203 IoState_clearRetainStack(self);
204
205 IoState_popCollectorPause(self);
206
207 //Collector_collect(self->collector);
208
209 //io_show_mem("before IoVMCodeInit");
210 IoVMCodeInit(core);
211
212 //io_show_mem("after IoVMCodeInit");
213 //Collector_collect(self->collector);
214 //io_show_mem("after Collector_collect");
215
216 //IoState_popCollectorPause(self);
217 IoState_clearRetainStack(self);
218
219 //Collector_check(self->collector);
220 Collector_collect(self->collector);
221 //io_show_mem("after IoState_clearRetainStack and Collector_collect");
222 IoState_setupUserInterruptHandler(self);
223 }
224 }
225
IoState_new(void)226 IoState *IoState_new(void)
227 {
228 IoState *self = (IoState *)io_calloc(1, sizeof(IoState));
229 IoState_new_atAddress(self);
230 return self;
231 }
232
IoState_retainedSymbol(IoState * self,char * s)233 IoSymbol *IoState_retainedSymbol(IoState *self, char *s)
234 {
235 return IoState_retain_(self, SIOSYMBOL(s));
236 }
237
238
IoState_setupQuickAccessSymbols(IoState * self)239 void IoState_setupQuickAccessSymbols(IoState *self)
240 {
241 self->activateSymbol = IoState_retainedSymbol(self, "activate");
242 self->callSymbol = IoState_retainedSymbol(self, "call");
243 self->forwardSymbol = IoState_retainedSymbol(self, "forward");
244 self->noShufflingSymbol = IoState_retainedSymbol(self, "__noShuffling__");
245 self->opShuffleSymbol = IoState_retainedSymbol(self, "opShuffle");
246 //self->performSymbol = IoState_retainedSymbol(self, "perform");
247 //self->referenceIdSymbol = IoState_retainedSymbol(self, "referenceId");
248 self->semicolonSymbol = IoState_retainedSymbol(self, ";");
249 self->selfSymbol = IoState_retainedSymbol(self, "self");
250 self->setSlotSymbol = IoState_retainedSymbol(self, "setSlot");
251 self->setSlotWithTypeSymbol = IoState_retainedSymbol(self, "setSlotWithType");
252 self->stackSizeSymbol = IoState_retainedSymbol(self, "stackSize");
253 self->typeSymbol = IoState_retainedSymbol(self, "type");
254 self->updateSlotSymbol = IoState_retainedSymbol(self, "updateSlot");
255 self->runTargetSymbol = IoState_retainedSymbol(self, "runTarget");
256 self->runMessageSymbol = IoState_retainedSymbol(self, "runMessage");
257 self->runLocalsSymbol = IoState_retainedSymbol(self, "runLocals");
258 self->parentCoroutineSymbol = IoState_retainedSymbol(self, "parentCoroutine");
259 self->resultSymbol = IoState_retainedSymbol(self, "result");
260 self->exceptionSymbol = IoState_retainedSymbol(self, "exception");
261 }
262
IoState_setupSingletons(IoState * self)263 void IoState_setupSingletons(IoState *self)
264 {
265 IoObject *core = self->core;
266 // nil
267
268 self->ioNil = IOCLONE(self->objectProto);
269 IoObject_setSlot_to_(core, SIOSYMBOL("nil"), self->ioNil);
270 //IoObject_setSlot_to_(core, self->noShufflingSymbol, self->ioNil);
271 IoObject_setSlot_to_(core, SIOSYMBOL("Message"), IoMessage_proto(self));
272 IoObject_setSlot_to_(core, SIOSYMBOL("Call"), IoCall_proto(self));
273
274 self->nilMessage = IoMessage_newWithName_(self, SIOSYMBOL("nil"));
275 IoMessage_rawSetCachedResult_(self->nilMessage, self->ioNil);
276 IoState_retain_(self, self->nilMessage);
277
278 // true
279
280 self->ioTrue = IoObject_new(self);
281 IoObject_setSlot_to_(core, SIOSYMBOL("true"), self->ioTrue);
282 IoObject_setSlot_to_(self->ioTrue, SIOSYMBOL("type"), SIOSYMBOL("true"));
283 IoState_retain_(self, self->ioTrue);
284
285 // false
286
287 self->ioFalse = IoObject_new(self);
288 IoObject_setSlot_to_(core, SIOSYMBOL("false"), self->ioFalse);
289 IoObject_setSlot_to_(self->ioFalse, SIOSYMBOL("type"), SIOSYMBOL("false"));
290 IoState_retain_(self, self->ioFalse);
291
292 // Flow control: Normal
293 self->ioNormal = IoObject_new(self);
294 IoObject_setSlot_to_(core, SIOSYMBOL("Normal"), self->ioNormal);
295 IoObject_setSlot_to_(self->ioNormal, SIOSYMBOL("type"), SIOSYMBOL("Normal"));
296 IoState_retain_(self, self->ioNormal);
297
298 // Flow control: Break
299 self->ioBreak = IoObject_new(self);
300 IoObject_setSlot_to_(core, SIOSYMBOL("Break"), self->ioBreak);
301 IoObject_setSlot_to_(self->ioBreak, SIOSYMBOL("type"), SIOSYMBOL("Break"));
302 IoState_retain_(self, self->ioBreak);
303
304 // Flow control: Continue
305 self->ioContinue = IoObject_new(self);
306 IoObject_setSlot_to_(core, SIOSYMBOL("Continue"), self->ioContinue);
307 IoObject_setSlot_to_(self->ioContinue, SIOSYMBOL("type"), SIOSYMBOL("Continue"));
308 IoState_retain_(self, self->ioContinue);
309
310 // Flow control: Return
311 self->ioReturn = IoObject_new(self);
312 IoObject_setSlot_to_(core, SIOSYMBOL("Return"), self->ioReturn);
313 IoObject_setSlot_to_(self->ioReturn, SIOSYMBOL("type"), SIOSYMBOL("Return"));
314 IoState_retain_(self, self->ioReturn);
315
316 // Flow control: Eol
317 self->ioEol = IoObject_new(self);
318 IoObject_setSlot_to_(core, SIOSYMBOL("Eol"), self->ioEol);
319 IoObject_setSlot_to_(self->ioEol, SIOSYMBOL("type"), SIOSYMBOL("Eol"));
320 IoState_retain_(self, self->ioEol);
321 }
322
IoState_setupCachedMessages(IoState * self)323 void IoState_setupCachedMessages(IoState *self)
324 {
325 self->asStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("asString"));
326 IoState_retain_(self, self->asStringMessage);
327
328 self->collectedLinkMessage = IoMessage_newWithName_(self, SIOSYMBOL("collectedLink"));
329 IoState_retain_(self, self->collectedLinkMessage);
330
331 self->compareMessage = IoMessage_newWithName_(self, SIOSYMBOL("compare"));
332 IoState_retain_(self, self->compareMessage);
333
334 //self->doStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("doString"));
335 //IoState_retain_(self, self->doStringMessage);
336
337 self->initMessage = IoMessage_newWithName_(self, SIOSYMBOL("init"));
338 IoState_retain_(self, self->initMessage);
339
340 self->mainMessage = IoMessage_newWithName_(self, SIOSYMBOL("main"));
341 IoState_retain_(self, self->mainMessage);
342
343 self->opShuffleMessage = IoMessage_newWithName_(self, self->opShuffleSymbol);
344 IoState_retain_(self, self->opShuffleMessage);
345
346 self->printMessage = IoMessage_newWithName_(self, SIOSYMBOL("print"));
347 IoState_retain_(self, self->printMessage);
348
349 self->referenceIdForObjectMessage = IoMessage_newWithName_(self, SIOSYMBOL("referenceIdForObject"));
350 IoState_retain_(self, self->referenceIdForObjectMessage);
351
352 self->objectForReferenceIdMessage = IoMessage_newWithName_(self, SIOSYMBOL("objectForReferenceId"));
353 IoState_retain_(self, self->objectForReferenceIdMessage);
354
355 self->runMessage = IoMessage_newWithName_(self, SIOSYMBOL("run"));
356 IoState_retain_(self, self->runMessage);
357
358 self->willFreeMessage = IoMessage_newWithName_(self, SIOSYMBOL("willFree"));
359 IoState_retain_(self, self->willFreeMessage);
360
361 self->yieldMessage = IoMessage_newWithName_(self, SIOSYMBOL("yield"));
362 IoState_retain_(self, self->yieldMessage);
363
364 self->didFinishMessage = IoMessage_newWithName_(self, SIOSYMBOL("didFinish"));
365 IoState_retain_(self, self->didFinishMessage);
366
367 self->asBooleanMessage = IoMessage_newWithName_(self, SIOSYMBOL("asBoolean"));
368 IoState_retain_(self, self->asBooleanMessage);
369 }
370
IO_METHOD(IoObject,initBindings)371 IO_METHOD(IoObject, initBindings)
372 {
373 IOSTATE->bindingsInitCallback(IOSTATE, self);
374 return self;
375 }
376
IoState_init(IoState * self)377 void IoState_init(IoState *self)
378 {
379 if (self->bindingsInitCallback)
380 {
381 IoState_pushCollectorPause(self);
382 self->bindingsInitCallback(self, self->core);
383 IoState_popCollectorPause(self);
384 IoState_clearRetainStack(self);
385 }
386 }
387
388 /*
389 IoObject_registerAsProto(IoObject *self)
390 {
391 IoState_registerProtoWithNamed_(IOSTATE, self, IoObject_name(self));
392 }
393
394 void IoState_registerProtoWithNamed_(IoState *self, IoObject *proto, const char *name)
395 {
396 if (PointerHash_at_(self->primitives, (void *)name))
397 {
398 printf("Error registering proto: %s\n", IoObject_name(proto));
399 IoState_fatalError_(self, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice");
400 }
401
402 IoState_retain_(self, proto);
403 PointerHash_at_put_(self->primitives, (void *)func, proto);
404 //printf("registered %s\n", IoObject_name(proto));
405 }
406 */
407
IoState_registerProtoWithFunc_(IoState * self,IoObject * proto,const char * v)408 void IoState_registerProtoWithFunc_(IoState *self, IoObject *proto, const char *v)
409 {
410 IoState_registerProtoWithId_(self, proto, v);
411 }
412
IoState_registerProtoWithId_(IoState * self,IoObject * proto,const char * v)413 IOVM_API void IoState_registerProtoWithId_(IoState *self, IoObject *proto, const char *v)
414 {
415 if (PointerHash_at_(self->primitives, (void *)v))
416 {
417 printf("Error registering proto: %s\n", IoObject_name(proto));
418 IoState_fatalError_(self, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice");
419 }
420
421 IoState_retain_(self, proto);
422 PointerHash_at_put_(self->primitives, (void *)v, proto);
423 //printf("registered %s\n", IoObject_name(proto));
424 }
425
IoState_protoWithName_(IoState * self,const char * name)426 IoObject *IoState_protoWithName_(IoState *self, const char *name)
427 {
428 POINTERHASH_FOREACH(self->primitives, key, proto, if (!strcmp(IoObject_name(proto), name)) { return proto; });
429 return NULL;
430 }
431
IoState_tagList(IoState * self)432 List *IoState_tagList(IoState *self) // caller must io_free returned List
433 {
434 List *tags = List_new();
435 POINTERHASH_FOREACH(self->primitives, k, proto, List_append_(tags, IoObject_tag((IoObject *)proto)));
436 return tags;
437 }
438
IoState_done(IoState * self)439 void IoState_done(IoState *self)
440 {
441 // this should only be called from the main coro from outside of Io
442
443 List *tags = IoState_tagList(self); // need to get the tags before we io_free the protos
444
445 self->maxRecycledObjects = 0;
446
447 Collector_freeAllValues(self->collector); // io_free all objects known to the collector
448 Collector_free(self->collector);
449
450 List_do_(tags, (ListDoCallback *)IoTag_free);
451 List_free(tags);
452
453 PointerHash_free(self->primitives);
454 CHash_free(self->symbols);
455
456 LIST_DO_(self->recycledObjects, IoObject_dealloc); // this does not work now that objects and marks are separate
457 List_free(self->recycledObjects);
458 List_free(self->cachedNumbers);
459
460 RandomGen_free(self->randomGen);
461 MainArgs_free(self->mainArgs);
462 }
463
IoState_free(IoState * self)464 void IoState_free(IoState *self)
465 {
466 IoState_done(self);
467 io_free(self);
468 }
469
IoState_lobby(IoState * self)470 IoObject *IoState_lobby(IoState *self)
471 {
472 return self->lobby;
473 }
474
IoState_setLobby_(IoState * self,IoObject * obj)475 void IoState_setLobby_(IoState *self, IoObject *obj)
476 {
477 self->lobby = obj;
478 }
479
MissingProtoError(void)480 void MissingProtoError(void)
481 {
482 printf("missing proto\n");
483 }
484
IoState_protoWithId_(IoState * self,const char * v)485 IoObject *IoState_protoWithId_(IoState *self, const char *v)
486 {
487 IoObject *proto = PointerHash_at_(self->primitives, (void *)v);
488
489 //printf("IoState_protoWithId_(self, %s)\n", v);
490
491 if (!proto)
492 {
493 printf("IoState fatal error: missing proto '%s'", v);
494 IoState_fatalError_(self, "IoState_protoWithId_() Error: missing proto with id");
495 }
496
497 return proto;
498 }
499
500
501 // command line ------------------------------------------------
502
IoState_argc_argv_(IoState * self,int argc,const char * argv[])503 void IoState_argc_argv_(IoState *self, int argc, const char *argv[])
504 {
505 IoList *args = IoList_new(self);
506 int i;
507
508 for (i = 1; i < argc; i ++)
509 {
510 IoList_rawAppend_(args, SIOSYMBOL(argv[i]));
511 }
512
513 {
514 IoObject *system = IoObject_getSlot_(self->lobby, SIOSYMBOL("System"));
515 IoObject_setSlot_to_(system, SIOSYMBOL("args"), args);
516 }
517
518 MainArgs_argc_argv_(self->mainArgs, argc, argv);
519 }
520
521 // store -------------------------------------------------------
522
IoState_objectWithPid_(IoState * self,PID_TYPE pid)523 IoObject *IoState_objectWithPid_(IoState *self, PID_TYPE pid)
524 {
525 return self->ioNil;
526 }
527
528 // doString -------------------------------------------------------
529
IoState_rawOn_doCString_withLabel_(IoState * self,IoObject * target,const char * s,const char * label)530 IoObject *IoState_rawOn_doCString_withLabel_(IoState *self,
531 IoObject *target,
532 const char *s,
533 const char *label)
534 {
535 IoMessage *m = IoMessage_newFromText_label_(self, s, label);
536 return IoMessage_locals_performOn_(m, target, target);
537 }
538
539 // CLI ---------------------------------------------------------
540
IoState_rawPrompt(IoState * self)541 void IoState_rawPrompt(IoState *self)
542 {
543 int max = 1024 * 16;
544 char *s = io_calloc(1, max);
545 IoObject *result;
546
547 for (;;)
548 {
549 fputs("Io> ", stdout);
550 fflush(stdout);
551 fgets(s, max, stdin);
552
553 if (feof(stdin))
554 {
555 break;
556 }
557
558 result = IoState_rawOn_doCString_withLabel_(self, self->lobby, s, "IoState_rawPrompt()");
559
560 fputs("==> ", stdout);
561 IoObject_print(result);
562 fputs("\n", stdout);
563 }
564
565 io_free(s);
566 }
567
IoState_runCLI(IoState * self)568 void IoState_runCLI(IoState *self)
569 {
570 IoObject *result = IoState_on_doCString_withLabel_(self, self->lobby, "CLI run", "IoState_runCLI()");
571 IoObject *e = IoCoroutine_rawException(self->currentCoroutine);
572
573 if (e != self->ioNil)
574 {
575 self->exitResult = -1;
576 }
577 else if (!self->shouldExit && ISNUMBER(result))
578 {
579 self->exitResult = CNUMBER(result);
580 }
581 }
582
IoState_exitResult(IoState * self)583 IOVM_API int IoState_exitResult(IoState *self)
584 {
585 return self->exitResult;
586 }
587
588
589