Mercurial > projects > dmdscript-tango
comparison dmdscript_tango/dobject.d @ 0:55c2951c07be
initial, files origin, premoved tree
author | saaadel |
---|---|
date | Sun, 24 Jan 2010 12:34:47 +0200 |
parents | |
children | 8363a4bf6a8f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:55c2951c07be |
---|---|
1 | |
2 /* Digital Mars DMDScript source code. | |
3 * Copyright (c) 2000-2002 by Chromium Communications | |
4 * D version Copyright (c) 2004-2006 by Digital Mars | |
5 * All Rights Reserved | |
6 * written by Walter Bright | |
7 * www.digitalmars.com | |
8 * Use at your own risk. There is no warranty, express or implied. | |
9 * License for redistribution is by the GNU General Public License in gpl.txt. | |
10 * | |
11 * A binary, non-exclusive license for commercial use can be | |
12 * purchased from www.digitalmars.com/dscript/buy.html. | |
13 * | |
14 * DMDScript is implemented in the D Programming Language, | |
15 * www.digitalmars.com/d/ | |
16 * | |
17 * For a C++ implementation of DMDScript, including COM support, | |
18 * see www.digitalmars.com/dscript/cppscript.html. | |
19 */ | |
20 | |
21 | |
22 module dmdscript.dobject; | |
23 | |
24 import std.string; | |
25 import std.c.stdarg; | |
26 import std.c.string; | |
27 | |
28 import dmdscript.script; | |
29 import dmdscript.value; | |
30 import dmdscript.dfunction; | |
31 import dmdscript.property; | |
32 import dmdscript.threadcontext; | |
33 import dmdscript.iterator; | |
34 import dmdscript.identifier; | |
35 import dmdscript.errmsgs; | |
36 import dmdscript.text; | |
37 import dmdscript.program; | |
38 | |
39 import dmdscript.dboolean; | |
40 import dmdscript.dstring; | |
41 import dmdscript.dnumber; | |
42 import dmdscript.darray; | |
43 import dmdscript.dmath; | |
44 import dmdscript.ddate; | |
45 import dmdscript.dregexp; | |
46 import dmdscript.derror; | |
47 import dmdscript.dnative; | |
48 | |
49 import dmdscript.protoerror; | |
50 int* pfoo = &dmdscript.protoerror.foo; // link it in | |
51 | |
52 | |
53 //debug = LOG; | |
54 | |
55 /************************** Dobject_constructor *************************/ | |
56 | |
57 class Dobject_constructor : Dfunction | |
58 { | |
59 this(ThreadContext *tc) | |
60 { | |
61 super(1, tc.Dfunction_prototype); | |
62 if (tc.Dobject_prototype) | |
63 Put(TEXT_prototype, tc.Dobject_prototype, DontEnum | DontDelete | ReadOnly); | |
64 } | |
65 | |
66 void *Construct(CallContext *cc, Value *ret, Value[] arglist) | |
67 { Dobject o; | |
68 Value* v; | |
69 | |
70 // ECMA 15.2.2 | |
71 if (arglist.length == 0) | |
72 { | |
73 o = new Dobject(Dobject.getPrototype()); | |
74 } | |
75 else | |
76 { | |
77 v = &arglist[0]; | |
78 if (v.isPrimitive()) | |
79 { | |
80 if (v.isUndefinedOrNull()) | |
81 { | |
82 o = new Dobject(Dobject.getPrototype()); | |
83 } | |
84 else | |
85 o = v.toObject(); | |
86 } | |
87 else | |
88 o = v.toObject(); | |
89 } | |
90 //printf("constructed object o=%p, v=%p,'%s'\n", o, v,v.getType()); | |
91 ret.putVobject(o); | |
92 return null; | |
93 } | |
94 | |
95 void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) | |
96 { Dobject o; | |
97 void *result; | |
98 | |
99 // ECMA 15.2.1 | |
100 if (arglist.length == 0) | |
101 { | |
102 result = Construct(cc, ret, arglist); | |
103 } | |
104 else | |
105 { Value* v; | |
106 | |
107 v = &arglist[0]; | |
108 if (v.isUndefinedOrNull()) | |
109 result = Construct(cc, ret, arglist); | |
110 else | |
111 { | |
112 o = v.toObject(); | |
113 ret.putVobject(o); | |
114 result = null; | |
115 } | |
116 } | |
117 return result; | |
118 } | |
119 } | |
120 | |
121 | |
122 /* ===================== Dobject_prototype_toString ================ */ | |
123 | |
124 void* Dobject_prototype_toString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
125 { | |
126 d_string s; | |
127 d_string string; | |
128 | |
129 //debug (LOG) writef("Dobject.prototype.toString(ret = %x)\n", ret); | |
130 | |
131 s = othis.classname; | |
132 /+ | |
133 // Should we do [object] or [object Object]? | |
134 if (s == TEXT_Object) | |
135 string = TEXT_bobjectb; | |
136 else | |
137 +/ | |
138 string = std.string.format("[object %s]", s); | |
139 ret.putVstring(string); | |
140 return null; | |
141 } | |
142 | |
143 /* ===================== Dobject_prototype_toLocaleString ================ */ | |
144 | |
145 void* Dobject_prototype_toLocaleString(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
146 { | |
147 // ECMA v3 15.2.4.3 | |
148 // "This function returns the result of calling toString()." | |
149 | |
150 Value* v; | |
151 | |
152 //writef("Dobject.prototype.toLocaleString(ret = %x)\n", ret); | |
153 v = othis.Get(TEXT_toString); | |
154 if (v && !v.isPrimitive()) // if it's an Object | |
155 { void *a; | |
156 Dobject o; | |
157 | |
158 o = v.object; | |
159 a = o.Call(cc, othis, ret, arglist); | |
160 if (a) // if exception was thrown | |
161 return a; | |
162 } | |
163 return null; | |
164 } | |
165 | |
166 /* ===================== Dobject_prototype_valueOf ================ */ | |
167 | |
168 void* Dobject_prototype_valueOf(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
169 { | |
170 ret.putVobject(othis); | |
171 return null; | |
172 } | |
173 | |
174 /* ===================== Dobject_prototype_toSource ================ */ | |
175 | |
176 void* Dobject_prototype_toSource(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
177 { | |
178 tchar[] buf; | |
179 int any; | |
180 | |
181 //writef("Dobject.prototype.toSource(this = %p, ret = %p)\n", this, ret); | |
182 | |
183 buf = "{"; | |
184 any = 0; | |
185 foreach (Value key, Property p; *othis.proptable) | |
186 { | |
187 if (!(p.attributes & (DontEnum | Deleted))) | |
188 { | |
189 if (any) | |
190 buf ~= ','; | |
191 any = 1; | |
192 buf ~= key.toString(); | |
193 buf ~= ':'; | |
194 buf ~= p.value.toSource(); | |
195 } | |
196 } | |
197 buf ~= '}'; | |
198 ret.putVstring(buf); | |
199 return null; | |
200 } | |
201 | |
202 /* ===================== Dobject_prototype_hasOwnProperty ================ */ | |
203 | |
204 void* Dobject_prototype_hasOwnProperty(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
205 { | |
206 // ECMA v3 15.2.4.5 | |
207 Value* v; | |
208 | |
209 v = arglist.length ? &arglist[0] : &vundefined; | |
210 ret.putVboolean(othis.proptable.hasownproperty(v, 0)); | |
211 return null; | |
212 } | |
213 | |
214 /* ===================== Dobject_prototype_isPrototypeOf ================ */ | |
215 | |
216 void* Dobject_prototype_isPrototypeOf(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
217 { | |
218 // ECMA v3 15.2.4.6 | |
219 d_boolean result = false; | |
220 Value* v; | |
221 Dobject o; | |
222 | |
223 v = arglist.length ? &arglist[0] : &vundefined; | |
224 if (!v.isPrimitive()) | |
225 { | |
226 o = v.toObject(); | |
227 for (;;) | |
228 { | |
229 o = o.internal_prototype; | |
230 if (!o) | |
231 break; | |
232 if (o == othis) | |
233 { result = true; | |
234 break; | |
235 } | |
236 } | |
237 } | |
238 | |
239 ret.putVboolean(result); | |
240 return null; | |
241 } | |
242 | |
243 /* ===================== Dobject_prototype_propertyIsEnumerable ================ */ | |
244 | |
245 void* Dobject_prototype_propertyIsEnumerable(Dobject pthis, CallContext *cc, Dobject othis, Value *ret, Value[] arglist) | |
246 { | |
247 // ECMA v3 15.2.4.7 | |
248 Value* v; | |
249 | |
250 v = arglist.length ? &arglist[0] : &vundefined; | |
251 ret.putVboolean(othis.proptable.hasownproperty(v, 1)); | |
252 return null; | |
253 } | |
254 | |
255 /* ===================== Dobject_prototype ========================= */ | |
256 | |
257 class Dobject_prototype : Dobject | |
258 { | |
259 this(ThreadContext *tc) | |
260 { | |
261 super(null); | |
262 } | |
263 } | |
264 | |
265 | |
266 /* ====================== Dobject ======================= */ | |
267 | |
268 class Dobject | |
269 { | |
270 PropTable* proptable; | |
271 Dobject internal_prototype; | |
272 d_string classname; | |
273 Value value; | |
274 | |
275 const uint DOBJECT_SIGNATURE = 0xAA31EE31; | |
276 uint signature; | |
277 | |
278 invariant | |
279 { | |
280 assert(signature == DOBJECT_SIGNATURE); | |
281 } | |
282 | |
283 this(Dobject prototype) | |
284 { | |
285 //writef("new Dobject = %x, prototype = %x, line = %d, file = '%s'\n", this, prototype, GC.line, ascii2unicode(GC.file)); | |
286 //writef("Dobject(prototype = %p)\n", prototype); | |
287 proptable = new PropTable; | |
288 internal_prototype = prototype; | |
289 if (prototype) | |
290 proptable.previous = prototype.proptable; | |
291 classname = TEXT_Object; | |
292 value.putVobject(this); | |
293 | |
294 signature = DOBJECT_SIGNATURE; | |
295 } | |
296 | |
297 Dobject Prototype() | |
298 { | |
299 return internal_prototype; | |
300 } | |
301 | |
302 Value* Get(d_string PropertyName) | |
303 { | |
304 return Get(PropertyName, Value.calcHash(PropertyName)); | |
305 } | |
306 | |
307 Value* Get(Identifier* id) | |
308 { | |
309 Value* v; | |
310 | |
311 //writefln("Dobject.Get(this = %x, '%s', hash = %x)", cast(uint)cast(void*)this, PropertyName, hash); | |
312 //writef("\tinternal_prototype = %p\n", this.internal_prototype); | |
313 //writef("\tDfunction.getPrototype() = %p\n", Dfunction.getPrototype()); | |
314 v = proptable.get(&id.value, id.value.hash); | |
315 //if (v) writef("found it %p\n", v.object); | |
316 return v; | |
317 } | |
318 | |
319 Value* Get(d_string PropertyName, uint hash) | |
320 { | |
321 Value* v; | |
322 | |
323 //writefln("Dobject.Get(this = %x, '%s', hash = %x)", cast(uint)cast(void*)this, PropertyName, hash); | |
324 //writef("\tinternal_prototype = %p\n", this.internal_prototype); | |
325 //writef("\tDfunction.getPrototype() = %p\n", Dfunction.getPrototype()); | |
326 v = proptable.get(PropertyName, hash); | |
327 //if (v) writef("found it %p\n", v.object); | |
328 return v; | |
329 } | |
330 | |
331 Value* Get(d_uint32 index) | |
332 { | |
333 Value* v; | |
334 | |
335 v = proptable.get(index); | |
336 // if (!v) | |
337 // v = &vundefined; | |
338 return v; | |
339 } | |
340 | |
341 Value* Get(d_uint32 index, Value* vindex) | |
342 { | |
343 return proptable.get(vindex, Value.calcHash(index)); | |
344 } | |
345 | |
346 Value* Put(d_string PropertyName, Value* value, uint attributes) | |
347 { | |
348 // ECMA 8.6.2.2 | |
349 //writef("Dobject.Put(this = %p)\n", this); | |
350 proptable.put(PropertyName, value, attributes); | |
351 return null; | |
352 } | |
353 | |
354 Value* Put(Identifier* key, Value* value, uint attributes) | |
355 { | |
356 // ECMA 8.6.2.2 | |
357 //writef("Dobject.Put(this = %p)\n", this); | |
358 proptable.put(&key.value, key.value.hash, value, attributes); | |
359 return null; | |
360 } | |
361 | |
362 Value* Put(d_string PropertyName, Dobject o, uint attributes) | |
363 { | |
364 // ECMA 8.6.2.2 | |
365 Value v; | |
366 v.putVobject(o); | |
367 | |
368 proptable.put(PropertyName, &v, attributes); | |
369 return null; | |
370 } | |
371 | |
372 Value* Put(d_string PropertyName, d_number n, uint attributes) | |
373 { | |
374 // ECMA 8.6.2.2 | |
375 Value v; | |
376 v.putVnumber(n); | |
377 | |
378 proptable.put(PropertyName, &v, attributes); | |
379 return null; | |
380 } | |
381 | |
382 Value* Put(d_string PropertyName, d_string s, uint attributes) | |
383 { | |
384 // ECMA 8.6.2.2 | |
385 Value v; | |
386 v.putVstring(s); | |
387 | |
388 proptable.put(PropertyName, &v, attributes); | |
389 return null; | |
390 } | |
391 | |
392 Value* Put(d_uint32 index, Value* vindex, Value* value, uint attributes) | |
393 { | |
394 // ECMA 8.6.2.2 | |
395 proptable.put(vindex, Value.calcHash(index), value, attributes); | |
396 return null; | |
397 } | |
398 | |
399 Value* Put(d_uint32 index, Value* value, uint attributes) | |
400 { | |
401 // ECMA 8.6.2.2 | |
402 proptable.put(index, value, attributes); | |
403 return null; | |
404 } | |
405 | |
406 Value* PutDefault(Value* value) | |
407 { | |
408 // Not ECMA, Microsoft extension | |
409 //writef("Dobject.PutDefault(this = %p)\n", this); | |
410 ErrInfo errinfo; | |
411 return RuntimeError(&errinfo, ERR_NO_DEFAULT_PUT); | |
412 } | |
413 | |
414 Value* put_Value(Value* ret, Value[] arglist) | |
415 { | |
416 // Not ECMA, Microsoft extension | |
417 //writef("Dobject.put_Value(this = %p)\n", this); | |
418 ErrInfo errinfo; | |
419 return RuntimeError(&errinfo, ERR_FUNCTION_NOT_LVALUE); | |
420 } | |
421 | |
422 int CanPut(d_string PropertyName) | |
423 { | |
424 // ECMA 8.6.2.3 | |
425 return proptable.canput(PropertyName); | |
426 } | |
427 | |
428 int HasProperty(d_string PropertyName) | |
429 { | |
430 // ECMA 8.6.2.4 | |
431 return proptable.hasproperty(PropertyName); | |
432 } | |
433 | |
434 /*********************************** | |
435 * Return: | |
436 * TRUE not found or successful delete | |
437 * FALSE property is marked with DontDelete attribute | |
438 */ | |
439 | |
440 int Delete(d_string PropertyName) | |
441 { | |
442 // ECMA 8.6.2.5 | |
443 //writef("Dobject.Delete('%ls')\n", d_string_ptr(PropertyName)); | |
444 return proptable.del(PropertyName); | |
445 } | |
446 | |
447 int Delete(d_uint32 index) | |
448 { | |
449 // ECMA 8.6.2.5 | |
450 return proptable.del(index); | |
451 } | |
452 | |
453 int implementsDelete() | |
454 { | |
455 // ECMA 8.6.2 says every object implements [[Delete]], | |
456 // but ECMA 11.4.1 says that some objects may not. | |
457 // Assume the former is correct. | |
458 return true; | |
459 } | |
460 | |
461 void *DefaultValue(Value* ret, tchar[] Hint) | |
462 { Dobject o; | |
463 Value* v; | |
464 static d_string*[2] table = [ &TEXT_toString, &TEXT_valueOf ]; | |
465 int i = 0; // initializer necessary for /W4 | |
466 | |
467 // ECMA 8.6.2.6 | |
468 //writef("Dobject.DefaultValue(ret = %x, Hint = '%s')\n", cast(uint)ret, Hint); | |
469 | |
470 if (Hint == TypeString || | |
471 (Hint == null && this.isDdate())) | |
472 { | |
473 i = 0; | |
474 } | |
475 else if (Hint == TypeNumber || | |
476 Hint == null) | |
477 { | |
478 i = 1; | |
479 } | |
480 else | |
481 assert(0); | |
482 | |
483 for (int j = 0; j < 2; j++) | |
484 { d_string htab = *table[i]; | |
485 | |
486 //writefln("\ti = %d, htab = '%s'", i, htab); | |
487 v = Get(htab, Value.calcHash(htab)); | |
488 //writefln("\tv = %x", cast(uint)v); | |
489 if (v && !v.isPrimitive()) // if it's an Object | |
490 { void *a; | |
491 CallContext *cc; | |
492 | |
493 //writefln("\tfound default value"); | |
494 o = v.object; | |
495 cc = Program.getProgram().callcontext; | |
496 a = o.Call(cc, this, ret, null); | |
497 if (a) // if exception was thrown | |
498 return a; | |
499 if (ret.isPrimitive()) | |
500 return null; | |
501 } | |
502 i ^= 1; | |
503 } | |
504 ret.putVstring(classname); | |
505 return null; | |
506 //ErrInfo errinfo; | |
507 //return RuntimeError(&errinfo, DTEXT("no Default Value for object")); | |
508 } | |
509 | |
510 void *Construct(CallContext *cc, Value *ret, Value[] arglist) | |
511 { ErrInfo errinfo; | |
512 return RuntimeError(&errinfo, errmsgtbl[ERR_S_NO_CONSTRUCT], classname); | |
513 } | |
514 | |
515 void *Call(CallContext *cc, Dobject othis, Value* ret, Value[] arglist) | |
516 { | |
517 ErrInfo errinfo; | |
518 return RuntimeError(&errinfo, errmsgtbl[ERR_S_NO_CALL], classname); | |
519 } | |
520 | |
521 void *HasInstance(Value* ret, Value* v) | |
522 { // ECMA v3 8.6.2 | |
523 ErrInfo errinfo; | |
524 return RuntimeError(&errinfo, errmsgtbl[ERR_S_NO_INSTANCE], classname); | |
525 } | |
526 | |
527 d_string getTypeof() | |
528 { // ECMA 11.4.3 | |
529 return TEXT_object; | |
530 } | |
531 | |
532 | |
533 int isClass(d_string classname) | |
534 { | |
535 return this.classname == classname; | |
536 } | |
537 | |
538 int isDarray() { return isClass(TEXT_Array); } | |
539 int isDdate() { return isClass(TEXT_Date); } | |
540 int isDregexp() { return isClass(TEXT_RegExp); } | |
541 | |
542 int isDarguments() { return false; } | |
543 int isCatch() { return false; } | |
544 int isFinally() { return false; } | |
545 | |
546 void getErrInfo(ErrInfo *perrinfo, int linnum) | |
547 { | |
548 ErrInfo errinfo; | |
549 Value v; | |
550 v.putVobject(this); | |
551 | |
552 errinfo.message = v.toString(); | |
553 if (perrinfo) | |
554 *perrinfo = errinfo; | |
555 } | |
556 | |
557 static Value* RuntimeError(ErrInfo *perrinfo, int msgnum) | |
558 { | |
559 return RuntimeError(perrinfo, errmsgtbl[msgnum]); | |
560 } | |
561 | |
562 static Value* RuntimeError(ErrInfo *perrinfo, ...) | |
563 { Dobject o; | |
564 | |
565 perrinfo.message = null; | |
566 | |
567 void putc(dchar c) | |
568 { | |
569 std.utf.encode(perrinfo.message, c); | |
570 } | |
571 | |
572 std.format.doFormat(&putc, _arguments, _argptr); | |
573 | |
574 o = new typeerror.D0(perrinfo); | |
575 Value* v = new Value; | |
576 v.putVobject(o); | |
577 return v; | |
578 } | |
579 | |
580 static Value* RangeError(ErrInfo *perrinfo, int msgnum) | |
581 { | |
582 return RangeError(perrinfo, errmsgtbl[msgnum]); | |
583 } | |
584 | |
585 static Value* RangeError(ErrInfo *perrinfo, ...) | |
586 { Dobject o; | |
587 | |
588 perrinfo.message = null; | |
589 | |
590 void putc(dchar c) | |
591 { | |
592 std.utf.encode(perrinfo.message, c); | |
593 } | |
594 | |
595 std.format.doFormat(&putc, _arguments, _argptr); | |
596 | |
597 o = new rangeerror.D0(perrinfo); | |
598 Value* v = new Value; | |
599 v.putVobject(o); | |
600 return v; | |
601 } | |
602 | |
603 Value* putIterator(Value* v) | |
604 { | |
605 Iterator* i = new Iterator; | |
606 | |
607 i.ctor(this); | |
608 v.putViterator(i); | |
609 return null; | |
610 } | |
611 | |
612 static Dfunction getConstructor() | |
613 { | |
614 ThreadContext *tc = ThreadContext.getThreadContext(); | |
615 assert(tc); | |
616 return tc.Dobject_constructor; | |
617 } | |
618 | |
619 static Dobject getPrototype() | |
620 { | |
621 ThreadContext *tc = ThreadContext.getThreadContext(); | |
622 assert(tc); | |
623 return tc.Dobject_prototype; | |
624 } | |
625 | |
626 static void init(ThreadContext *tc) | |
627 { | |
628 tc.Dobject_prototype = new Dobject_prototype(tc); | |
629 Dfunction.init(tc); | |
630 tc.Dobject_constructor = new Dobject_constructor(tc); | |
631 | |
632 Dobject op = tc.Dobject_prototype; | |
633 Dobject f = tc.Dfunction_prototype; | |
634 | |
635 op.Put(TEXT_constructor, tc.Dobject_constructor, DontEnum); | |
636 | |
637 static NativeFunctionData nfd[] = | |
638 [ | |
639 { &TEXT_toString, &Dobject_prototype_toString, 0 }, | |
640 { &TEXT_toLocaleString, &Dobject_prototype_toLocaleString, 0 }, | |
641 { &TEXT_toSource, &Dobject_prototype_toSource, 0 }, | |
642 { &TEXT_valueOf, &Dobject_prototype_valueOf, 0 }, | |
643 { &TEXT_hasOwnProperty, &Dobject_prototype_hasOwnProperty, 1 }, | |
644 { &TEXT_isPrototypeOf, &Dobject_prototype_isPrototypeOf, 0 }, | |
645 { &TEXT_propertyIsEnumerable, &Dobject_prototype_propertyIsEnumerable, 0 }, | |
646 ]; | |
647 | |
648 DnativeFunction.init(op, nfd, DontEnum); | |
649 } | |
650 } | |
651 | |
652 | |
653 /********************************************* | |
654 * Initialize the built-in's. | |
655 */ | |
656 | |
657 void dobject_init(ThreadContext *tc) | |
658 { | |
659 //writef("dobject_init(tc = %x)\n", cast(uint)tc); | |
660 if (tc.Dobject_prototype) | |
661 return; // already initialized for this thread | |
662 | |
663 version (none) | |
664 { | |
665 writef("sizeof(Dobject) = %d\n", sizeof(Dobject)); | |
666 writef("sizeof(PropTable) = %d\n", sizeof(PropTable)); | |
667 writef("offsetof(proptable) = %d\n", offsetof(Dobject, proptable)); | |
668 writef("offsetof(internal_prototype) = %d\n", offsetof(Dobject, internal_prototype)); | |
669 writef("offsetof(classname) = %d\n", offsetof(Dobject, classname)); | |
670 writef("offsetof(value) = %d\n", offsetof(Dobject, value)); | |
671 } | |
672 | |
673 Dobject.init(tc); | |
674 Dboolean.init(tc); | |
675 Dstring.init(tc); | |
676 Dnumber.init(tc); | |
677 Darray.init(tc); | |
678 Dmath.init(tc); | |
679 Ddate.init(tc); | |
680 Dregexp.init(tc); | |
681 Derror.init(tc); | |
682 | |
683 // Call registered initializer for each object type | |
684 foreach (void function(ThreadContext*) fpinit; ThreadContext.initTable) | |
685 (*fpinit)(tc); | |
686 } | |
687 | |
688 void dobject_term(ThreadContext *tc) | |
689 { | |
690 //writef("dobject_term(program = %x)\n", tc.program); | |
691 | |
692 memset(&tc.program, 0, ThreadContext.sizeof - Thread.sizeof); | |
693 } |