root/NEWT0/trunk/src/newt_core/NewtObj.c

Revision 113, 90.0 kB (checked in by gnue, 17 months ago)

'#pragma mark' is invalidated by '#if 0'

Line 
1/*------------------------------------------------------------------------*/
2/**
3 * @file    NewtObj.c
4 * @brief   オブジェクトシステム
5 *
6 * @author  M.Nukui
7 * @date    2003-11-07
8 *
9 * Copyright (C) 2003-2004 M.Nukui All rights reserved.
10 */
11
12
13/* ヘッダファイル */
14#include <stdlib.h>
15#include <stdio.h>
16#include <string.h>
17
18#include "config.h"
19
20#include "NewtCore.h"
21#include "NewtGC.h"
22#include "NewtIO.h"
23
24
25/* 関数プロトタイプ */
26static newtRef      NewtMakeSymbol0(const char *s);
27static bool         NewtBSearchSymTable(newtRefArg r, const char * name, uint32_t hash, int32_t st, int32_t * indexP);
28static newtObjRef   NewtObjMemAlloc(newtPool pool, uint32_t n, bool literal);
29static newtObjRef   NewtObjRealloc(newtPool pool, newtObjRef obj, uint32_t n);
30static void         NewtGetObjData(newtRefArg r, uint8_t * data, uint32_t len);
31static newtObjRef   NewtObjBinarySetLength(newtObjRef obj, uint32_t n);
32static uint32_t     NewtObjSymbolLength(newtObjRef obj);
33static uint32_t     NewtObjStringLength(newtObjRef obj);
34static newtObjRef   NewtObjStringSetLength(newtObjRef obj, uint32_t n);
35static void         NewtMakeInitSlots(newtRefArg r, uint32_t st, uint32_t n, uint32_t step, const newtRefVar v[]);
36static newtObjRef   NewtObjSlotsSetLength(newtObjRef obj, uint32_t n, newtRefArg v);
37static int          NewtInt32Compare(newtRefArg r1, newtRefArg r2);
38static int          NewtRealCompare(newtRefArg r1, newtRefArg r2);
39static int          NewtStringCompare(newtRefArg r1, newtRefArg r2);
40static int          NewtBinaryCompare(newtRefArg r1, newtRefArg r2);
41static uint16_t     NewtArgsType(newtRefArg r1, newtRefArg r2);
42
43static newtRef      NewtMakeThrowSymbol(int32_t err);
44
45static bool         NewtObjHasProto(newtObjRef obj);
46static bool         NewtMapIsSorted(newtRefArg r);
47static void         NewtObjRemoveArraySlot(newtObjRef obj, int32_t n);
48static void         NewtDeeplyCopyMap(newtRef * dst, int32_t * pos, newtRefArg src);
49static newtRef      NewtDeeplyCloneMap(newtRefArg map, int32_t len);
50static void         NewtObjRemoveFrameSlot(newtObjRef obj, newtRefArg slot);
51static bool         NewtStrNBeginsWith(char * str, uint32_t len, char * sub, uint32_t sublen);
52static bool         NewtStrIsSubclass(char * sub, uint32_t sublen, char * supr, uint32_t suprlen);
53static bool         NewtStrHasSubclass(char * sub, uint32_t sublen, char * supr, uint32_t suprlen);
54
55
56#if 0
57#pragma mark -
58#endif
59/*------------------------------------------------------------------------*/
60/** シンボルのハッシュ値を計算
61 *
62 * @param name      [in] シンボル名
63 *
64 * @return          ハッシュ値
65 */
66
67uint32_t NewtSymbolHashFunction(const char * name)
68{
69    uint32_t result = 0;
70    char c;
71
72    while (*name)
73    {
74        c = *name;
75
76        if (c >= 'a' && c <= 'z')
77            result = result + c - ('a' - 'A');
78        else
79            result = result + c;
80
81        name++;
82    }
83
84    return result * 2654435769U;
85}
86
87
88/*------------------------------------------------------------------------*/
89/** シンボルオブジェクトの作成
90 *
91 * @param s         [in] 文字列
92 *
93 * @return          シンボルオブジェクト
94 */
95
96newtRef NewtMakeSymbol0(const char *s)
97{
98    newtObjRef  obj;
99    uint32_t    size;
100
101    size = sizeof(uint32_t) + strlen(s) + 1;
102    obj = NewtObjAlloc(kNewtSymbolClass, size, 0, true);
103
104    if (obj != NULL)
105    {
106        newtSymDataRef  objData;
107        uint32_t    setlen;
108
109        objData = NewtObjToSymbol(obj);
110
111        setlen = NewtObjSize(obj) - size;
112
113        if (0 < setlen)
114            memset(objData + size, 0, setlen);
115
116        objData->hash = NewtSymbolHashFunction(s);
117        strcpy(objData->name, s);
118
119        return NewtMakePointer(obj);
120    }
121
122    return kNewtRefUnbind;
123}
124
125
126/*------------------------------------------------------------------------*/
127/** シンボルテーブルの位置検索
128 *
129 * @param r         [in] シンボルテーブル
130 * @param name      [in] シンボル文字列
131 * @param hash      [in] ハッシュ値
132 * @param st        [in] 開始位置
133 * @param indexP    [out]位置
134 *
135 * @retval          true    成功
136 * @retval          false   失敗
137 */
138
139bool NewtBSearchSymTable(newtRefArg r, const char * name, uint32_t hash,
140    int32_t st, int32_t * indexP)
141{
142    newtSymDataRef  sym;
143    newtRef *   slots;
144    int32_t len;
145    int32_t ed;
146    int32_t md = st;
147    int16_t comp;
148
149    slots = NewtRefToSlots(r);
150
151    if (hash == 0)
152        hash = NewtSymbolHashFunction(name);
153
154    len = NewtArrayLength(r);
155    ed = len - 1;
156
157    while (st <= ed)
158    {
159        md = (st + ed) / 2;
160
161        sym = NewtRefToSymbol(slots[md]);
162
163        if (hash < sym->hash)
164            comp = -1;
165        else if (hash > sym->hash)
166            comp = 1;
167        else
168            comp = 0;
169
170        if (comp == 0)
171            comp = strcasecmp(name, sym->name);
172
173        if (comp == 0)
174        {
175            *indexP = md;
176            return true;
177        }
178
179        if (comp < 0)
180            ed = md - 1;
181        else
182            st = md + 1;
183    }
184
185    if (len < st)
186        *indexP = len;
187    else
188        *indexP = st;
189
190    return false;
191}
192
193
194/*------------------------------------------------------------------------*/
195/** シンボルのルックアップ
196 *
197 * @param r         [in] シンボルテーブル
198 * @param name      [in] シンボル文字列
199 * @param hash      [in] ハッシュ値
200 * @param st        [in] 開始位置
201 *
202 * @return          シンボルオブジェクト
203 *
204 * @note            未登録の場合はシンボルオブジェクトを作成しシンボルテーブルに登録する
205 */
206
207newtRef NewtLookupSymbol(newtRefArg r, const char * name, uint32_t hash, int32_t st)
208{
209    newtRefVar  sym;
210    int32_t index;
211
212    if (NewtBSearchSymTable(r, name, 0, st, &index))
213        return NewtGetArraySlot(r, index);
214
215    sym = NewtMakeSymbol0(name);
216    NewtInsertArraySlot(r, index, sym);
217
218    return sym;
219}
220
221
222/*------------------------------------------------------------------------*/
223/** シンボルのルックアップ
224 *
225 * @param r         [in] シンボルテーブル
226 * @param name      [in] シンボル文字列
227 * @param st        [in] 開始位置
228 *
229 * @return          シンボルオブジェクト
230 */
231
232newtRef NewtLookupSymbolArray(newtRefArg r, newtRefArg name, int32_t st)
233{
234    newtSymDataRef  sym;
235
236    sym = NewtRefToSymbol(name);
237
238    if (sym != NULL)
239        return NewtLookupSymbol(r, sym->name, sym->hash, st);
240    else
241        return kNewtRefUnbind;
242}
243
244
245/**
246 * Return the ASCII string associated with a symbol ref.
247 * Remark: doesn't check that the passed object is indeed a symbol.
248 *
249 * @param inSymbol  symbol object
250 * @return a pointer to the name of the symbol
251 */
252 
253const char* NewtSymbolGetName(newtRefArg inSymbol)
254{
255    return NewtRefToSymbol(inSymbol)->name;
256}
257
258
259#if 0
260#pragma mark -
261#endif
262/*------------------------------------------------------------------------*/
263/** オブジェクトのオブジェクトタイプの取得
264 *
265 * @param r         [in] オブジェクト
266 * @param detail    [in] リテラルフラグ
267 *
268 * @return          オブジェクトタイプ
269 */
270
271uint16_t NewtGetRefType(newtRefArg r, bool detail)
272{
273    uint16_t    type = kNewtUnknownType;
274
275    switch (r & 3)
276    {
277        case 0: // Integer
278            type = kNewtInt30;
279            break;
280
281        case 1: // Pointer
282            if (detail)
283                type = NewtGetObjectType(NewtRefToPointer(r), true);
284            else
285                type = kNewtPointer;
286            break;
287
288        case 2: // Character or Special
289            switch (r)
290            {
291                case kNewtRefNIL:
292                    type = kNewtNil;
293                    break;
294
295                case kNewtRefTRUE:
296                    type = kNewtTrue;
297                    break;
298
299                case kNewtRefUnbind:
300                    type = kNewtUnbind;
301                    break;
302
303                case kNewtSymbolClass:
304                    type = kNewtSymbol;
305                    break;
306
307                default:
308                    if ((r & 0xF) == 6)
309                        type = kNewtCharacter;
310                    else
311                        type = kNewtSpecial;
312                    break;
313            }
314            break;
315
316        case 3: // Magic Pointer
317            type = kNewtMagicPointer;
318            break;
319    }
320
321    return type;
322}
323
324
325/*------------------------------------------------------------------------*/
326/** オブジェクトデータのオブジェクトタイプの取得
327 *
328 * @param obj       [in] オブジェクトデータ
329 * @param detail    [in] ディテイルフラグ
330 *
331 * @return          オブジェクトタイプ
332 */
333
334uint16_t NewtGetObjectType(newtObjRef obj, bool detail)
335{
336    uint16_t    type = kNewtUnknownType;
337
338    switch (NewtObjType(obj))
339    {
340        case 0: // binary
341            type = kNewtBinary;
342
343            if (detail)
344            {
345                if (obj->as.klass == kNewtSymbolClass)
346                    type = kNewtSymbol;
347                else if (NewtRefEqual(obj->as.klass, NSSYM0(string)))
348                    type = kNewtString;
349                else if (NewtRefEqual(obj->as.klass, NSSYM0(int32)))
350                    type = kNewtInt32;
351                else if (NewtRefEqual(obj->as.klass, NSSYM0(real)))
352                    type = kNewtReal;
353                else if (NewtIsSubclass(obj->as.klass, NSSYM0(string)))
354                    type = kNewtString;
355            }
356            break;
357
358        case 1: // array
359            type = kNewtArray;
360            break;
361
362        case 3: // frame
363            type = kNewtFrame;
364            break;
365    }
366
367    return type;
368}
369
370
371#if 0
372#pragma mark -
373#endif
374/*------------------------------------------------------------------------*/
375/** オブジェクトデータの実データサイズを計算
376 *
377 * @param n         [in] データサイズ
378 *
379 * @return          実データサイズ
380 */
381
382uint32_t NewtObjCalcDataSize(uint32_t n)
383{
384    if (n < 4)
385        return 4;
386    else
387        return n;
388}
389
390
391/*------------------------------------------------------------------------*/
392/** オブジェクトデータのメモリ確保
393 *
394 * @param pool      [in] メモリプール
395 * @param n         [in] データサイズ
396 * @param literal   [in] リテラルフラグ
397 *
398 * @return          オブジェクトデータ
399 */
400
401newtObjRef NewtObjMemAlloc(newtPool pool, uint32_t n, bool literal)
402{
403    newtObjRef  obj;
404    uint32_t    newSize;
405
406    if (literal)
407    {
408        newSize = NewtAlign(sizeof(newtObj) + n, 4);
409        obj = NewtObjChainAlloc(pool, newSize, 0);
410    }
411    else
412    {
413        newSize = NewtObjCalcDataSize(n);
414        obj = NewtObjChainAlloc(pool, sizeof(newtObj) + sizeof(uint8_t *), newSize);
415    }
416
417    return obj;
418}
419
420
421/*------------------------------------------------------------------------*/
422/** オブジェクトのメモリ確保
423 *
424 * @param r         [in] クラス/マップ
425 * @param n         [in] サイズ
426 * @param type      [in] オブジェクトタイプ
427 * @param literal   [in] リテラルフラグ
428 *
429 * @return          オブジェクト
430 */
431
432newtObjRef NewtObjAlloc(newtRefArg r, uint32_t n, uint16_t type, bool literal)
433{
434    newtObjRef  obj;
435
436    obj = NewtObjMemAlloc(NEWT_POOL, n, literal);
437    if (obj == NULL) return NULL;
438
439    obj->header.h |= (n << 8) | type;
440
441    if (NEWT_SWEEP)
442        obj->header.h |= kNewtObjSweep;
443
444    if ((type & kNewtObjFrame) != 0)
445        obj->as.map = r;
446    else
447        obj->as.klass = r;
448
449    return obj;
450}
451
452
453/*------------------------------------------------------------------------*/
454/** オブジェクトデータのメモリ再確保
455 *
456 * @param pool      [in] メモリプール
457 * @param obj       [in] オブジェクトデータ
458 * @param n         [in] サイズ
459 *
460 * @return          オブジェクトデータ
461 */
462
463newtObjRef NewtObjRealloc(newtPool pool, newtObjRef obj, uint32_t n)
464{
465    uint8_t **  datap;
466    uint8_t *   data;
467    int32_t oldSize;
468    int32_t newSize;
469    int32_t addSize;
470
471    oldSize = NewtObjCalcDataSize(NewtObjSize(obj));
472    newSize = NewtObjCalcDataSize(n);
473    addSize = newSize - oldSize;
474
475    if (0 < addSize)
476        NewtCheckGC(pool, addSize);
477
478    datap = (uint8_t **)(obj + 1);
479    data = NewtMemRealloc(pool, *datap, newSize);
480    if (data == NULL) return NULL;
481
482    pool->usesize += addSize;
483
484    if (data != *datap)
485        *datap = data;
486
487    obj->header.h = ((n << 8) | (obj->header.h & 0xff));
488
489    return obj;
490}
491
492
493/*------------------------------------------------------------------------*/
494/** オブジェクトデータのサイズ変更
495 *
496 * @param obj       [in] オブジェクトデータ
497 * @param n         [in] サイズ
498 *
499 * @return          オブジェクトデータ
500 */
501
502newtObjRef NewtObjResize(newtObjRef obj, uint32_t n)
503{
504    if (NewtObjIsReadonly(obj))
505    {
506        NewtThrow0(kNErrObjectReadOnly);
507        return NULL;
508    }
509
510    return NewtObjRealloc(NEWT_POOL, obj, n);
511}
512
513
514/*------------------------------------------------------------------------*/
515/** オブジェクトデータのデータ部を取得
516 *
517 * @param obj       [in] オブジェクトデータ
518 *
519 * @return          データ部
520 */
521
522void * NewtObjData(newtObjRef obj)
523{
524    void *  data;
525
526    data = (void *)(obj + 1);
527
528    if (NewtObjIsLiteral(obj))
529        return data;
530    else
531        return *((void **)data);
532}
533
534
535/*------------------------------------------------------------------------*/
536/** オブジェクのクローン複製
537 *
538 * @param r         [in] オブジェクト
539 *
540 * @return          クローン複製されたオブジェクト
541 */
542
543newtRef NewtObjClone(newtRefArg r)
544{
545    newtObjRef  obj;
546
547    obj = NewtRefToPointer(r);
548
549    if (obj != NULL)
550    {
551        newtObjRef  newObj = NULL;
552        uint32_t    size;
553        uint16_t    type;
554
555        size = NewtObjSize(obj);
556        type = NewtObjType(obj);
557
558        switch (NewtGetObjectType(obj, true))
559        {
560            case kNewtSymbol:
561            case kNewtReal:
562                return r;
563
564            case kNewtFrame:
565                {
566                    newtRefVar  map;
567
568                    if (NewtRefIsLiteral(obj->as.map))
569                        map = obj->as.map;
570                    else
571                        map = NcClone(obj->as.map);
572
573                    newObj = NewtObjAlloc(map, size, type, false);
574                }
575                break;
576
577            default:
578                newObj = NewtObjAlloc(obj->as.klass, size, type, false);
579                break;
580        }
581
582        if (newObj != NULL)
583        {
584            uint8_t *   src;
585            uint8_t *   dst;
586
587            src = NewtObjToBinary(obj);
588            dst = NewtObjToBinary(newObj);
589            memcpy(dst, src, size);
590
591            return NewtMakePointer(newObj);
592        }
593    }
594
595    return (newtRef)r;
596}
597
598
599/*------------------------------------------------------------------------*/
600/** オブジェクのリテラル化
601 *
602 * @param r         [in] オブジェクト
603 *
604 * @return          リテラル化されたオブジェクト
605 */
606
607newtRef NewtPackLiteral(newtRefArg r)
608{
609    newtObjRef  obj;
610
611    if (NewtRefIsLiteral(r))
612        return r;
613
614    obj = NewtRefToPointer(r);
615
616    if (obj != NULL)
617    {
618        newtObjRef  newObj = NULL;
619        uint32_t    size;
620        uint16_t    type;
621
622        size = NewtObjSize(obj);
623        type = NewtObjType(obj);
624
625        if (NewtObjIsFrame(obj))
626        {
627            obj->as.map = NewtPackLiteral(obj->as.map);
628            newObj = NewtObjAlloc(obj->as.map, size, type, true);
629        }
630        else
631        {
632            newObj = NewtObjAlloc(obj->as.klass, size, type, true);
633        }
634
635        if (newObj != NULL)
636        {
637            uint8_t *   src;
638            uint8_t *   dst;
639
640            src = NewtObjToBinary(obj);
641            dst = NewtObjToBinary(newObj);
642            memcpy(dst, src, size);
643
644            if (NewtObjIsSlotted(newObj))
645            {
646                newtRef *   slots;
647                uint32_t    len;
648                uint32_t    i;
649
650                len = NewtObjSlotsLength(newObj);
651                slots = NewtObjToSlots(newObj);
652
653                for (i = 0; i < len; i++)
654                {
655                    slots[i] = NewtPackLiteral(slots[i]);
656                }
657            }
658
659            newObj->header.h |= kNewtObjLiteral;
660
661            // obj を free してはいけない
662            // GC にまかせる
663
664            return NewtMakePointer(newObj);
665        }
666    }
667
668    return (newtRef)r;
669}
670
671
672#if 0
673#pragma mark -
674#endif
675/*------------------------------------------------------------------------*/
676/** オブジェクのデータ部をバッファに取出す
677 *
678 * @param r         [in] オブジェクト
679 * @param data      [out]バッファ
680 * @param len       [in] バッファ長
681 *
682 * @return          なし
683 */
684
685void NewtGetObjData(newtRefArg r, uint8_t * data, uint32_t len)
686{
687    newtObjRef  obj;
688    uint8_t *   objData;
689
690    obj = NewtRefToPointer(r);
691    objData = NewtObjToBinary(obj);
692
693    memcpy(data, objData, len);
694}
695
696
697#if 0
698#pragma mark -
699#endif
700/*------------------------------------------------------------------------*/
701/** オブジェクトがリテラルかチェックする
702 *
703 * @param r         [in] オブジェクト
704 *
705 * @retval          true    リテラル
706 * @retval          false   リテラルでない
707 */
708
709bool NewtRefIsLiteral(newtRefArg r)
710{
711    if (NewtRefIsPointer(r))
712    {
713        newtObjRef  obj;
714
715        obj = NewtRefToPointer(r);
716
717        return NewtObjIsLiteral(obj);
718    }
719
720    return true;
721}
722
723
724/*------------------------------------------------------------------------*/
725/** オブジェクにスウィープフラグが立っているかチェックする
726 *
727 * @param r         [in] オブジェクト
728 * @param mark      [in] マーク
729 *
730 * @retval          true    スウィープフラグが立っている
731 * @retval          false   スウィープフラグが立っていない
732 */
733
734bool NewtRefIsSweep(newtRefArg r, bool mark)
735{
736    if (NewtRefIsPointer(r))
737    {
738        newtObjRef  obj;
739
740        obj = NewtRefToPointer(r);
741
742        return NewtObjIsSweep(obj, mark);
743    }
744
745    return true;
746}
747
748
749/*------------------------------------------------------------------------*/
750/** オブジェクトが NIL かチェックする
751 *
752 * @param r         [in] オブジェクト
753 *
754 * @retval          true    NIL または #UNBIND
755 * @retval          false   NIL でない
756 */
757
758bool NewtRefIsNIL(newtRefArg r)
759{
760    return (kNewtRefNIL == r || kNewtRefUnbind == r);
761}
762
763
764/*------------------------------------------------------------------------*/
765/** オブジェクトがシンボルかチェックする
766 *
767 * @param r         [in] オブジェクト
768 *
769 * @retval          true    シンボル
770 * @retval          false   シンボルでない
771 */
772
773bool NewtRefIsSymbol(newtRefArg r)
774{
775    return (kNewtSymbol == NewtGetRefType(r, true));
776}
777
778
779/*------------------------------------------------------------------------*/
780/** オブジェクトのハッシュ値を取得する
781 *
782 * @param r         [in] オブジェクト
783 *
784 * @return          ハッシュ値
785 */
786
787uint32_t NewtRefToHash(newtRefArg r)
788{
789    newtSymDataRef  sym;
790
791    sym = NewtRefToSymbol(r);
792
793    if (sym != NULL)
794        return sym->hash;
795    else
796        return 0;
797}
798
799
800/*------------------------------------------------------------------------*/
801/** オブジェクトが文字列かチェックする
802 *
803 * @param r         [in] オブジェクト
804 *
805 * @retval          true    文字列
806 * @retval          false   文字列でない
807 */
808
809bool NewtRefIsString(newtRefArg r)
810{
811    return (kNewtString == NewtGetRefType(r, true));
812}
813
814
815/*------------------------------------------------------------------------*/
816/** オブジェクトが整数かチェックする
817 *
818 * @param r         [in] オブジェクト
819 *
820 * @retval          true    整数
821 * @retval          false   整数でない
822 */
823
824bool NewtRefIsInteger(newtRefArg r)
825{
826    return (NewtRefIsInt30(r) || NewtRefIsInt32(r));
827}
828
829
830/*------------------------------------------------------------------------*/
831/** 整数オブジェクを整数にする
832 *
833 * @param r         [in] オブジェクト
834 *
835 * @return          整数
836 */
837
838int32_t NewtRefToInteger(newtRefArg r)
839{
840    int32_t v = 0;
841
842    if (NewtRefIsInt30(r))
843        v = NewtRefToInt30(r);
844    else
845        NewtGetObjData(r, (uint8_t *)&v, sizeof(v));
846
847    return v;
848}
849
850
851/*------------------------------------------------------------------------*/
852/** オブジェクトが32bit整数かチェックする
853 *
854 * @param r         [in] オブジェクト
855 *
856 * @retval          true    32bit整数
857 * @retval          false   32bit整数でない
858 */
859
860bool NewtRefIsInt32(newtRefArg r)
861{
862    return (kNewtInt32 == NewtGetRefType(r, true));
863}
864
865
866/*------------------------------------------------------------------------*/
867/** オブジェクトが浮動小数点かチェックする
868 *
869 * @param r         [in] オブジェクト
870 *
871 * @retval          true    浮動小数点
872 * @retval          false   浮動小数点でない
873 */
874
875bool NewtRefIsReal(newtRefArg r)
876{
877    return (kNewtReal == NewtGetRefType(r, true));
878}
879
880
881/*------------------------------------------------------------------------*/
882/** 数値オブジェクを浮動小数点にする
883 *
884 * @param r         [in] オブジェクト
885 *
886 * @return          浮動小数点
887 */
888
889double NewtRefToReal(newtRefArg r)
890{
891    double  v = 0.0;
892
893    if (NewtRefIsInteger(r))
894        v = NewtRefToInteger(r);
895    else
896        NewtGetObjData(r, (uint8_t *)&v, sizeof(v));
897
898    return v;
899}
900
901
902/*------------------------------------------------------------------------*/
903/** オブジェクトがバイナリオブジェクトかチェックする
904 *
905 * @param r         [in] オブジェクト
906 *
907 * @retval          true    バイナリオブジェクト
908 * @retval          false   バイナリオブジェクトでない
909 */
910
911bool NewtRefIsBinary(newtRefArg r)
912{
913    if (NewtRefIsPointer(r))
914    {
915        uint16_t    type;
916
917        type = NewtGetObjectType(NewtRefToPointer(r), false);
918
919        return (type == kNewtBinary);
920    }
921
922    return false;
923}
924
925
926/*------------------------------------------------------------------------*/
927/** オブジェクトのオブジェクトデータを取得する
928 *
929 * @param r         [in] オブジェクト
930 *
931 * @return          オブジェクトデータ
932 */
933
934void * NewtRefToData(newtRefArg r)
935{
936    newtObjRef  obj;
937
938    obj = NewtRefToPointer(r);
939
940    return NewtObjData(obj);
941}
942
943
944/*------------------------------------------------------------------------*/
945/** オブジェクトが配列オブジェクトかチェックする
946 *
947 * @param r         [in] オブジェクト
948 *
949 * @retval          true    配列オブジェクト
950 * @retval          false   配列オブジェクトでない
951 */
952
953bool NewtRefIsArray(newtRefArg r)
954{
955    return (NewtGetRefType(r, true) == kNewtArray);
956}
957
958
959/*------------------------------------------------------------------------*/
960/** オブジェクトがフレームオブジェクトかチェックする
961 *
962 * @param r         [in] オブジェクト
963 *
964 * @retval          true    フレームオブジェクト
965 * @retval          false   フレームオブジェクトでない
966 */
967
968bool NewtRefIsFrame(newtRefArg r)
969{
970    return (NewtGetRefType(r, true) == kNewtFrame);
971}
972
973
974/*------------------------------------------------------------------------*/
975/** オブジェクトがフレームまたは配列オブジェクトかチェックする
976 *
977 * @param r         [in] オブジェクト
978 *
979 * @retval          true    フレームまたは配列オブジェクト
980 * @retval          false   フレームまたは配列オブジェクトでない
981 */
982
983bool NewtRefIsFrameOrArray(newtRefArg r)
984{
985    uint16_t    type;
986
987    type = NewtGetRefType(r, true);
988    return (type == kNewtFrame || type == kNewtArray);
989}
990
991
992/*------------------------------------------------------------------------*/
993/** オブジェクトがイミディエイト(即値)かチェックする
994 *
995 * @param r         [in] オブジェクト
996 *
997 * @retval          true    イミディエイトである
998 * @retval          false   イミディエイトでない
999 */
1000
1001bool NewtRefIsImmediate(newtRefArg r)
1002{
1003#ifdef __NAMED_MAGIC_POINTER__
1004    if (NewtRefIsNamedMP(r))
1005        return false;
1006#endif /* __NAMED_MAGIC_POINTER__ */
1007
1008    return ! NewtRefIsPointer(r);
1009}
1010
1011
1012/*------------------------------------------------------------------------*/
1013/** オブジェクトがコードブロック(関数オブジェクト)かチェックする
1014 *
1015 * @param r         [in] オブジェクト
1016 *
1017 * @retval          true    コードブロック
1018 * @retval          false   コードブロックでない
1019 */
1020
1021bool NewtRefIsCodeBlock(newtRefArg r)
1022{
1023    if (NewtRefIsFrame(r))
1024    {
1025        newtRefVar  klass;
1026
1027        klass = NcClassOf(r);
1028
1029        if (NewtRefEqual(klass, NSSYM0(CodeBlock)))
1030            return true;
1031    }
1032
1033    return false;
1034}
1035
1036
1037/*------------------------------------------------------------------------*/
1038/** オブジェクトがネイティブ関数(rcvrなし関数オブジェクト)かチェックする
1039 *
1040 * @param r         [in] オブジェクト
1041 *
1042 * @retval          true    ネイティブ関数
1043 * @retval          false   ネイティブ関数でない
1044 */
1045
1046bool NewtRefIsNativeFn(newtRefArg r)
1047{
1048    if (NewtRefIsFrame(r))
1049        return NewtRefEqual(NcClassOf(r), NSSYM0(_function.native0));
1050    else
1051        return false;
1052}
1053
1054
1055/*------------------------------------------------------------------------*/
1056/** オブジェクトがネイティブ関数(rcvrあり関数オブジェクト)かチェックする
1057 *
1058 * @param r         [in] オブジェクト
1059 *
1060 * @retval          true    ネイティブ関数
1061 * @retval          false   ネイティブ関数でない
1062 */
1063
1064bool NewtRefIsNativeFunc(newtRefArg r)
1065{
1066    if (NewtRefIsFrame(r))
1067        return NewtRefEqual(NcClassOf(r), NSSYM0(_function.native));
1068    else
1069        return false;
1070}
1071
1072
1073/*------------------------------------------------------------------------*/
1074/** オブジェクトが関数オブジェクトかチェックする
1075 *
1076 * @param r         [in] オブジェクト
1077 *
1078 * @retval          true    関数オブジェクト
1079 * @retval          false   関数オブジェクトでない
1080 */
1081
1082bool NewtRefIsFunction(newtRefArg r)
1083{
1084    return (NewtRefFunctionType(r) != kNewtNotFunction);
1085}
1086
1087
1088/*------------------------------------------------------------------------*/
1089/** 関数オブジェクトのタイプを取得する
1090 *
1091 * @param r         [in] オブジェクト
1092 *
1093 * @retval          kNewtNotFunction    関数オブジェクトでない
1094 * @retval          kNewtCodeBlock      バイトコード関数
1095 * @retval          kNewtNativeFn       ネイティブ関数(rcvrなし、Old Style)
1096 * @retval          kNewtNativeFunc     ネイティブ関数(rcvrあり、New Style)
1097 */
1098
1099int NewtRefFunctionType(newtRefArg r)
1100{
1101    if (NewtRefIsFrame(r))
1102    {
1103        newtRefVar  klass;
1104
1105        klass = NcClassOf(r);
1106
1107        if (NewtRefEqual(klass, NSSYM0(CodeBlock)))
1108            return kNewtCodeBlock;
1109
1110        if (NewtRefEqual(klass, NSSYM0(_function.native0)))
1111            return kNewtNativeFn;
1112
1113        if (NewtRefEqual(klass, NSSYM0(_function.native)))
1114            return kNewtNativeFunc;
1115    }
1116
1117    return kNewtNotFunction;