2 //metadoc State copyright Steve Dekorte 2002
3 //metadoc State license BSD revised
11 #include "IoCoroutine.h"
14 #include "IoCFunction.h"
18 //#include "IoRange.h"
21 #include "IoDuration.h"
23 #include "IoMessage_parser.h"
25 #include "IoWeakLink.h"
28 #include "IoCompiler.h"
29 #include "IoDebugger.h"
30 #include "IoCollector.h"
31 #include "IoSandbox.h"
32 #include "IoDirectory.h"
33 //#include "IoEditLine.h"
37 void IoVMCodeInit(IoObject
*context
);
39 void IoState_new_atAddress(void *address
)
41 IoState
*self
= (IoState
*)address
;
42 IoCFunction
*cFunctionProto
;
47 self
->collector
= Collector_new();
48 IoState_pushCollectorPause(self
);
50 Collector_setMarkFunc_(self
->collector
, (CollectorMarkFunc
*)IoObject_mark
);
51 Collector_setWillFreeFunc_(self
->collector
, (CollectorWillFreeFunc
*)IoObject_willFree
);
52 Collector_setFreeFunc_(self
->collector
, (CollectorFreeFunc
*)IoObject_free
);
54 self
->mainArgs
= MainArgs_new();
55 self
->primitives
= PHash_new();
57 self
->recycledObjects
= List_new();
58 self
->maxRecycledObjects
= IOSTATE_DEFAULT_MAX_RECYCLED_OBJECTS
;
62 self
->messageCount
= 0;
63 self
->messageCountLimit
= 0;
68 self
->symbols
= SHash_new();
70 SHash_setKeysEqualCallback(self
->symbols
, (SHashKeysEqualCallback
*)UArray_equalsWithHashCheck_
);
71 SHash_setHashForKeyCallback(self
->symbols
, (SHashHashforKeyCallback
*)UArray_hash
);
75 - there are some interdependencies here:
76 - creating instances requires a retain stack
77 - we need a Coroutine to use for our retainStack
78 - defining any primitive methods requires Strings and CFunctions
81 - create a temporary fake stack
82 - create Object, CFunction and String protos sans methods.
83 - then add methods to Object, CFunction and String
86 self
->currentIoStack
= Stack_new(); // temp retain stack until coro is up
88 self
->objectProto
= IoObject_proto(self
); // need to do this first, so we have a retain stack
89 //IoState_retain_(self, self->objectProto);
91 self
->mainCoroutine
= IoCoroutine_proto(self
);
92 Stack_free(self
->currentIoStack
);
93 self
->currentIoStack
= NULL
;
95 IoState_setCurrentCoroutine_(self
, self
->mainCoroutine
);
97 seqProto
= IoSeq_proto(self
);
99 IoState_setupQuickAccessSymbols(self
);
101 IoObject_rawSetProto_(seqProto
, self
->objectProto
);
103 cFunctionProto
= IoCFunction_proto(self
);
104 self
->localsUpdateSlotCFunc
= IoState_retain_(self
,
105 IoCFunction_newWithFunctionPointer_tag_name_(self
,
106 IoObject_localsUpdateSlot
, NULL
, "localsUpdate"));
108 IoSeq_protoFinish(seqProto
);
109 IoObject_protoFinish(self
);
110 IoCFunction_protoFinish(self
);
111 IoCoroutine_protoFinish(self
->mainCoroutine
);
113 self
->setSlotBlock
= IoState_retain_(self
, IoObject_getSlot_(self
->objectProto
, SIOSYMBOL("setSlot")));
118 IoObject
*objectProto
= self
->objectProto
;
119 IoObject
*protos
= IOCLONE(objectProto
);
120 IoObject
*core
= IOCLONE(objectProto
);
123 self
->lobby
= IOCLONE(objectProto
);
124 IoState_retain_(self
, self
->lobby
);
125 IoState_retain_(self
, self
->core
);
129 IoObject_setSlot_to_(self
->lobby
, SIOSYMBOL("Lobby"), self
->lobby
);
130 IoObject_setSlot_to_(self
->lobby
, SIOSYMBOL("Protos"), protos
);
131 IoObject_setSlot_to_(protos
, SIOSYMBOL("Core"), core
);
132 IoObject_setSlot_to_(protos
, SIOSYMBOL("Addons"), IOCLONE(objectProto
));
134 IoObject_setSlot_to_(core
, SIOSYMBOL("Compiler"), IoCompiler_proto(self
));
135 IoObject_setSlot_to_(core
, SIOSYMBOL("Collector"), IoCollector_proto(self
));
136 IoObject_setSlot_to_(core
, SIOSYMBOL("Exception"), IOCLONE(objectProto
));
140 IoObject_rawSetProto_(objectProto
, self
->lobby
);
141 IoObject_rawSetProto_(self
->lobby
, protos
);
142 IoObject_rawSetProto_(protos
, core
);
144 // add protos to namespace
146 IoObject_setSlot_to_(core
, SIOSYMBOL("Object"), objectProto
);
147 IoObject_setSlot_to_(core
, SIOSYMBOL("Sequence"), seqProto
);
148 IoObject_setSlot_to_(core
, SIOSYMBOL("Number"), IoNumber_proto(self
));
150 IoState_setupCachedNumbers(self
);
153 IoObject
*systemProto
= IoSystem_proto(self
);
154 IoObject_setSlot_to_(core
, SIOSYMBOL("System"), systemProto
);
157 IoState_setupSingletons(self
);
158 IoState_setupCachedMessages(self
);
161 self
->debugger
= IoState_retain_(self
, IoDebugger_proto(self
));
162 IoObject_setSlot_to_(core
, SIOSYMBOL("Debugger"), self
->debugger
);
164 self
->vmWillSendMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("vmWillSendMessage"));
165 IoMessage_cachedResult_(self
->nilMessage
, self
->ioNil
);
166 IoState_retain_(self
, self
->vmWillSendMessage
);
169 IoObject_setSlot_to_(core
, SIOSYMBOL("Block"), IoBlock_proto(self
));
170 IoObject_setSlot_to_(core
, SIOSYMBOL("List"), IoList_proto(self
));
171 IoObject_setSlot_to_(core
, SIOSYMBOL("Map"), IoMap_proto(self
));
172 //IoObject_setSlot_to_(core, SIOSYMBOL("Range"), IoRange_proto(self));
173 IoObject_setSlot_to_(core
, SIOSYMBOL("Coroutine"), self
->mainCoroutine
);
174 IoObject_setSlot_to_(core
, SIOSYMBOL("File"), IoFile_proto(self
));
175 IoObject_setSlot_to_(core
, SIOSYMBOL("Directory"), IoDirectory_proto(self
));
176 IoObject_setSlot_to_(core
, SIOSYMBOL("Date"), IoDate_proto(self
));
177 IoObject_setSlot_to_(core
, SIOSYMBOL("Duration"), IoDuration_proto(self
));
178 IoObject_setSlot_to_(core
, SIOSYMBOL("WeakLink"), IoWeakLink_proto(self
));
179 IoObject_setSlot_to_(core
, SIOSYMBOL("Sandbox"), IoSandbox_proto(self
));
180 //IoObject_setSlot_to_(core, SIOSYMBOL("EditLine"), IoEditLine_proto(self));
182 #if !defined(__SYMBIAN32__)
183 IoObject_setSlot_to_(core
, SIOSYMBOL("DynLib"), IoDynLib_proto(self
));
187 //IoObject_setSlot_to_(core, SIOSYMBOL("Store"), self->store);
188 IoObject_setSlot_to_(core
, SIOSYMBOL("CFunction"), cFunctionProto
);
190 self
->localsProto
= IoState_retain_(self
, IoObject_localsProto(self
));
191 IoObject_setSlot_to_(core
, SIOSYMBOL("Locals"), self
->localsProto
);
193 self
->stopStatus
= MESSAGE_STOP_STATUS_NORMAL
;
194 self
->returnValue
= self
->ioNil
;
196 IoState_clearRetainStack(self
);
198 IoState_popCollectorPause(self
);
200 //Collector_collect(self->collector);
202 //io_show_mem("before IoVMCodeInit");
205 //io_show_mem("after IoVMCodeInit");
206 //Collector_collect(self->collector);
207 //io_show_mem("after Collector_collect");
209 // IoState_popCollectorPause(self);
210 IoState_clearRetainStack(self
);
212 Collector_collect(self
->collector
);
213 //io_show_mem("after IoState_clearRetainStack and Collector_collect");
217 IoState
*IoState_new(void)
219 IoState
*self
= (IoState
*)io_calloc(1, sizeof(IoState
));
220 IoState_new_atAddress(self
);
224 void IoState_setupQuickAccessSymbols(IoState
*self
)
226 self
->activateSymbol
= IoState_retain_(self
, SIOSYMBOL("activate"));
227 self
->forwardSymbol
= IoState_retain_(self
, SIOSYMBOL("forward"));
228 self
->selfSymbol
= IoState_retain_(self
, SIOSYMBOL("self"));
229 self
->setSlotSymbol
= IoState_retain_(self
, SIOSYMBOL("setSlot"));
230 self
->setSlotWithTypeSymbol
= IoState_retain_(self
, SIOSYMBOL("setSlotWithType"));
231 self
->updateSlotSymbol
= IoState_retain_(self
, SIOSYMBOL("updateSlot"));
232 self
->callSymbol
= IoState_retain_(self
, SIOSYMBOL("call"));
233 self
->typeSymbol
= IoState_retain_(self
, SIOSYMBOL("type"));
234 self
->opShuffleSymbol
= IoState_retain_(self
, SIOSYMBOL("opShuffle"));
235 self
->noShufflingSymbol
= IoState_retain_(self
, SIOSYMBOL("__noShuffling__"));
236 self
->semicolonSymbol
= IoState_retain_(self
, SIOSYMBOL(";"));
237 self
->stackSizeSymbol
= IoState_retain_(self
, SIOSYMBOL("stackSize"));
240 void IoState_setupSingletons(IoState
*self
)
242 IoObject
*core
= self
->core
;
245 self
->ioNil
= IOCLONE(self
->objectProto
);
246 IoObject_setSlot_to_(core
, SIOSYMBOL("nil"), self
->ioNil
);
247 //IoObject_setSlot_to_(core, self->noShufflingSymbol, self->ioNil);
248 IoObject_setSlot_to_(core
, SIOSYMBOL("Message"), IoMessage_proto(self
));
249 IoObject_setSlot_to_(core
, SIOSYMBOL("Call"), IoCall_proto(self
));
251 self
->nilMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("nil"));
252 IoMessage_cachedResult_(self
->nilMessage
, self
->ioNil
);
253 IoState_retain_(self
, self
->nilMessage
);
257 self
->ioTrue
= IoObject_new(self
);
258 IoObject_setSlot_to_(core
, SIOSYMBOL("true"), self
->ioTrue
);
259 IoObject_setSlot_to_(self
->ioTrue
, SIOSYMBOL("type"), SIOSYMBOL("true"));
260 IoState_retain_(self
, self
->ioTrue
);
264 self
->ioFalse
= IoObject_new(self
);
265 IoObject_setSlot_to_(core
, SIOSYMBOL("false"), self
->ioFalse
);
266 IoObject_setSlot_to_(self
->ioFalse
, SIOSYMBOL("type"), SIOSYMBOL("false"));
267 IoState_retain_(self
, self
->ioFalse
);
269 // Flow control: Normal
270 self
->ioNormal
= IoObject_new(self
);
271 IoObject_setSlot_to_(core
, SIOSYMBOL("Normal"), self
->ioNormal
);
272 IoObject_setSlot_to_(self
->ioNormal
, SIOSYMBOL("type"), SIOSYMBOL("Normal"));
273 IoState_retain_(self
, self
->ioNormal
);
275 // Flow control: Break
276 self
->ioBreak
= IoObject_new(self
);
277 IoObject_setSlot_to_(core
, SIOSYMBOL("Break"), self
->ioBreak
);
278 IoObject_setSlot_to_(self
->ioBreak
, SIOSYMBOL("type"), SIOSYMBOL("Break"));
279 IoState_retain_(self
, self
->ioBreak
);
281 // Flow control: Continue
282 self
->ioContinue
= IoObject_new(self
);
283 IoObject_setSlot_to_(core
, SIOSYMBOL("Continue"), self
->ioContinue
);
284 IoObject_setSlot_to_(self
->ioContinue
, SIOSYMBOL("type"), SIOSYMBOL("Continue"));
285 IoState_retain_(self
, self
->ioContinue
);
287 // Flow control: Return
288 self
->ioReturn
= IoObject_new(self
);
289 IoObject_setSlot_to_(core
, SIOSYMBOL("Return"), self
->ioReturn
);
290 IoObject_setSlot_to_(self
->ioReturn
, SIOSYMBOL("type"), SIOSYMBOL("Return"));
291 IoState_retain_(self
, self
->ioReturn
);
294 self
->ioEol
= IoObject_new(self
);
295 IoObject_setSlot_to_(core
, SIOSYMBOL("Eol"), self
->ioEol
);
296 IoObject_setSlot_to_(self
->ioEol
, SIOSYMBOL("type"), SIOSYMBOL("Eol"));
297 IoState_retain_(self
, self
->ioEol
);
300 void IoState_setupCachedMessages(IoState
*self
)
302 self
->asStringMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("asString"));
303 IoState_retain_(self
, self
->asStringMessage
);
305 self
->collectedLinkMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("collectedLink"));
306 IoState_retain_(self
, self
->collectedLinkMessage
);
308 self
->compareMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("compare"));
309 IoState_retain_(self
, self
->compareMessage
);
311 //self->doStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("doString"));
312 //IoState_retain_(self, self->doStringMessage);
314 self
->printMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("print"));
315 IoState_retain_(self
, self
->printMessage
);
317 self
->initMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("init"));
318 IoState_retain_(self
, self
->initMessage
);
320 self
->willFreeMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("willFree"));
321 IoState_retain_(self
, self
->willFreeMessage
);
323 self
->runMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("run"));
324 IoState_retain_(self
, self
->runMessage
);
326 self
->mainMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("main"));
327 IoState_retain_(self
, self
->mainMessage
);
329 self
->opShuffleMessage
= IoMessage_newWithName_(self
, self
->opShuffleSymbol
);
330 IoState_retain_(self
, self
->opShuffleMessage
);
332 self
->yieldMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("yield"));
333 IoState_retain_(self
, self
->yieldMessage
);
336 IoObject
*IoObject_initBindings(IoObject
*self
, IoObject
*locals
, IoMessage
*m
)
338 IOSTATE
->bindingsInitCallback(IOSTATE
, self
);
342 void IoState_init(IoState
*self
)
344 if (self
->bindingsInitCallback
)
346 IoState_pushCollectorPause(self
);
347 self
->bindingsInitCallback(self
, self
->core
);
348 IoState_popCollectorPause(self
);
349 IoState_clearRetainStack(self
);
353 void IoState_registerProtoWithFunc_(IoState
*self
, IoObject
*proto
, IoStateProtoFunc
*func
)
355 if (PHash_at_(self
->primitives
, (void *)func
))
357 IoState_fatalError_(self
, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice");
360 IoState_retain_(self
, proto
);
361 PHash_at_put_(self
->primitives
, (void *)func
, proto
);
362 //printf("registered %s\n", IoObject_name(proto));
365 IoObject
*IoState_protoWithName_(IoState
*self
, const char *name
)
367 PHASH_FOREACH(self
->primitives
, key
, proto
, if (!strcmp(IoObject_name(proto
), name
)) { return proto
; });
371 List
*IoState_tagList(IoState
*self
) // caller must io_free returned List
373 List
*tags
= List_new();
374 PHASH_FOREACH(self
->primitives
, k
, proto
, List_append_(tags
, IoObject_tag((IoObject
*)proto
)));
378 void IoState_done(IoState
*self
)
380 // this should only be called from the main coro from outside of Io
382 List
*tags
= IoState_tagList(self
); // need to get the tags before we io_free the protos
384 self
->maxRecycledObjects
= 0;
386 Collector_freeAllValues(self
->collector
); // io_free all objects known to the collector
387 Collector_free(self
->collector
);
389 List_do_(tags
, (ListDoCallback
*)IoTag_free
);
392 PHash_free(self
->primitives
);
393 SHash_free(self
->symbols
);
395 LIST_DO_(self
->recycledObjects
, IoObject_dealloc
); // this doesn't work now that objects and marks are separate
396 List_free(self
->recycledObjects
);
397 List_free(self
->cachedNumbers
);
399 MainArgs_free(self
->mainArgs
);
402 void IoState_free(IoState
*self
)
408 IoObject
*IoState_lobby(IoState
*self
)
413 void IoState_setLobby_(IoState
*self
, IoObject
*obj
)
418 void MissingProtoError(void)
420 printf("missing proto\n");
423 IoObject
*IoState_protoWithInitFunction_(IoState
*self
, IoStateProtoFunc
*func
)
425 IoObject
*proto
= PHash_at_(self
->primitives
, (void *)func
);
427 //printf("IoState_protoWithInitFunction_(self, %p)\n", (void *)func);
431 //MissingProtoError();
432 printf("missing proto %p\n", (void *)func
);
434 IoState_fatalError_(self
, "IoState_protoWithInitFunction() Error: missing proto");
441 // command line ------------------------------------------------
443 void IoState_argc_argv_(IoState
*self
, int argc
, const char *argv
[])
445 IoList
*args
= IoList_new(self
);
448 for (i
= 1; i
< argc
; i
++)
450 IoList_rawAppend_(args
, SIOSYMBOL(argv
[i
]));
454 IoObject
*system
= IoObject_getSlot_(self
->lobby
, SIOSYMBOL("System"));
455 IoObject_setSlot_to_(system
, SIOSYMBOL("args"), args
);
458 MainArgs_argc_argv_(self
->mainArgs
, argc
, argv
);
461 // store -------------------------------------------------------
463 IoObject
*IoState_objectWithPid_(IoState
*self
, PID_TYPE pid
)
468 // doString -------------------------------------------------------
470 IoObject
*IoState_rawOn_doCString_withLabel_(IoState
*self
,
475 IoMessage
*m
= IoMessage_newFromText_label_(self
, s
, label
);
476 return IoMessage_locals_performOn_(m
, target
, target
);
479 // CLI ---------------------------------------------------------
481 void IoState_rawPrompt(IoState
*self
)
484 char *s
= io_calloc(1, max
);
489 fputs("Io> ", stdout
);
491 fgets(s
, max
, stdin
);
498 result
= IoState_rawOn_doCString_withLabel_(self
, self
->lobby
, s
, "IoState_rawPrompt()");
500 fputs("==> ", stdout
);
501 IoObject_print(result
);
508 void IoState_runCLI(IoState
*self
)
510 IoObject
*result
= IoState_on_doCString_withLabel_(self
, self
->lobby
, "CLI run", "IoState_runCLI()");
512 if (!self
->shouldExit
&& ISNUMBER(result
))
514 self
->exitResult
= CNUMBER(result
);
518 IOVM_API
int IoState_exitResult(IoState
*self
)
520 return self
->exitResult
;