2 docCopyright("Steve Dekorte", 2002)
3 docLicense("BSD revised")
12 #include "IoCoroutine.h"
15 #include "IoCFunction.h"
19 //#include "IoRange.h"
22 #include "IoDuration.h"
24 #include "IoMessage_parser.h"
26 #include "IoWeakLink.h"
29 #include "IoCompiler.h"
30 #include "IoDebugger.h"
31 #include "IoCollector.h"
32 #include "IoSandbox.h"
33 #include "IoDirectory.h"
34 #include "IoEditLine.h"
38 void IoVMCodeInit(IoObject
*context
);
40 void IoState_new_atAddress(void *address
)
42 IoState
*self
= (IoState
*)address
;
43 IoCFunction
*cFunctionProto
;
48 self
->collector
= Collector_new();
49 IoState_pushCollectorPause(self
);
51 Collector_setMarkFunc_(self
->collector
, (CollectorMarkFunc
*)IoObject_mark
);
52 Collector_setWillFreeFunc_(self
->collector
, (CollectorWillFreeFunc
*)IoObject_willFree
);
53 Collector_setFreeFunc_(self
->collector
, (CollectorFreeFunc
*)IoObject_free
);
55 self
->mainArgs
= MainArgs_new();
56 self
->primitives
= PHash_new();
58 self
->recycledObjects
= List_new();
59 self
->maxRecycledObjects
= IOSTATE_DEFAULT_MAX_RECYCLED_OBJECTS
;
63 self
->messageCount
= 0;
64 self
->messageCountLimit
= 0;
69 self
->symbols
= SHash_new();
71 SHash_setKeysEqualCallback(self
->symbols
, (SHashKeysEqualCallback
*)UArray_equalsWithHashCheck_
);
72 SHash_setHashForKeyCallback(self
->symbols
, (SHashHashforKeyCallback
*)UArray_hash
);
76 - there are some interdependencies here:
77 - creating instances requires a retain stack
78 - we need a Coroutine to use for our retainStack
79 - defining any primitive methods requires Strings and CFunctions
82 - create a temporary fake stack
83 - create Object, CFunction and String protos sans methods.
84 - then add methods to Object, CFunction and String
87 self
->currentIoStack
= Stack_new(); // temp retain stack until coro is up
89 self
->objectProto
= IoObject_proto(self
); // need to do this first, so we have a retain stack
90 //IoState_retain_(self, self->objectProto);
92 self
->mainCoroutine
= IoCoroutine_proto(self
);
93 Stack_free(self
->currentIoStack
);
94 self
->currentIoStack
= NULL
;
96 IoState_setCurrentCoroutine_(self
, self
->mainCoroutine
);
98 seqProto
= IoSeq_proto(self
);
100 IoState_setupQuickAccessSymbols(self
);
102 IoObject_rawSetProto_(seqProto
, self
->objectProto
);
104 cFunctionProto
= IoCFunction_proto(self
);
105 self
->localsUpdateSlotCFunc
= IoState_retain_(self
,
106 IoCFunction_newWithFunctionPointer_tag_name_(self
,
107 IoObject_localsUpdateSlot
, NULL
, "localsUpdate"));
109 IoSeq_protoFinish(seqProto
);
110 IoObject_protoFinish(self
);
111 IoCFunction_protoFinish(self
);
112 IoCoroutine_protoFinish(self
->mainCoroutine
);
114 self
->setSlotBlock
= IoState_retain_(self
, IoObject_getSlot_(self
->objectProto
, SIOSYMBOL("setSlot")));
119 IoObject
*objectProto
= self
->objectProto
;
120 IoObject
*protos
= IOCLONE(objectProto
);
121 IoObject
*core
= IOCLONE(objectProto
);
124 self
->lobby
= IOCLONE(objectProto
);
125 IoState_retain_(self
, self
->lobby
);
126 IoState_retain_(self
, self
->core
);
130 IoObject_setSlot_to_(self
->lobby
, SIOSYMBOL("Lobby"), self
->lobby
);
131 IoObject_setSlot_to_(self
->lobby
, SIOSYMBOL("Protos"), protos
);
132 IoObject_setSlot_to_(protos
, SIOSYMBOL("Core"), core
);
133 IoObject_setSlot_to_(protos
, SIOSYMBOL("Addons"), IOCLONE(objectProto
));
135 IoObject_setSlot_to_(core
, SIOSYMBOL("Compiler"), IoCompiler_proto(self
));
136 IoObject_setSlot_to_(core
, SIOSYMBOL("Collector"), IoCollector_proto(self
));
137 IoObject_setSlot_to_(core
, SIOSYMBOL("Exception"), IOCLONE(objectProto
));
141 IoObject_rawSetProto_(objectProto
, self
->lobby
);
142 IoObject_rawSetProto_(self
->lobby
, protos
);
143 IoObject_rawSetProto_(protos
, core
);
145 // add protos to namespace
147 IoObject_setSlot_to_(core
, SIOSYMBOL("Object"), objectProto
);
148 IoObject_setSlot_to_(core
, SIOSYMBOL("Sequence"), seqProto
);
149 IoObject_setSlot_to_(core
, SIOSYMBOL("Number"), IoNumber_proto(self
));
151 IoState_setupCachedNumbers(self
);
154 IoObject
*systemProto
= IoSystem_proto(self
);
155 IoObject_setSlot_to_(core
, SIOSYMBOL("System"), systemProto
);
158 IoState_setupSingletons(self
);
159 IoState_setupCachedMessages(self
);
162 self
->debugger
= IoState_retain_(self
, IoDebugger_proto(self
));
163 IoObject_setSlot_to_(core
, SIOSYMBOL("Debugger"), self
->debugger
);
165 self
->vmWillSendMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("vmWillSendMessage"));
166 IoMessage_cachedResult_(self
->nilMessage
, self
->ioNil
);
167 IoState_retain_(self
, self
->vmWillSendMessage
);
170 IoObject_setSlot_to_(core
, SIOSYMBOL("Block"), IoBlock_proto(self
));
171 IoObject_setSlot_to_(core
, SIOSYMBOL("List"), IoList_proto(self
));
172 IoObject_setSlot_to_(core
, SIOSYMBOL("Map"), IoMap_proto(self
));
173 //IoObject_setSlot_to_(core, SIOSYMBOL("Range"), IoRange_proto(self));
174 IoObject_setSlot_to_(core
, SIOSYMBOL("Coroutine"), self
->mainCoroutine
);
175 IoObject_setSlot_to_(core
, SIOSYMBOL("File"), IoFile_proto(self
));
176 IoObject_setSlot_to_(core
, SIOSYMBOL("Directory"), IoDirectory_proto(self
));
177 IoObject_setSlot_to_(core
, SIOSYMBOL("Date"), IoDate_proto(self
));
178 IoObject_setSlot_to_(core
, SIOSYMBOL("Duration"), IoDuration_proto(self
));
179 IoObject_setSlot_to_(core
, SIOSYMBOL("WeakLink"), IoWeakLink_proto(self
));
180 IoObject_setSlot_to_(core
, SIOSYMBOL("Sandbox"), IoSandbox_proto(self
));
181 IoObject_setSlot_to_(core
, SIOSYMBOL("EditLine"), IoEditLine_proto(self
));
183 #if !defined(__SYMBIAN32__)
184 IoObject_setSlot_to_(core
, SIOSYMBOL("DynLib"), IoDynLib_proto(self
));
188 //IoObject_setSlot_to_(core, SIOSYMBOL("Store"), self->store);
189 IoObject_setSlot_to_(core
, SIOSYMBOL("CFunction"), cFunctionProto
);
191 self
->localsProto
= IoState_retain_(self
, IoObject_localsProto(self
));
192 IoObject_setSlot_to_(core
, SIOSYMBOL("Locals"), self
->localsProto
);
194 self
->stopStatus
= MESSAGE_STOP_STATUS_NORMAL
;
195 self
->returnValue
= self
->ioNil
;
197 IoState_clearRetainStack(self
);
199 IoState_popCollectorPause(self
);
201 //Collector_collect(self->collector);
203 //io_show_mem("before IoVMCodeInit");
206 //io_show_mem("after IoVMCodeInit");
207 //Collector_collect(self->collector);
208 //io_show_mem("after Collector_collect");
210 // IoState_popCollectorPause(self);
211 IoState_clearRetainStack(self
);
213 Collector_collect(self
->collector
);
214 //io_show_mem("after IoState_clearRetainStack and Collector_collect");
218 IoState
*IoState_new(void)
220 IoState
*self
= (IoState
*)io_calloc(1, sizeof(IoState
));
221 IoState_new_atAddress(self
);
225 void IoState_setupQuickAccessSymbols(IoState
*self
)
227 self
->activateSymbol
= IoState_retain_(self
, SIOSYMBOL("activate"));
228 self
->forwardSymbol
= IoState_retain_(self
, SIOSYMBOL("forward"));
229 self
->selfSymbol
= IoState_retain_(self
, SIOSYMBOL("self"));
230 self
->setSlotSymbol
= IoState_retain_(self
, SIOSYMBOL("setSlot"));
231 self
->setSlotWithTypeSymbol
= IoState_retain_(self
, SIOSYMBOL("setSlotWithType"));
232 self
->updateSlotSymbol
= IoState_retain_(self
, SIOSYMBOL("updateSlot"));
233 self
->callSymbol
= IoState_retain_(self
, SIOSYMBOL("call"));
234 self
->typeSymbol
= IoState_retain_(self
, SIOSYMBOL("type"));
235 self
->opShuffleSymbol
= IoState_retain_(self
, SIOSYMBOL("opShuffle"));
236 self
->noShufflingSymbol
= IoState_retain_(self
, SIOSYMBOL("__noShuffling__"));
237 self
->semicolonSymbol
= IoState_retain_(self
, SIOSYMBOL(";"));
238 self
->stackSizeSymbol
= IoState_retain_(self
, SIOSYMBOL("stackSize"));
241 void IoState_setupSingletons(IoState
*self
)
243 IoObject
*core
= self
->core
;
246 self
->ioNil
= IOCLONE(self
->objectProto
);
247 IoObject_setSlot_to_(core
, SIOSYMBOL("nil"), self
->ioNil
);
248 //IoObject_setSlot_to_(core, self->noShufflingSymbol, self->ioNil);
249 IoObject_setSlot_to_(core
, SIOSYMBOL("Message"), IoMessage_proto(self
));
250 IoObject_setSlot_to_(core
, SIOSYMBOL("Call"), IoCall_proto(self
));
252 self
->nilMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("nil"));
253 IoMessage_cachedResult_(self
->nilMessage
, self
->ioNil
);
254 IoState_retain_(self
, self
->nilMessage
);
258 self
->ioTrue
= IoObject_new(self
);
259 IoObject_setSlot_to_(core
, SIOSYMBOL("true"), self
->ioTrue
);
260 IoObject_setSlot_to_(self
->ioTrue
, SIOSYMBOL("type"), SIOSYMBOL("true"));
261 IoState_retain_(self
, self
->ioTrue
);
265 self
->ioFalse
= IoObject_new(self
);
266 IoObject_setSlot_to_(core
, SIOSYMBOL("false"), self
->ioFalse
);
267 IoObject_setSlot_to_(self
->ioFalse
, SIOSYMBOL("type"), SIOSYMBOL("false"));
268 IoState_retain_(self
, self
->ioFalse
);
270 // Flow control: Normal
271 self
->ioNormal
= IoObject_new(self
);
272 IoObject_setSlot_to_(core
, SIOSYMBOL("Normal"), self
->ioNormal
);
273 IoObject_setSlot_to_(self
->ioNormal
, SIOSYMBOL("type"), SIOSYMBOL("Normal"));
274 IoState_retain_(self
, self
->ioNormal
);
276 // Flow control: Break
277 self
->ioBreak
= IoObject_new(self
);
278 IoObject_setSlot_to_(core
, SIOSYMBOL("Break"), self
->ioBreak
);
279 IoObject_setSlot_to_(self
->ioBreak
, SIOSYMBOL("type"), SIOSYMBOL("Break"));
280 IoState_retain_(self
, self
->ioBreak
);
282 // Flow control: Continue
283 self
->ioContinue
= IoObject_new(self
);
284 IoObject_setSlot_to_(core
, SIOSYMBOL("Continue"), self
->ioContinue
);
285 IoObject_setSlot_to_(self
->ioContinue
, SIOSYMBOL("type"), SIOSYMBOL("Continue"));
286 IoState_retain_(self
, self
->ioContinue
);
288 // Flow control: Return
289 self
->ioReturn
= IoObject_new(self
);
290 IoObject_setSlot_to_(core
, SIOSYMBOL("Return"), self
->ioReturn
);
291 IoObject_setSlot_to_(self
->ioReturn
, SIOSYMBOL("type"), SIOSYMBOL("Return"));
292 IoState_retain_(self
, self
->ioReturn
);
295 self
->ioEol
= IoObject_new(self
);
296 IoObject_setSlot_to_(core
, SIOSYMBOL("Eol"), self
->ioEol
);
297 IoObject_setSlot_to_(self
->ioEol
, SIOSYMBOL("type"), SIOSYMBOL("Eol"));
298 IoState_retain_(self
, self
->ioEol
);
301 void IoState_setupCachedMessages(IoState
*self
)
303 self
->collectedLinkMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("collectedLink"));
304 IoState_retain_(self
, self
->collectedLinkMessage
);
306 self
->printMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("print"));
307 IoState_retain_(self
, self
->printMessage
);
309 self
->initMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("init"));
310 IoState_retain_(self
, self
->initMessage
);
312 self
->compareMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("compare"));
313 IoState_retain_(self
, self
->compareMessage
);
315 self
->willFreeMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("willFree"));
316 IoState_retain_(self
, self
->willFreeMessage
);
318 self
->runMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("run"));
319 IoState_retain_(self
, self
->runMessage
);
321 self
->mainMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("main"));
322 IoState_retain_(self
, self
->mainMessage
);
324 self
->opShuffleMessage
= IoMessage_newWithName_(self
, self
->opShuffleSymbol
);
325 IoState_retain_(self
, self
->opShuffleMessage
);
327 self
->yieldMessage
= IoMessage_newWithName_(self
, SIOSYMBOL("yield"));
328 IoState_retain_(self
, self
->yieldMessage
);
331 IoObject
*IoObject_initBindings(IoObject
*self
, IoObject
*locals
, IoMessage
*m
)
333 IOSTATE
->bindingsInitCallback(IOSTATE
, self
);
337 void IoState_init(IoState
*self
)
339 if (self
->bindingsInitCallback
)
341 IoState_pushCollectorPause(self
);
342 self
->bindingsInitCallback(self
, self
->core
);
343 IoState_popCollectorPause(self
);
344 IoState_clearRetainStack(self
);
348 void IoState_registerProtoWithFunc_(IoState
*self
, IoObject
*proto
, IoStateProtoFunc
*func
)
350 if (PHash_at_(self
->primitives
, (void *)func
))
352 IoState_fatalError_(self
, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice");
355 IoState_retain_(self
, proto
);
356 PHash_at_put_(self
->primitives
, (void *)func
, proto
);
357 //printf("registered %s\n", IoObject_name(proto));
360 IoObject
*IoState_protoWithName_(IoState
*self
, const char *name
)
362 PHASH_FOREACH(self
->primitives
, key
, proto
, if (!strcmp(IoObject_name(proto
), name
)) { return proto
; });
366 List
*IoState_tagList(IoState
*self
) // caller must io_free returned List
368 List
*tags
= List_new();
369 PHASH_FOREACH(self
->primitives
, k
, proto
, List_append_(tags
, IoObject_tag((IoObject
*)proto
)));
373 void IoState_done(IoState
*self
)
375 // this should only be called from the main coro from outside of Io
377 List
*tags
= IoState_tagList(self
); // need to get the tags before we io_free the protos
379 self
->maxRecycledObjects
= 0;
381 Collector_freeAllValues(self
->collector
); // io_free all objects known to the collector
382 Collector_free(self
->collector
);
384 List_do_(tags
, (ListDoCallback
*)IoTag_free
);
387 PHash_free(self
->primitives
);
388 SHash_free(self
->symbols
);
390 LIST_DO_(self
->recycledObjects
, IoObject_dealloc
); // this doesn't work now that objects and marks are separate
391 List_free(self
->recycledObjects
);
392 List_free(self
->cachedNumbers
);
394 MainArgs_free(self
->mainArgs
);
397 void IoState_free(IoState
*self
)
403 IoObject
*IoState_lobby(IoState
*self
)
408 void IoState_setLobby_(IoState
*self
, IoObject
*obj
)
413 void MissingProtoError(void)
415 printf("missing proto\n");
418 IoObject
*IoState_protoWithInitFunction_(IoState
*self
, IoStateProtoFunc
*func
)
420 IoObject
*proto
= PHash_at_(self
->primitives
, (void *)func
);
422 //printf("IoState_protoWithInitFunction_(self, %p)\n", (void *)func);
426 //MissingProtoError();
427 printf("missing proto %p\n", (void *)func
);
429 IoState_fatalError_(self
, "IoState_protoWithInitFunction() Error: missing proto");
436 // command line ------------------------------------------------
438 void IoState_argc_argv_(IoState
*self
, int argc
, const char *argv
[])
440 IoList
*args
= IoList_new(self
);
443 for (i
= 1; i
< argc
; i
++)
445 IoList_rawAppend_(args
, SIOSYMBOL(argv
[i
]));
449 IoObject
*system
= IoObject_getSlot_(self
->lobby
, SIOSYMBOL("System"));
450 IoObject_setSlot_to_(system
, SIOSYMBOL("args"), args
);
453 MainArgs_argc_argv_(self
->mainArgs
, argc
, argv
);
456 // store -------------------------------------------------------
458 IoObject
*IoState_objectWithPid_(IoState
*self
, PID_TYPE pid
)
463 // doString -------------------------------------------------------
465 IoObject
*IoState_rawOn_doCString_withLabel_(IoState
*self
,
470 IoMessage
*m
= IoMessage_newFromText_label_(self
, s
, label
);
471 return IoMessage_locals_performOn_(m
, target
, target
);
474 // CLI ---------------------------------------------------------
476 void IoState_rawPrompt(IoState
*self
)
479 char *s
= io_calloc(1, max
);
484 fputs("Io> ", stdout
);
486 fgets(s
, max
, stdin
);
493 result
= IoState_rawOn_doCString_withLabel_(self
, self
->lobby
, s
, "IoState_rawPrompt()");
495 fputs("==> ", stdout
);
496 IoObject_print(result
);
503 void IoState_runCLI(IoState
*self
)
505 IoObject
*result
= IoState_on_doCString_withLabel_(self
, self
->lobby
, "CLI run", "IoState_runCLI()");
507 if (!self
->shouldExit
&& ISNUMBER(result
))
509 self
->exitResult
= CNUMBER(result
);
513 IOVM_API
int IoState_exitResult(IoState
*self
)
515 return self
->exitResult
;