00001
00013
00014 #include <stdlib.h>
00015 #include <stdio.h>
00016 #include <string.h>
00017
00018 #include "NewtCore.h"
00019 #include "NewtGC.h"
00020 #include "NewtIO.h"
00021
00022
00023
00024 static newtRef NewtMakeSymbol0(const char *s);
00025 static bool NewtBSearchSymTable(newtRefArg r, const char * name, uint32_t hash, int32_t st, int32_t * indexP);
00026 static newtObjRef NewtObjMemAlloc(newtPool pool, uint32_t n, bool literal);
00027 static newtObjRef NewtObjRealloc(newtPool pool, newtObjRef obj, uint32_t n);
00028 static void NewtGetObjData(newtRefArg r, uint8_t * data, uint32_t len);
00029 static newtObjRef NewtObjBinarySetLength(newtObjRef obj, uint32_t n);
00030 static uint32_t NewtObjSymbolLength(newtObjRef obj);
00031 static uint32_t NewtObjStringLength(newtObjRef obj);
00032 static newtObjRef NewtObjStringSetLength(newtObjRef obj, uint32_t n);
00033 static void NewtMakeInitSlots(newtRefArg r, uint32_t st, uint32_t n, uint32_t step, newtRefVar v[]);
00034 static newtObjRef NewtObjSlotsSetLength(newtObjRef obj, uint32_t n, newtRefArg v);
00035 static int NewtInt32Compare(newtRefArg r1, newtRefArg r2);
00036 static int NewtRealCompare(newtRefArg r1, newtRefArg r2);
00037 static int NewtStringCompare(newtRefArg r1, newtRefArg r2);
00038 static int NewtBinaryCompare(newtRefArg r1, newtRefArg r2);
00039 static uint16_t NewtArgsType(newtRefArg r1, newtRefArg r2);
00040
00041 static newtRef NewtMakeThrowSymbol(int32_t err);
00042
00043 static bool NewtObjHasProto(newtObjRef obj);
00044 static bool NewtMapIsSorted(newtRefArg r);
00045 static void NewtObjRemoveArraySlot(newtObjRef obj, int32_t n);
00046 static void NewtDeeplyCopyMap(newtRef * dst, int32_t * pos, newtRefArg src);
00047 static newtRef NewtDeeplyCloneMap(newtRefArg map, int32_t len);
00048 static void NewtObjRemoveFrameSlot(newtObjRef obj, newtRefArg slot);
00049 static bool NewtStrNBeginsWith(char * str, uint32_t len, char * sub, uint32_t sublen);
00050 static bool NewtStrIsSubclass(char * sub, uint32_t sublen, char * supr, uint32_t suprlen);
00051 static bool NewtStrHasSubclass(char * sub, uint32_t sublen, char * supr, uint32_t suprlen);
00052
00053
00054 #pragma mark -
00055
00063 uint32_t NewtSymbolHashFunction(const char * name)
00064 {
00065 uint32_t result = 0;
00066 char c;
00067
00068 while (*name)
00069 {
00070 c = *name;
00071
00072 if (c >= 'a' && c <= 'z')
00073 result = result + c - ('a' - 'A');
00074 else
00075 result = result + c;
00076
00077 name++;
00078 }
00079
00080 return result * 2654435769U;
00081 }
00082
00083
00084
00092 newtRef NewtMakeSymbol0(const char *s)
00093 {
00094 newtObjRef obj;
00095 uint32_t size;
00096
00097 size = sizeof(uint32_t) + strlen(s) + 1;
00098 obj = NewtObjAlloc(kNewtSymbolClass, size, 0, true);
00099
00100 if (obj != NULL)
00101 {
00102 newtSymDataRef objData;
00103 uint32_t setlen;
00104
00105 objData = NewtObjToSymbol(obj);
00106
00107 setlen = NewtObjSize(obj) - size;
00108
00109 if (0 < setlen)
00110 memset(objData + size, 0, setlen);
00111
00112 objData->hash = NewtSymbolHashFunction(s);
00113 strcpy(objData->name, s);
00114
00115 return NewtMakePointer(obj);
00116 }
00117
00118 return kNewtRefUnbind;
00119 }
00120
00121
00122
00135 bool NewtBSearchSymTable(newtRefArg r, const char * name, uint32_t hash,
00136 int32_t st, int32_t * indexP)
00137 {
00138 newtSymDataRef sym;
00139 newtRef * slots;
00140 int32_t len;
00141 int32_t ed;
00142 int32_t md = st;
00143 int16_t comp;
00144
00145 slots = NewtRefToSlots(r);
00146
00147 if (hash == 0)
00148 hash = NewtSymbolHashFunction(name);
00149
00150 len = NewtArrayLength(r);
00151 ed = len - 1;
00152
00153 while (st <= ed)
00154 {
00155 md = (st + ed) / 2;
00156
00157 sym = NewtRefToSymbol(slots[md]);
00158
00159 if (hash < sym->hash)
00160 comp = -1;
00161 else if (hash > sym->hash)
00162 comp = 1;
00163 else
00164 comp = 0;
00165
00166 if (comp == 0)
00167 comp = strcasecmp(name, sym->name);
00168
00169 if (comp == 0)
00170 {
00171 *indexP = md;
00172 return true;
00173 }
00174
00175 if (comp < 0)
00176 ed = md - 1;
00177 else
00178 st = md + 1;
00179 }
00180
00181 if (len < st)
00182 *indexP = len;
00183 else
00184 *indexP = st;
00185
00186 return false;
00187 }
00188
00189
00190
00203 newtRef NewtLookupSymbol(newtRefArg r, const char * name, uint32_t hash, int32_t st)
00204 {
00205 newtRefVar sym;
00206 int32_t index;
00207
00208 if (NewtBSearchSymTable(r, name, 0, st, &index))
00209 return NewtGetArraySlot(r, index);
00210
00211 sym = NewtMakeSymbol0(name);
00212 NewtInsertArraySlot(r, index, sym);
00213
00214 return sym;
00215 }
00216
00217
00218
00228 newtRef NewtLookupSymbolArray(newtRefArg r, newtRefArg name, int32_t st)
00229 {
00230 newtSymDataRef sym;
00231
00232 sym = NewtRefToSymbol(name);
00233
00234 if (sym != NULL)
00235 return NewtLookupSymbol(r, sym->name, sym->hash, st);
00236 else
00237 return kNewtRefUnbind;
00238 }
00239
00240
00249 const char* NewtSymbolGetName(newtRefArg inSymbol)
00250 {
00251 return NewtRefToSymbol(inSymbol)->name;
00252 }
00253
00254
00255 #pragma mark -
00256
00265 uint16_t NewtGetRefType(newtRefArg r, bool detail)
00266 {
00267 uint16_t type = kNewtUnknownType;
00268
00269 switch (r & 3)
00270 {
00271 case 0:
00272 type = kNewtInt30;
00273 break;
00274
00275 case 1:
00276 if (detail)
00277 type = NewtGetObjectType(NewtRefToPointer(r), true);
00278 else
00279 type = kNewtPointer;
00280 break;
00281
00282 case 2:
00283 switch (r)
00284 {
00285 case kNewtRefNIL:
00286 type = kNewtNil;
00287 break;
00288
00289 case kNewtRefTRUE:
00290 type = kNewtTrue;
00291 break;
00292
00293 case kNewtRefUnbind:
00294 type = kNewtUnbind;
00295 break;
00296
00297 case kNewtSymbolClass:
00298 type = kNewtSymbol;
00299 break;
00300
00301 default:
00302 if ((r & 0xF) == 6)
00303 type = kNewtCharacter;
00304 else
00305 type = kNewtSpecial;
00306 break;
00307 }
00308 break;
00309
00310 case 3:
00311 type = kNewtMagicPointer;
00312 break;
00313 }
00314
00315 return type;
00316 }
00317
00318
00319
00328 uint16_t NewtGetObjectType(newtObjRef obj, bool detail)
00329 {
00330 uint16_t type = kNewtUnknownType;
00331
00332 switch (NewtObjType(obj))
00333 {
00334 case 0:
00335 type = kNewtBinary;
00336
00337 if (detail)
00338 {
00339 if (obj->as.klass == kNewtSymbolClass)
00340 type = kNewtSymbol;
00341 else if (NewtRefEqual(obj->as.klass, NSSYM0(string)))
00342 type = kNewtString;
00343 else if (NewtRefEqual(obj->as.klass, NSSYM0(int32)))
00344 type = kNewtInt32;
00345 else if (NewtRefEqual(obj->as.klass, NSSYM0(real)))
00346 type = kNewtReal;
00347 else if (NewtIsSubclass(obj->as.klass, NSSYM0(string)))
00348 type = kNewtString;
00349 }
00350 break;
00351
00352 case 1:
00353 type = kNewtArray;
00354 break;
00355
00356 case 3:
00357 type = kNewtFrame;
00358 break;
00359 }
00360
00361 return type;
00362 }
00363
00364
00365 #pragma mark -
00366
00374 uint32_t NewtObjCalcDataSize(uint32_t n)
00375 {
00376 if (n < 4)
00377 return 4;
00378 else
00379 return n;
00380 }
00381
00382
00383
00393 newtObjRef NewtObjMemAlloc(newtPool pool, uint32_t n, bool literal)
00394 {
00395 newtObjRef obj;
00396 uint32_t newSize;
00397
00398 if (literal)
00399 {
00400 newSize = NewtAlign(sizeof(newtObj) + n, 4);
00401 obj = NewtObjChainAlloc(pool, newSize, 0);
00402 }
00403 else
00404 {
00405 newSize = NewtObjCalcDataSize(n);
00406 obj = NewtObjChainAlloc(pool, sizeof(newtObj) + sizeof(uint8_t *), newSize);
00407 }
00408
00409 return obj;
00410 }
00411
00412
00413
00424 newtObjRef NewtObjAlloc(newtRefArg r, uint32_t n, uint16_t type, bool literal)
00425 {
00426 newtObjRef obj;
00427
00428 obj = NewtObjMemAlloc(NEWT_POOL, n, literal);
00429 if (obj == NULL) return NULL;
00430
00431 obj->header.h |= (n << 8) | type;
00432
00433 if (NEWT_SWEEP)
00434 obj->header.h |= kNewtObjSweep;
00435
00436 if ((type & kNewtObjFrame) != 0)
00437 obj->as.map = r;
00438 else
00439 obj->as.klass = r;
00440
00441 return obj;
00442 }
00443
00444
00445
00455 newtObjRef NewtObjRealloc(newtPool pool, newtObjRef obj, uint32_t n)
00456 {
00457 uint8_t ** datap;
00458 uint8_t * data;
00459 int32_t oldSize;
00460 int32_t newSize;
00461 int32_t addSize;
00462
00463 oldSize = NewtObjCalcDataSize(NewtObjSize(obj));
00464 newSize = NewtObjCalcDataSize(n);
00465 addSize = newSize - oldSize;
00466
00467 if (0 < addSize)
00468 NewtCheckGC(pool, addSize);
00469
00470 datap = (uint8_t **)(obj + 1);
00471 data = NewtMemRealloc(pool, *datap, newSize);
00472 if (data == NULL) return NULL;
00473
00474 pool->usesize += addSize;
00475
00476 if (data != *datap)
00477 *datap = data;
00478
00479 obj->header.h = ((n << 8) | (obj->header.h & 0xff));
00480
00481 return obj;
00482 }
00483
00484
00485
00494 newtObjRef NewtObjResize(newtObjRef obj, uint32_t n)
00495 {
00496 if (NewtObjIsReadonly(obj))
00497 {
00498 NewtThrow0(kNErrObjectReadOnly);
00499 return NULL;
00500 }
00501
00502 return NewtObjRealloc(NEWT_POOL, obj, n);
00503 }
00504
00505
00506
00514 void * NewtObjData(newtObjRef obj)
00515 {
00516 void * data;
00517
00518 data = (void *)(obj + 1);
00519
00520 if (NewtObjIsLiteral(obj))
00521 return data;
00522 else
00523 return *((void **)data);
00524 }
00525
00526
00527
00535 newtRef NewtObjClone(newtRefArg r)
00536 {
00537 newtObjRef obj;
00538
00539 obj = NewtRefToPointer(r);
00540
00541 if (obj != NULL)
00542 {
00543 newtObjRef newObj = NULL;
00544 uint32_t size;
00545 uint16_t type;
00546
00547 size = NewtObjSize(obj);
00548 type = NewtObjType(obj);
00549
00550 switch (NewtGetObjectType(obj, true))
00551 {
00552 case kNewtSymbol:
00553 case kNewtReal:
00554 return r;
00555
00556 case kNewtFrame:
00557 {
00558 newtRefVar map;
00559
00560 if (NewtRefIsLiteral(obj->as.map))
00561 map = obj->as.map;
00562 else
00563 map = NcClone(obj->as.map);
00564
00565 newObj = NewtObjAlloc(map, size, type, false);
00566 }
00567 break;
00568
00569 default:
00570 newObj = NewtObjAlloc(obj->as.klass, size, type, false);
00571 break;
00572 }
00573
00574 if (newObj != NULL)
00575 {
00576 uint8_t * src;
00577 uint8_t * dst;
00578
00579 src = NewtObjToBinary(obj);
00580 dst = NewtObjToBinary(newObj);
00581 memcpy(dst, src, size);
00582
00583 return NewtMakePointer(newObj);
00584 }
00585 }
00586
00587 return (newtRef)r;
00588 }
00589
00590
00591
00599 newtRef NewtPackLiteral(newtRefArg r)
00600 {
00601 newtObjRef obj;
00602
00603 if (NewtRefIsLiteral(r))
00604 return r;
00605
00606 obj = NewtRefToPointer(r);
00607
00608 if (obj != NULL)
00609 {
00610 newtObjRef newObj = NULL;
00611 uint32_t size;
00612 uint16_t type;
00613
00614 size = NewtObjSize(obj);
00615 type = NewtObjType(obj);
00616
00617 if (NewtObjIsFrame(obj))
00618 {
00619 obj->as.map = NewtPackLiteral(obj->as.map);
00620 newObj = NewtObjAlloc(obj->as.map, size, type, true);
00621 }
00622 else
00623 {
00624 newObj = NewtObjAlloc(obj->as.klass, size, type, true);
00625 }
00626
00627 if (newObj != NULL)
00628 {
00629 uint8_t * src;
00630 uint8_t * dst;
00631
00632 src = NewtObjToBinary(obj);
00633 dst = NewtObjToBinary(newObj);
00634 memcpy(dst, src, size);
00635
00636 if (NewtObjIsSlotted(newObj))
00637 {
00638 newtRef * slots;
00639 uint32_t len;
00640 uint32_t i;
00641
00642 len = NewtObjSlotsLength(newObj);
00643 slots = NewtObjToSlots(newObj);
00644
00645 for (i = 0; i < len; i++)
00646 {
00647 slots[i] = NewtPackLiteral(slots[i]);
00648 }
00649 }
00650
00651 newObj->header.h |= kNewtObjLiteral;
00652
00653
00654
00655
00656 return NewtMakePointer(newObj);
00657 }
00658 }
00659
00660 return (newtRef)r;
00661 }
00662
00663
00664 #pragma mark -
00665
00675 void NewtGetObjData(newtRefArg r, uint8_t * data, uint32_t len)
00676 {
00677 newtObjRef obj;
00678 uint8_t * objData;
00679
00680 obj = NewtRefToPointer(r);
00681 objData = NewtObjToBinary(obj);
00682
00683 memcpy(data, objData, len);
00684 }
00685
00686
00687 #pragma mark -
00688
00697 bool NewtRefIsLiteral(newtRefArg r)
00698 {
00699 if (NewtRefIsPointer(r))
00700 {
00701 newtObjRef obj;
00702
00703 obj = NewtRefToPointer(r);
00704
00705 return NewtObjIsLiteral(obj);
00706 }
00707
00708 return true;
00709 }
00710
00711
00712
00722 bool NewtRefIsSweep(newtRefArg r, bool mark)
00723 {
00724 if (NewtRefIsPointer(r))
00725 {
00726 newtObjRef obj;
00727
00728 obj = NewtRefToPointer(r);
00729
00730 return NewtObjIsSweep(obj, mark);
00731 }
00732
00733 return true;
00734 }
00735
00736
00737
00746 bool NewtRefIsNIL(newtRefArg r)
00747 {
00748 return (kNewtRefNIL == r || kNewtRefUnbind == r);
00749 }
00750
00751
00752
00761 bool NewtRefIsSymbol(newtRefArg r)
00762 {
00763 return (kNewtSymbol == NewtGetRefType(r, true));
00764 }
00765
00766
00767
00775 uint32_t NewtRefToHash(newtRefArg r)
00776 {
00777 newtSymDataRef sym;
00778
00779 sym = NewtRefToSymbol(r);
00780
00781 if (sym != NULL)
00782 return sym->hash;
00783 else
00784 return 0;
00785 }
00786
00787
00788
00797 bool NewtRefIsString(newtRefArg r)
00798 {
00799 return (kNewtString == NewtGetRefType(r, true));
00800 }
00801
00802
00803
00812 bool NewtRefIsInteger(newtRefArg r)
00813 {
00814 return (NewtRefIsInt30(r) || NewtRefIsInt32(r));
00815 }
00816
00817
00818
00826 int32_t NewtRefToInteger(newtRefArg r)
00827 {
00828 int32_t v = 0;
00829
00830 if (NewtRefIsInt30(r))
00831 v = NewtRefToInt30(r);
00832 else
00833 NewtGetObjData(r, (uint8_t *)&v, sizeof(v));
00834
00835 return v;
00836 }
00837
00838
00839
00848 bool NewtRefIsInt32(newtRefArg r)
00849 {
00850 return (kNewtInt32 == NewtGetRefType(r, true));
00851 }
00852
00853
00854
00863 bool NewtRefIsReal(newtRefArg r)
00864 {
00865 return (kNewtReal == NewtGetRefType(r, true));
00866 }
00867
00868
00869
00877 double NewtRefToReal(newtRefArg r)
00878 {
00879 double v = 0.0;
00880
00881 if (NewtRefIsInteger(r))
00882 v = NewtRefToInteger(r);
00883 else
00884 NewtGetObjData(r, (uint8_t *)&v, sizeof(v));
00885
00886 return v;
00887 }
00888
00889
00890
00899 bool NewtRefIsBinary(newtRefArg r)
00900 {
00901 if (NewtRefIsPointer(r))
00902 {
00903 uint16_t type;
00904
00905 type = NewtGetObjectType(NewtRefToPointer(r), false);
00906
00907 return (type == kNewtBinary);
00908 }
00909
00910 return false;
00911 }
00912
00913
00914
00922 void * NewtRefToData(newtRefArg r)
00923 {
00924 newtObjRef obj;
00925
00926 obj = NewtRefToPointer(r);
00927
00928 return NewtObjData(obj);
00929 }
00930
00931
00932
00941 bool NewtRefIsArray(newtRefArg r)
00942 {
00943 return (NewtGetRefType(r, true) == kNewtArray);
00944 }
00945
00946
00947
00956 bool NewtRefIsFrame(newtRefArg r)
00957 {
00958 return (NewtGetRefType(r, true) == kNewtFrame);
00959 }
00960
00961
00962
00971 bool NewtRefIsFrameOrArray(newtRefArg r)
00972 {
00973 uint16_t type;
00974
00975 type = NewtGetRefType(r, true);
00976 return (type == kNewtFrame || type == kNewtArray);
00977 }
00978
00979
00980
00989 bool NewtRefIsImmediate(newtRefArg r)
00990 {
00991 #ifdef __NAMED_MAGIC_POINTER__
00992 if (NewtRefIsMagicPointer(r))
00993 return false;
00994 #endif
00995
00996 return ! NewtRefIsPointer(r);
00997 }
00998
00999
01000
01009 bool NewtRefIsCodeBlock(newtRefArg r)
01010 {
01011 if (NewtRefIsFrame(r))
01012 {
01013 newtRefVar klass;
01014
01015 klass = NcClassOf(r);
01016
01017 if (NewtRefEqual(klass, NSSYM0(CodeBlock)))
01018 return true;
01019 }
01020
01021 return false;
01022 }
01023
01024
01025
01034 bool NewtRefIsNativeFn(newtRefArg r)
01035 {
01036 if (NewtRefIsFrame(r))
01037 return NewtRefEqual(NcClassOf(r), NSSYM0(_function.native0));
01038 else
01039 return false;
01040 }
01041
01042
01043
01052 bool NewtRefIsNativeFunc(newtRefArg r)
01053 {
01054 if (NewtRefIsFrame(r))
01055 return NewtRefEqual(NcClassOf(r), NSSYM0(_function.native));
01056 else
01057 return false;
01058 }
01059
01060
01061
01070 bool NewtRefIsFunction(newtRefArg r)
01071 {
01072 return (NewtRefFunctionType(r) != kNewtNotFunction);
01073 }
01074
01075
01076
01087 int NewtRefFunctionType(newtRefArg r)
01088 {
01089 if (NewtRefIsFrame(r))
01090 {
01091 newtRefVar klass;
01092
01093 klass = NcClassOf(r);
01094
01095 if (NewtRefEqual(klass, NSSYM0(CodeBlock)))
01096 return kNewtCodeBlock;
01097
01098 if (NewtRefEqual(klass, NSSYM0(_function.native0)))
01099 return kNewtNativeFn;
01100
01101 if (NewtRefEqual(klass, NSSYM0(_function.native)))
01102 return kNewtNativeFunc;
01103 }
01104
01105 return kNewtNotFunction;
01106 }
01107
01108
01109
01118 bool NewtRefIsRegex(newtRefArg r)
01119 {
01120 if (NewtRefIsFrame(r))
01121 {
01122 newtRefVar klass;
01123
01124 klass = NcClassOf(r);
01125
01126 if (NewtRefEqual(klass, NSSYM0(regex)))
01127 return true;
01128 }
01129
01130 return false;
01131 }
01132
01133
01134
01142 void * NewtRefToAddress(newtRefArg r)
01143 {
01144 if (NewtRefIsInteger(r))
01145 return (void *)(((uint32_t)NewtRefToInteger(r)) << NOBJ_ADDR_SHIFT);
01146 else
01147 return NULL;
01148 }
01149
01150
01151 #pragma mark -
01152
01163 newtRef NewtMakeBinary(newtRefArg klass, uint8_t * data, uint32_t size, bool literal)
01164 {
01165 newtObjRef obj;
01166
01167 obj = NewtObjAlloc(klass, size, 0, literal);
01168
01169 if (obj != NULL)
01170 {
01171 uint8_t * objData;
01172
01173 objData = NewtObjToBinary(obj);
01174
01175 if (data != NULL && 0 < size)
01176 {
01177 uint32_t setlen;
01178
01179 setlen = NewtObjSize(obj) - size;
01180
01181 if (0 < setlen)
01182 memset(objData + size, 0, setlen);
01183
01184 memcpy(objData, data, size);
01185 }
01186 else
01187 {
01188 memset(objData, 0, NewtObjSize(obj));
01189 }
01190
01191 return NewtMakePointer(obj);
01192 }
01193
01194 return kNewtRefUnbind;
01195 }
01196
01197
01198
01207 newtObjRef NewtObjBinarySetLength(newtObjRef obj, uint32_t n)
01208 {
01209 return NewtObjResize(obj, n);
01210 }
01211
01212
01213
01222 newtRef NewtBinarySetLength(newtRefArg r, uint32_t n)
01223 {
01224 newtObjRef obj;
01225
01226 obj = NewtRefToPointer(r);
01227 NewtObjBinarySetLength(obj, n);
01228
01229 return r;
01230 }
01231
01232
01233
01243 newtRef NewtMakeSymbol(const char *s)
01244 {
01245 return NewtLookupSymbolTable(s);
01246 }
01247
01248
01249
01257 uint32_t NewtObjSymbolLength(newtObjRef obj)
01258 {
01259 newtSymDataRef sym;
01260
01261 sym = NewtObjToSymbol(obj);
01262 return strlen(sym->name);
01263 }
01264
01265
01266
01275 newtRef NewtMakeString(const char *s, bool literal)
01276 {
01277 return NewtMakeBinary(NSSYM0(string), (uint8_t *)s, strlen(s) + 1, literal);
01278 }
01279
01280
01281
01291 newtRef NewtMakeString2(const char *s, uint32_t len, bool literal)
01292 {
01293 newtRefVar r;
01294
01295 r = NewtMakeBinary(NSSYM0(string), (uint8_t *)s, len + 1, literal);
01296
01297 if (NewtRefIsNotNIL(r))
01298 {
01299 char * objData;
01300
01301 objData = NewtRefToString(r);
01302
01303 if (s != NULL && 0 < len)
01304 {
01305
01306 objData[len] = '0';
01307 }
01308 else
01309 {
01310 objData[0] = '0';
01311 }
01312 }
01313
01314 return r;
01315 }
01316
01317
01318
01326 uint32_t NewtObjStringLength(newtObjRef obj)
01327 {
01328 char * s;
01329
01330 s = NewtObjToString(obj);
01331 return strlen(s);
01332 }
01333
01334
01335
01344 newtObjRef NewtObjStringSetLength(newtObjRef obj, uint32_t n)
01345 {
01346 return NewtObjBinarySetLength(obj, n + 1);
01347 }
01348
01349
01350
01359 newtRef NewtStringSetLength(newtRefArg r, uint32_t n)
01360 {
01361 newtObjRef obj;
01362
01363 obj = NewtRefToPointer(r);
01364 NewtObjStringSetLength(obj, n);
01365
01366 return r;
01367 }
01368
01369
01370
01378 newtRef NewtMakeInteger(int32_t v)
01379 {
01380 if (-536870912 <= v && v <= 536870911)
01381 {
01382 return NewtMakeInt30(v);
01383 }
01384 else
01385 {
01386 return NewtMakeInt32(v);
01387 }
01388 }
01389
01390
01391
01399 newtRef NewtMakeInt32(int32_t v)
01400 {
01401 return NewtMakeBinary(NSSYM0(int32), (uint8_t *)&v, sizeof(v), true);
01402 }
01403
01404
01405
01413 newtRef NewtMakeReal(double v)
01414 {
01415 return NewtMakeBinary(NSSYM0(real), (uint8_t *)&v, sizeof(v), true);
01416 }
01417
01418
01419
01428 newtRef NewtMakeArray(newtRefArg klass, uint32_t n)
01429 {
01430 return NewtMakeSlotsObj(klass, n, 0);
01431 }
01432
01433 void NewtMakeInitSlots(newtRefArg r, uint32_t st, uint32_t n, uint32_t step, newtRefVar v[])
01434 {
01435 if (v != NULL)
01436 {
01437 newtRef * slots;
01438 uint32_t i;
01439
01440 slots = NewtRefToSlots(r);
01441
01442 for (i = 0; i < n; i++)
01443 {
01444 slots[st + i] = *v;
01445 v += step;
01446 }
01447 }
01448 }
01449
01450
01451
01461 newtRef NewtMakeArray2(newtRefArg klass, uint32_t n, newtRefVar v[])
01462 {
01463 newtRefVar r;
01464
01465 r = NewtMakeSlotsObj(klass, n, 0);
01466
01467 if (NewtRefIsNotNIL(r))
01468 NewtMakeInitSlots(r, 0, n, 1, v);
01469
01470 return r;
01471 }
01472
01473
01474
01484 newtRef NewtMakeMap(newtRefArg superMap, uint32_t n, newtRefVar v[])
01485 {
01486 newtRefVar r;
01487 int32_t flags = 0;
01488
01489 r = NewtMakeSlotsObj(NewtMakeInteger(flags), n + 1, 0);
01490 NewtSetArraySlot(r, 0, superMap);
01491
01492 if (NewtRefIsNotNIL(superMap))
01493 {
01494 flags = NewtRefToInteger(NcClassOf(superMap));
01495 flags &= kNewtMapSorted;
01496 }
01497
01498 if (NewtRefIsNotNIL(r) && v != NULL)
01499 {
01500
01501
01502 newtRef * slots;
01503 uint32_t i;
01504
01505 slots = NewtRefToSlots(r);
01506
01507 for (i = 1; i <= n; i++)
01508 {
01509 slots[i] = *v;
01510
01511 if (slots[i] == NSSYM0(_proto))
01512 flags |= kNewtMapProto;
01513
01514 v += 2;
01515 }
01516 }
01517
01518 NcSetClass(r, NewtMakeInteger(flags));
01519
01520 return r;
01521 }
01522
01523
01524
01533 void NewtSetMapFlags(newtRefArg map, int32_t bit)
01534 {
01535 int32_t flags;
01536
01537 flags = NewtRefToInteger(NcClassOf(map));
01538 flags |= bit;
01539 NcSetClass(map, NewtMakeInteger(flags));
01540 }
01541
01542
01543
01552 void NewtClearMapFlags(newtRefArg map, int32_t bit)
01553 {
01554 int32_t flags;
01555
01556 flags = NewtRefToInteger(NcClassOf(map));
01557 flags &= bit;
01558 NcSetClass(map, NewtMakeInteger(flags));
01559 }
01560
01561
01562
01570 uint32_t NewtMapLength(newtRefArg map)
01571 {
01572 uint32_t len = 0;
01573 newtRefVar r;
01574
01575 r = (newtRef)map;
01576
01577 while (NewtRefIsNotNIL(r))
01578 {
01579 len += NewtLength(r) - 1;
01580 r = NewtGetArraySlot(r, 0);
01581 }
01582
01583 return len;
01584 }
01585
01586
01587
01596 newtRef NewtMakeFrame(newtRefArg map, uint32_t n)
01597 {
01598 newtRefVar m;
01599
01600 m = (newtRef)map;
01601
01602 if (NewtRefIsNIL(m))
01603 m = NewtMakeMap(kNewtRefNIL, n, NULL);
01604
01605 return NewtMakeSlotsObj(m, n, kNewtObjFrame);
01606 }
01607
01608
01609
01618 newtRef NewtMakeFrame2(uint32_t n, newtRefVar v[])
01619 {
01620 newtRefVar m;
01621 newtRefVar r;
01622
01623 m = NewtMakeMap(kNewtRefNIL, n, v);
01624 r = NewtMakeFrame(m, n);
01625
01626 if (NewtRefIsNotNIL(r))
01627 NewtMakeInitSlots(r, 0, n, 2, v + 1);
01628
01629 return r;
01630 }
01631
01632
01633
01643 newtRef NewtMakeSlotsObj(newtRefArg r, uint32_t n, uint16_t type)
01644 {
01645 newtObjRef obj;
01646 uint32_t size;
01647
01648 size = sizeof(newtRef) * n;
01649 obj = NewtObjAlloc(r, size, kNewtObjSlotted | type, false);
01650
01651 if (obj != NULL)
01652 {
01653 newtRef * slots;
01654 uint32_t i;
01655
01656 slots = NewtObjToSlots(obj);
01657
01658 for (i = 0; i < n; i++)
01659 {
01660 slots[i] = kNewtRefUnbind;
01661 }
01662
01663 return NewtMakePointer(obj);
01664 }
01665
01666 return kNewtRefNIL;
01667 }
01668
01669
01670
01678 uint32_t NewtObjSlotsLength(newtObjRef obj)
01679 {
01680 return NewtObjSize(obj) / sizeof(newtRef);
01681 }
01682
01683
01684
01694 newtObjRef NewtObjSlotsSetLength(newtObjRef obj, uint32_t n, newtRefArg v)
01695 {
01696 uint32_t size;
01697 uint32_t len;
01698
01699 len = NewtObjSlotsLength(obj);
01700 size = sizeof(newtRef) * n;
01701 obj = NewtObjResize(obj, size);
01702
01703 if (obj != NULL)
01704 {
01705 newtRef * slots;
01706 uint32_t i;
01707
01708 slots = NewtObjToSlots(obj);
01709
01710 for (i = len; i < n; i++)
01711 {
01712 slots[i] = v;
01713 }
01714 }
01715
01716 return obj;
01717 }
01718
01719
01720
01729 newtRef NewtObjAddArraySlot(newtObjRef obj, newtRefArg v)
01730 {
01731 uint32_t len;
01732
01733 len = NewtObjSlotsLength(obj);
01734 NewtObjSlotsSetLength(obj, len + 1, v);
01735
01736 return v;
01737 }
01738
01739
01740
01750 newtRef NewtSlotsSetLength(newtRefArg r, uint32_t n, newtRefArg v)
01751 {
01752 newtObjRef obj;
01753
01754 obj = NewtRefToPointer(r);
01755 NewtObjSlotsSetLength(obj, n, v);
01756
01757 return r;
01758 }
01759
01760
01761
01770 newtRef NewtSetLength(newtRefArg r, uint32_t n)
01771 {
01772 uint16_t type;
01773
01774 type = NewtGetRefType(r, true);
01775
01776 switch (type)
01777 {
01778 case kNewtBinary:
01779 NewtBinarySetLength(r, n);
01780 break;
01781
01782 case kNewtString:
01783 NewtStringSetLength(r, n);
01784 break;
01785
01786 case kNewtArray:
01787 case kNewtFrame:
01788 NewtSlotsSetLength(r, n, kNewtRefUnbind);
01789 break;
01790 }
01791
01792 return r;
01793 }
01794
01795
01796
01804 newtRef NewtMakeAddress(void * addr)
01805 {
01806 return NewtMakeInteger(((uint32_t)addr) >> NOBJ_ADDR_SHIFT);
01807 }
01808
01809
01810 #pragma mark -
01811
01819 newtRef NewtThrow0(int32_t err)
01820 {
01821 return NewtThrow(err, kNewtRefUnbind);
01822 }
01823
01824
01825