Develop and Download Open Source Software

Browse CVS Repository

Contents of /caraway/caraway/oop.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (as text) (vendor branch)
Tue Jan 24 07:38:06 2006 UTC (18 years, 2 months ago) by reno
Branch: MAIN, reno
CVS Tags: start, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/x-csrc
initial import into cvs

1 #include "caraway.h"
2
3 static OOP boot_defclass( char *name, OOP super, int fields );
4 static void cw_create_symbol_table( int count, OOP *classes );
5
6 static OOP boot_classes[20];
7 static char *boot_class_names[20];
8 static int boot_class_count = -1;
9
10 inline OOP cw_alloc_oop( unsigned long flags );
11 inline OOP cw_alloc_oop2();
12 inline OOP cw_new_instance( OOP klass, unsigned long fields );
13 inline OOP cw_new_instance( OOP klass, unsigned long fields );
14 inline OOP cw_new_instance2( OOP klass );
15
16 inline OOP cw_alloc_oop( unsigned long flags )
17 {
18 OOP oop;
19
20 oop = ALLOC(struct OOP);
21 oop->flags = flags;
22 oop->klass = 0;
23 oop->ptr.oops = 0;
24 return oop;
25 }
26
27 inline OOP cw_alloc_oop2()
28 {
29 return cw_alloc_oop(0);
30 }
31
32 inline OOP cw_new_instance( OOP klass, unsigned long fields )
33 {
34 OOP oop;
35
36 oop = cw_alloc_oop2();
37 oop->ptr.oops = ALLOC_N(OOP, fields);
38 return oop;
39 }
40
41 inline void cw_init_fields( OOP oop, long size )
42 {
43 int i, op;
44
45 oop->ptr.oops = ALLOC_N(OOP, size);
46 op = HAS_OPSIZE(oop);
47 for (i = 0; i < size; i++)
48 IV_SET(oop, op?i+1:i, Pnil);
49 }
50
51 void cw_init_dictionary()
52 {
53 //create_classes_pass1 ();
54 cw_init_proto_oops();
55
56 /*
57 init_smalltalk_dictionary ();
58
59 create_classes_pass2 ();
60
61 add_smalltalk ("KernelFilePath",
62 _gst_string_new (_gst_kernel_file_default_path));
63
64 init_runtime_objects ();
65
66 _gst_tenure_all_survivors ();
67 */
68 }
69
70 void cw_init_proto_oops()
71 {
72 OOP metaclass;
73
74 // まず・髟阡惨霙譽?薀垢涼羶箸魘?悩遒
75 // 巳苳餐阿魯轡鵐椒襪吠儡垢気譴襪????シンボルテ・踉札屮襪砲賄佻燭気譴覆
76 // クラスプロパティはSmalltalkで定義したときにセットする
77 CWObject = boot_defclass("Object", 0, Object_FIELD_SIZE);
78 CWBehavior = boot_defclass("Behavior", CWObject, Behavior_FIELD_SIZE);
79 CWClassDescription = boot_defclass("ClassDescription", CWBehavior,
80 ClassDescription_FIELD_SIZE);
81 CWClass = boot_defclass("Class", CWClassDescription, Class_FIELD_SIZE);
82 CWMetaclass = boot_defclass("Metaclass", CWClassDescription,
83 Metaclass_FIELD_SIZE);
84 CWMethodDictionary = boot_defclass("MethodDictionary", CWObject, 0);
85 CWString = boot_defclass("String", CWObject, 0);
86 CWByteString = boot_defclass("ByteString", CWString, 0);
87 CWSymbol = boot_defclass("Symbol", CWString, 0);
88 CWByteSymbol = boot_defclass("ByteSymbol", CWSymbol, 0);
89 CWArray = boot_defclass("Array", CWObject, 1);
90 CWMethodDictionary = boot_defclass("MethodDictionary", CWObject, 0);
91 CWNameSpace = boot_defclass("NameSpace", CWObject, Namespace_FIELD_SIZE);
92 CWNamedNameSpace = boot_defclass("NamedNameSpace", CWNameSpace,
93 NamedNamespace_FIELD_SIZE);
94 CWClassNameSpace = boot_defclass("ClassNameSpace", CWNameSpace,
95 ClassNamespace_FIELD_SIZE);
96 CWVariableBinding = boot_defclass("VariableBinding", CWObject,
97 VariableBinding_FIELD_SIZE);
98
99 // メタクラスを巳苳餐斡?屬離?薀好螢好箸謀佻
100 metaclass = cw_make_metaclass(CWObject, CWClass);
101 metaclass = cw_make_metaclass(CWBehavior, metaclass);
102 metaclass = cw_make_metaclass(CWClassDescription, metaclass);
103 cw_make_metaclass(CWClass, metaclass);
104 cw_make_metaclass(CWMetaclass, metaclass);
105
106 // ??,縫轡鵐椒襯董??ブルを生成
107 // シンボルテ・踉札屮襪鯀犧遒垢覺愎瑤鰺儖佞靴覆い
108 // う髟阡擦箸?WeakArrayに変換する
109 // シンボルテ・踉札屮襪寮言?紂???いままでのシンボルを登録する
110 // 同時に各シンボルのクラスをCWByteSymbolにセットする
111 cw_create_symbol_table(boot_class_count, boot_classes);
112
113 // ??,縫肇奪廛譽戰襪量??前空間を生成
114 // 生成後・髟阡札屐??トストラップのクラスを各巳苳餐斡?屬縫札奪箸垢
115 //cw_create_root_namespace();
116
117 //CWProcessor = cw_alloc_oop();
118
119 //printf("init proto oop completed. syms - %d\n", SML2INT(Array_tally(CWBootSymbols)));
120 }
121
122 static OOP boot_defclass( char *name, OOP super, int fields )
123 {
124 OOP oop;
125
126 oop = cw_class_boot(super, fields);
127 boot_classes[++boot_class_count] = oop;
128 boot_class_names[boot_class_count] = name;
129 return oop;
130 }
131
132 OOP cw_class_boot( OOP super, int fields )
133 {
134 if (super) {
135 /* adjust the number of instance variables to account for inheritance */
136 fields += FL_FIELD_SIZE(FORMAT(super));
137 Behavior_subclasses(super) = INT2SML(SML2INT(Behavior_subclasses(super)) + 1);
138 }
139
140 NEWOOP(klass);
141 INIT_FIELDS(klass, CLOOP_FIELD_SIZE); // class object fields
142 klass->flags = FL_PTR | CLOOP_FIELD_SIZE << FIELD_LSHIFT;
143 klass->klass = Pnil;
144 Behavior_superclass(klass) = super;
145 Behavior_format(klass) = INT2SML(fields << FIELD_LSHIFT-2);
146 Behavior_subclasses(klass) = INT2SML(0);
147 return klass;
148 }
149
150 char *cw_class_name( OOP klass )
151 {
152 return BYTESTR_PTR(Class_name(klass));
153 }
154
155 /*
156 * Metaclass world
157 *
158 * (name) ... metaclass
159 * ---> ... inherit relation
160 * ===> ... metaclass relation
161 *
162 *
163 * Object ===============> (Object)
164 * ^ ^
165 * | |
166 * Behavior =============> (Behavior)
167 * ^ ^
168 * | |
169 * ClassDescription =====> (ClassDescription)
170 * ^ ^ ^
171 * | | |
172 * | +-----------+ +-----------+
173 * | | |
174 * Class ===> (Class) Metaclass ===> (Metaclass)
175 * ^ ^
176 * | |
177 * Object ==========> (Object) ==================+
178 * ^ ^ |
179 * | | |
180 * OtherClass ===> (OtherClass) =================+
181 *
182 */
183 OOP cw_make_metaclass( OOP oop, OOP super )
184 {
185 OOP metasuper = NULL;
186 OOP klass;
187
188 klass = cw_class_boot(super, Metaclass_FIELD_SIZE);
189 oop->klass = klass;
190 metasuper = super->klass;
191 /* metaclass of a superclass may be NULL at boot time */
192 if (metasuper)
193 klass->klass = metasuper;
194 return klass;
195 }
196
197 static void cw_create_symbol_table( int count, OOP *classes )
198 {
199 OOP oop, sym;
200 int i;
201
202 CWBootSymbols = cw_array_new(100);
203 CWBootClasses = cw_array_new(30);
204 for (i = 0; i < count; i++) {
205 oop = classes[i];
206 sym = cw_boot_intern(boot_class_names[i]);
207 Class_name(oop) = sym;
208 cw_array_add(CWBootClasses, oop);
209 }
210 }
211
212 /*
213 static void cw_create_root_namespace()
214 {
215 CWRootNameSpace = cw_define_namespace();
216 core = cw_define_namespace(CWRootNameSpace);
217 }
218 */
219
220 /*
221 * Returns value of instance variable at index.
222 * If indexed type of the oop is bytes, returns a byte as SmallInteger.
223 */
224 OOP cw_iv_get( OOP oop, long index )
225 {
226 if (HAS_PTR(oop)) {
227 if (HAS_OPSIZE(oop))
228 index++;
229 return IV_GET(oop, FL_SP_FIELD_SIZE(oop) + index);
230 } else
231 return UINT2NUM(cw_byte_get(oop, index));
232 }
233
234 /*
235 * Sets the value for instance variable at index.
236 * If indexed type of the oop is bytes, sets the value as unsigned char.
237 */
238 void cw_iv_set( OOP oop, long index, OOP val )
239 {
240 if (HAS_PTR(oop)) {
241 if (HAS_OPSIZE(oop))
242 index++;
243 IV_SET(oop, FL_SP_FIELD_SIZE(oop) + index, val);
244 } else
245 cw_byte_set(oop, index, (unsigned char)NUM2UINT(val));
246 }
247
248 /*
249 * Returns value of indexed instance variable at index.
250 */
251 OOP cw_object_get( OOP oop, long index )
252 {
253 if (HAS_OPSIZE(oop))
254 index++;
255 return IV_GET(oop, FL_CL_FIELD_SIZE(oop) + index);
256 }
257
258 /*
259 * Sets the value for indexed instance variable at index.
260 */
261 void cw_object_set( OOP oop, long index, OOP val )
262 {
263 if (HAS_OPSIZE(oop))
264 index++;
265 IV_SET(oop, FL_CL_FIELD_SIZE(oop) + index, val);
266 }
267
268 /*
269 * Returns a byte of indexed instance variable at index.
270 */
271 unsigned char cw_byte_get( OOP oop, long index )
272 {
273 if (HAS_OPSIZE(oop))
274 index += SIZEOF_LONG;
275 return BYTE_GET(oop, index);
276 }
277
278 /*
279 * Sets the value for indexed instance variable at index.
280 */
281 void cw_byte_set( OOP oop, long index, unsigned char val )
282 {
283 if (HAS_OPSIZE(oop))
284 index += SIZEOF_LONG;
285 BYTE_SET(oop, index, val);
286 }
287
288 void cw_swap( OOP oop1, OOP oop2 )
289 {
290 struct OOP tmp;
291
292 tmp = *oop2;
293 *oop2 = *oop1;
294 *oop1 = tmp;
295 }
296
297 OOP cw_byte_string_new( const char *ptr, long len )
298 {
299 NEWOOP(str);
300 BYTESSETUP(str, CWByteString, 0, len);
301 if (HAS_OPSIZE(str))
302 memcpy(str->ptr.oops+1, ptr, len);
303 else
304 memcpy(str->ptr.oops, ptr, len);
305 return str;
306 }
307
308 OOP cw_byte_string_new2( const char *ptr )
309 {
310 return cw_byte_string_new(ptr, strlen(ptr));
311 }
312
313 int cw_byte_string_hash( OOP str )
314 {
315 int len, midLeft, midRight, nextToLast, firstc, mlc, mrc, nlc, lastc, hash;
316
317 len = FIELD_SIZE(str);
318 if (len == 0) {
319 hash = 0;
320 } else {
321 if (len == 1) {
322 midLeft = midRight = nextToLast = 1;
323 } else {
324 midLeft = len >> 1;
325 midRight = midLeft + 1;
326 nextToLast = len - 1;
327 }
328 firstc = cw_byte_get(str, 0);
329 mlc = cw_byte_get(str, midLeft-1);
330 mrc = cw_byte_get(str, midRight-1);
331 nlc = cw_byte_get(str, nextToLast-1);
332 lastc = cw_byte_get(str, len-1);
333 hash = mrc + (mrc + len << 8) +
334 ((firstc + nlc & 0x3fff) << 12) + (nlc << 2) +
335 ((lastc & 0x07ff) << 16) + (firstc + lastc << 4) +
336 ((mlc & 0xff) << 20) + (mlc << 6);
337 }
338 return hash;
339 }
340 /*
341 OOP cw_object_array_new( long size )
342 {
343 int i, op;
344
345 NEWOOP(ary);
346 IDXSETUP(ary, CWObjectArray, 0, size);
347 op = HAS_OPSIZE(ary);
348 for (i = 0; i < size; i++)
349 ary->ptr.oops[op?i+1:i] = Pnil;
350 return ary;
351 }
352 */
353 OOP cw_array_new( long size )
354 {
355 int i, op;
356
357 NEWOOP(ary);
358 IDXSETUP(ary, CWArray, FL_PTR, size);
359 op = HAS_OPSIZE(ary);
360 for (i = 0; i < size; i++)
361 ary->ptr.oops[op?i+1:i] = Pnil;
362 Array_tally(ary) = INT2SML(0);
363 return ary;
364 }
365
366 void cw_array_add( OOP ary, OOP obj )
367 {
368 long i;
369 for (i = 0; i < SML2INT(Array_tally(ary)); i++) {
370 if (obj == cw_object_get(ary, i))
371 return;
372 }
373 Array_tally(ary) = INT2SML(SML2INT(Array_tally(ary))+1);
374 cw_iv_set(ary, SML2INT(Array_tally(ary)), obj);
375 }
376
377 OOP cw_uint2inum( unsigned long n )
378 {
379 if (POSSMLABLE(n)) return LONG2SML(n);
380 //return rb_uint2big(n);
381 }
382
383 OOP cw_int2inum( long n )
384 {
385 if (SMLABLE(n)) return LONG2SML(n);
386 //return rb_int2big(n);
387 }
388
389 // float, largeinteger
390 long cw_num2long( OOP oop )
391 {
392 if (IS_SMLINT(oop)) return SML2LONG(oop);
393 return NUM2LONG(oop);
394 }
395
396 unsigned long cw_num2ulong( OOP oop )
397 {
398 return (unsigned long)cw_num2long(oop);
399 }
400
401
402 OOP cw_boot_intern( char *str )
403 {
404 OOP sym;
405
406 if (sym = cw_boot_lookup(str))
407 return sym;
408 sym = cw_byte_symbol_new2(str);
409 cw_array_add(CWBootSymbols, sym);
410 return sym;
411 }
412
413 OOP cw_boot_lookup( char *str )
414 {
415 int i;
416 OOP sym, sym2;
417
418 sym2 = cw_byte_symbol_new2(str);
419 for (i = 0; i < SML2INT(Array_tally(CWBootSymbols)); i++) {
420 sym = cw_object_get(CWBootSymbols, i);
421 if (sym != Pnil && sym->klass == CWByteSymbol &&
422 cw_byte_symbol_cmp(sym, sym2))
423 return sym;
424 }
425 return Pnil;
426 }
427
428 int cw_byte_string_cmp( OOP str, OOP other )
429 {
430 int size, i;
431
432 size = FIELD_SIZE(str);
433 if (size != FIELD_SIZE(other)) return 0;
434 for (i = 0; i < size; i++) {
435 if (cw_byte_get(str, i) != cw_byte_get(other, i))
436 return 0;
437 }
438 return 1;
439 }
440
441 /*
442 unsigned long cw_symbol_table_size()
443 {
444 unsigned long size = 0;
445 long i;
446 OOP ary;
447
448 for (i = 0; i < FIELD_SIZE(CWBootSymbolTable); i++) {
449 ary = cw_object_get(CWSymbolTable, i);
450 size += FIELD_SIZE(ary);
451 }
452 return size;
453 }
454 */
455 OOP cw_byte_symbol_new( const char *ptr, long len )
456 {
457 OOP sym;
458
459 sym = cw_byte_string_new(ptr, len);
460 sym->klass = CWByteSymbol;
461 return sym;
462 }
463
464 OOP cw_byte_symbol_new2( const char *ptr )
465 {
466 return cw_byte_symbol_new(ptr, strlen(ptr));
467 }
468
469 OOP cw_method_dictionary_new( long size )
470 {
471 NEWOOP(dict);
472 IDXSETUP(dict, CWMethodDictionary, 0, size);
473 return dict;
474 }
475
476 static int cw_method_dictionary_find_index( OOP dict, OOP sym );
477
478 OOP cw_method_dictionary_get( OOP dict, OOP sym )
479 {
480 int idx;
481
482 idx = cw_method_dictionary_find_index(dict, sym);
483 if (idx < 0)
484 return Pnil;
485 return cw_object_get(dict, idx+1);
486 }
487
488 static int cw_method_dictionary_find_index( OOP dict, OOP sym )
489 {
490 int size, high, low = 0, idx, hash, probe_hash;
491 OOP probe;
492
493 size = FIELD_SIZE(sym);
494 high = size - 1;
495 if (high < 20) {
496 while (low <= high) {
497 if (sym == cw_object_get(dict, low))
498 return low;
499 low += 2;
500 }
501
502 } else if (low >= high) {
503 return -1;
504
505 } else {
506 // binary search
507 while (1) {
508 idx = (low + high) >> 1 | 1;
509 if ((probe = cw_object_get(dict, idx)) == sym) return idx;
510 hash = cw_byte_symbol_hash(sym);
511 probe_hash = cw_byte_symbol_hash(probe);
512 if (probe_hash < hash) {
513 low = idx + 2;
514 } else {
515 if (probe_hash > hash) {
516 high = idx - 2;
517 } else {
518 low = idx;
519 do {
520 low -= 2;
521 if (low < 0) return -1;
522 if ((probe = cw_object_get(dict, low)) == sym) return low;
523 } while (cw_byte_symbol_hash(probe) == hash);
524 low = idx;
525 do {
526 low += 2;
527 if (low > high) return -1;
528 if ((probe = cw_object_get(dict, low)) == sym) return low;
529 } while (cw_byte_symbol_hash(probe) == hash);
530 return -1;
531 }
532 }
533 }
534 }
535 return -1;
536 }
537
538 void cw_method_dictionary_set( OOP dict, OOP sym, OOP mth )
539 {
540 int idx, hash, probe_hash, i, j, size, insert;
541 OOP new, probe;
542
543 idx = cw_method_dictionary_find_index(dict, sym);
544 if (idx >= 0) {
545 cw_object_set(dict, idx+1, mth);
546 } else {
547 size = FIELD_SIZE(dict);
548 hash = cw_byte_symbol_hash(sym);
549 new = cw_method_dictionary_new(size+2);
550 for (i = 0, j = 0, insert = -1; i < size; i += 2, j += 2) {
551 probe = cw_object_get(dict, i);
552 probe_hash = cw_byte_symbol_hash(probe);
553 if (insert < 0 && hash < probe_hash) {
554 insert = i;
555 j += 2;
556 }
557 cw_object_set(new, j, probe);
558 cw_object_set(new, j+1, cw_object_get(dict, i+1));
559 }
560 if (insert < 0)
561 insert = size == 0 ? 0 : i + 2;
562 cw_object_set(new, insert, sym);
563 cw_object_set(new, insert+1, mth);
564 cw_swap(dict, new);
565 }
566 }
567
568 int _main( int argc, char **argv )
569 {
570 OOP dict;
571
572 cw_init_proto_oops();
573
574 /*
575 // method dictionary test
576 dict = cw_method_dictionary_new(0);
577 cw_method_dictionary_set(dict, cw_boot_intern("add"), Pnil);
578 cw_method_dictionary_set(dict, cw_boot_intern("add1"), Pnil);
579 printf("dict field size = %d\n", FIELD_SIZE(dict));
580 printf("#add at %d\n", cw_method_dictionary_find_index(dict, cw_boot_intern("add")));
581 printf("#add1 at %d\n", cw_method_dictionary_find_index(dict, cw_boot_intern("add1")));
582 */
583 return 0;
584 }
585

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26