Coverage Report

Created: 2026-01-10 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsSymbol.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2016-2017  Moddable Tech, Inc.
3
 *
4
 *   This file is part of the Moddable SDK Runtime.
5
 * 
6
 *   The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
 *   it under the terms of the GNU Lesser General Public License as published by
8
 *   the Free Software Foundation, either version 3 of the License, or
9
 *   (at your option) any later version.
10
 * 
11
 *   The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *   GNU Lesser General Public License for more details.
15
 * 
16
 *   You should have received a copy of the GNU Lesser General Public License
17
 *   along with the Moddable SDK Runtime.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * This file incorporates work covered by the following copyright and  
20
 * permission notice:  
21
 *
22
 *       Copyright (C) 2010-2016 Marvell International Ltd.
23
 *       Copyright (C) 2002-2010 Kinoma, Inc.
24
 *
25
 *       Licensed under the Apache License, Version 2.0 (the "License");
26
 *       you may not use this file except in compliance with the License.
27
 *       You may obtain a copy of the License at
28
 *
29
 *        http://www.apache.org/licenses/LICENSE-2.0
30
 *
31
 *       Unless required by applicable law or agreed to in writing, software
32
 *       distributed under the License is distributed on an "AS IS" BASIS,
33
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
 *       See the License for the specific language governing permissions and
35
 *       limitations under the License.
36
 */
37
38
#include "xsAll.h"
39
40
static txSlot* fxCheckSymbol(txMachine* the, txSlot* it);
41
42
void fxBuildSymbol(txMachine* the)
43
16.3k
{
44
16.3k
  txSlot* slot;
45
16.3k
  mxPush(mxObjectPrototype);
46
16.3k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
47
16.3k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Symbol_prototype_get_description), C_NULL, mxID(_description), XS_DONT_ENUM_FLAG);
48
16.3k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
49
16.3k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_valueOf), 0, mxID(_valueOf), XS_DONT_ENUM_FLAG);
50
16.3k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_toPrimitive), 1, mxID(_Symbol_toPrimitive), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
51
16.3k
  slot = fxNextStringXProperty(the, slot, "Symbol", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
52
16.3k
  mxSymbolPrototype = *the->stack;
53
16.3k
  slot = fxBuildHostConstructor(the, mxCallback(fx_Symbol), 0, mxID(_Symbol));
54
16.3k
  mxSymbolConstructor = *the->stack;
55
16.3k
  slot = fxLastProperty(the, slot);
56
16.3k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_for), 1, mxID(_for), XS_DONT_ENUM_FLAG);
57
16.3k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_keyFor), 1, mxID(_keyFor), XS_DONT_ENUM_FLAG);
58
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_asyncIterator), mxID(_asyncIterator), XS_GET_ONLY);
59
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_hasInstance), mxID(_hasInstance), XS_GET_ONLY);
60
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_isConcatSpreadable), mxID(_isConcatSpreadable), XS_GET_ONLY);
61
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_iterator), mxID(_iterator), XS_GET_ONLY);
62
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_match), mxID(_match), XS_GET_ONLY);
63
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_matchAll), mxID(_matchAll), XS_GET_ONLY);
64
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_replace), mxID(_replace), XS_GET_ONLY);
65
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_search), mxID(_search), XS_GET_ONLY);
66
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_species), mxID(_species), XS_GET_ONLY);
67
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_split), mxID(_split), XS_GET_ONLY);
68
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_toPrimitive), mxID(_toPrimitive), XS_GET_ONLY);
69
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_toStringTag), mxID(_toStringTag), XS_GET_ONLY);
70
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_unscopables), mxID(_unscopables), XS_GET_ONLY);
71
16.3k
#if mxExplicitResourceManagement  
72
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_asyncDispose), mxID(_asyncDispose), XS_GET_ONLY);
73
16.3k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_dispose), mxID(_dispose), XS_GET_ONLY);
74
16.3k
#endif
75
16.3k
  mxPop();
76
16.3k
}
77
78
txSlot* fxNewSymbolInstance(txMachine* the)
79
99.3k
{
80
99.3k
  txSlot* instance;
81
99.3k
  instance = fxNewObjectInstance(the);
82
99.3k
  fxNextSymbolProperty(the, instance, XS_NO_ID, XS_NO_ID, XS_INTERNAL_FLAG);
83
99.3k
  return instance;
84
99.3k
}
85
86
void fx_Symbol(txMachine* the)
87
325k
{
88
325k
  txSlot* instance;
89
325k
  txSlot* slot;
90
325k
  txSlot* property;
91
325k
  if (mxTarget->kind != XS_UNDEFINED_KIND)
92
2
    mxTypeError("new: Symbol");
93
325k
  instance = fxNewInstance(the);
94
325k
  property = fxNextUndefinedProperty(the, instance, XS_NO_ID, XS_INTERNAL_FLAG);
95
325k
  if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) {
96
303k
    fxToString(the, mxArgv(0));
97
303k
    fxNextSlotProperty(the, property, mxArgv(0), XS_NO_ID, XS_INTERNAL_FLAG);
98
303k
  }  
99
21.4k
  else
100
21.4k
    fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
101
325k
  slot = fxFindKey(the);
102
325k
  slot->flag = XS_INTERNAL_FLAG;
103
325k
  slot->kind = XS_REFERENCE_KIND;
104
325k
  slot->value.reference = instance;
105
325k
  property->kind = XS_SYMBOL_KIND;
106
325k
  property->value.symbol = slot->ID;
107
325k
  mxPop();
108
325k
  mxResult->kind = XS_SYMBOL_KIND;
109
325k
  mxResult->value.symbol = slot->ID;
110
325k
}
111
112
void fx_Symbol_for(txMachine* the)
113
158
{
114
158
  txString string;
115
158
  txU1* p;
116
158
  txU4 sum;
117
158
  txU4 modulo;
118
158
  txSlot* result;
119
158
  if (mxArgc < 1)
120
0
    mxSyntaxError("no key");
121
158
  string = fxToString(the, mxArgv(0));
122
158
  p = (txU1*)string;
123
158
  sum = 0;
124
31.2k
  while(*p != 0) {
125
31.1k
    sum = (sum << 1) + *p++;
126
31.1k
  }
127
158
  sum &= 0x7FFFFFFF;
128
158
  modulo = sum % the->symbolModulo;
129
158
  result = the->symbolTable[modulo];
130
321
  while (result != C_NULL) {
131
201
    if (result->value.key.sum == sum)
132
194
      if (c_strcmp(result->value.key.string, string) == 0)
133
38
        break;
134
163
    result = result->next;
135
163
  }
136
158
  if (result == C_NULL) {
137
120
    result = fxFindKey(the);
138
120
    result->next = the->symbolTable[modulo];
139
120
    result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG;
140
120
    result->kind = (mxArgv(0)->kind == XS_STRING_X_KIND) ? XS_KEY_X_KIND : XS_KEY_KIND;
141
120
    result->value.key.string = mxArgv(0)->value.string;
142
120
    result->value.key.sum = sum;
143
120
    the->symbolTable[modulo] = result;
144
120
  }
145
158
  mxResult->kind = XS_SYMBOL_KIND;
146
158
  mxResult->value.symbol = result->ID;
147
158
}
148
149
void fx_Symbol_keyFor(txMachine* the)
150
23
{
151
23
  txSlot* key;
152
23
  if ((mxArgc == 0) || (mxArgv(0)->kind != XS_SYMBOL_KIND))
153
19
    mxTypeError("sym: not a symbol");
154
4
  key = fxGetKey(the, mxArgv(0)->value.symbol);
155
4
  if (((key->kind == XS_KEY_KIND) || (key->kind == XS_KEY_X_KIND)) && ((key->flag & XS_DONT_ENUM_FLAG) == 0)) {
156
1
    mxResult->kind = (key->kind == XS_KEY_KIND) ? XS_STRING_KIND : XS_STRING_X_KIND;
157
1
    mxResult->value.string = key->value.key.string;
158
1
  }
159
4
}
160
161
void fx_Symbol_prototype_get_description(txMachine* the)
162
40
{
163
40
  txSlot* slot = fxCheckSymbol(the, mxThis);
164
40
  if (!slot) mxTypeError("this: not a symbol");
165
28
  slot = fxGetKey(the, slot->value.symbol);
166
28
  if ((slot->kind == XS_KEY_KIND) || (slot->kind == XS_KEY_X_KIND)) {
167
3
    mxResult->kind = (slot->kind == XS_KEY_KIND) ? XS_STRING_KIND : XS_STRING_X_KIND;
168
3
    mxResult->value.string = slot->value.key.string;
169
3
  }
170
25
  else if (slot->kind == XS_REFERENCE_KIND) {
171
25
    slot = slot->value.reference->next->next;
172
25
    mxResult->kind = slot->kind;
173
25
    mxResult->value = slot->value;
174
25
  }
175
28
}
176
177
void fx_Symbol_prototype_toPrimitive(txMachine* the)
178
564
{
179
564
  txSlot* slot = fxCheckSymbol(the, mxThis);
180
564
  if (!slot) mxTypeError("this: not a symbol");
181
554
  mxResult->kind = slot->kind;
182
554
  mxResult->value = slot->value;
183
554
}
184
185
void fx_Symbol_prototype_toString(txMachine* the)
186
20
{
187
20
  txSlot* slot = fxCheckSymbol(the, mxThis);
188
20
  if (!slot) mxTypeError("this: not a symbol");
189
20
  mxResult->kind = slot->kind;
190
20
  mxResult->value = slot->value;
191
20
  fxSymbolToString(the, mxResult);
192
20
}
193
194
void fx_Symbol_prototype_valueOf(txMachine* the)
195
31
{
196
31
  txSlot* slot = fxCheckSymbol(the, mxThis);
197
31
  if (!slot) mxTypeError("this: not a symbol");
198
16
  mxResult->kind = slot->kind;
199
16
  mxResult->value = slot->value;
200
16
}
201
202
txSlot* fxCheckSymbol(txMachine* the, txSlot* it)
203
655
{
204
655
  txSlot* result = C_NULL;
205
655
  if (it->kind == XS_SYMBOL_KIND)
206
30
    result = it;
207
625
  else if (it->kind == XS_REFERENCE_KIND) {
208
599
    txSlot* instance = it->value.reference;
209
599
    it = instance->next;
210
599
    if ((it) && (it->flag & XS_INTERNAL_FLAG) && (it->kind == XS_SYMBOL_KIND))
211
588
      result = it;
212
599
  }
213
655
  return result;
214
655
}
215
216
void fxSymbolToString(txMachine* the, txSlot* slot)
217
50
{
218
50
  txSlot* key = fxGetKey(the, slot->value.symbol);
219
50
  fxStringX(the, slot, "Symbol(");
220
50
  if ((key->kind == XS_KEY_KIND) || (key->kind == XS_KEY_X_KIND))
221
2
    fxConcatString(the, slot, key);
222
48
  else if (key->kind == XS_REFERENCE_KIND) {
223
48
    key = key->value.reference->next->next;
224
48
    if (key->kind != XS_UNDEFINED_KIND)
225
13
      fxConcatString(the, slot, key);
226
48
  }
227
50
  fxConcatStringC(the, slot, ")");
228
50
}
229
230
txSlot* fxGetKey(txMachine* the, txID theID)
231
17.3M
{
232
17.3M
  txSlot* key;
233
17.3M
  mxCheck(the, 0 < theID);
234
17.3M
  mxCheck(the, theID < the->keyIndex);
235
17.3M
  if (theID < the->keyOffset)
236
0
    key = the->keyArrayHost[theID];
237
17.3M
  else
238
17.3M
    key = the->keyArray[theID - the->keyOffset];
239
17.3M
  mxCheck(the, key->kind != XS_UNDEFINED_KIND);
240
17.3M
  return key;
241
17.3M
}
242
243
char* fxGetKeyName(txMachine* the, txID theID)
244
1.22M
{
245
1.22M
  txSlot* key = fxGetKey(the, theID);
246
1.22M
  if (key->flag & XS_DONT_ENUM_FLAG)
247
1.22M
    return key->value.string;
248
0
  return C_NULL;
249
1.22M
}
250
251
char* fxGetKeyString(txMachine* the, txID theID, txBoolean* adorn)
252
1.15M
{
253
1.15M
  txString result = mxEmptyString.value.string;
254
1.15M
  txSlot* key = fxGetKey(the, theID);
255
1.15M
  txKind kind = key->kind;
256
1.15M
  if ((kind == XS_KEY_KIND) || (kind == XS_KEY_X_KIND))
257
1.15M
    result = key->value.key.string;
258
152
  else if (key->kind == XS_REFERENCE_KIND) {
259
152
    key = key->value.reference->next->next;
260
152
    if (key->kind != XS_UNDEFINED_KIND)
261
150
      result = key->value.string;
262
152
  }
263
1.15M
  if (adorn)
264
1.15M
    *adorn = (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
265
1.15M
  return result;
266
1.15M
}
267
268
void fxPushKeyString(txMachine* the, txID theID, txBoolean* adorn)
269
10.5M
{
270
10.5M
  txSlot* key = fxGetKey(the, theID);
271
10.5M
  txKind kind = key->kind;
272
10.5M
  if (adorn)
273
10.2M
    *adorn = (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
274
10.5M
  if (kind == XS_KEY_KIND)
275
10.0M
    mxPushString(key->value.key.string);
276
450k
  else if (kind == XS_KEY_X_KIND)
277
0
    mxPushStringX(key->value.key.string);
278
450k
  else {
279
450k
    mxCheck(the, key->kind == XS_REFERENCE_KIND);
280
450k
    key = key->value.reference->next->next;
281
450k
    if (key->kind == XS_UNDEFINED_KIND) {
282
2
      *adorn = 0;
283
2
      mxPush(mxEmptyString);
284
2
    }
285
450k
    else
286
450k
      mxPushSlot(key);
287
450k
  }
288
10.5M
}
289
290
txID fxFindName(txMachine* the, txString theString)
291
2.01k
{
292
2.01k
  txU1* aString;
293
2.01k
  txU4 aSum;
294
2.01k
  txU4 aModulo;
295
2.01k
  txSlot* result;
296
  
297
2.01k
  aString = (txU1*)theString;
298
2.01k
  aSum = 0;
299
40.3k
  while (*aString != 0) {
300
38.3k
    aSum = (aSum << 1) + *aString++;
301
38.3k
  }
302
2.01k
  aSum &= 0x7FFFFFFF;
303
2.01k
  aModulo = aSum % the->nameModulo;
304
2.01k
  result = the->nameTable[aModulo];
305
2.60k
  while (result != C_NULL) {
306
1.22k
    if (result->value.key.sum == aSum)
307
894
      if (c_strcmp(result->value.key.string, theString) == 0)
308
643
        return mxGetKeySlotID(result);
309
586
    result = result->next;
310
586
  }
311
1.37k
  return 0;
312
2.01k
}
313
314
txBoolean fxIsKeyName(txMachine* the, txID theID)
315
4.19M
{
316
4.19M
  txSlot* key = fxGetKey(the, theID);
317
4.19M
  return (key->flag & XS_DONT_ENUM_FLAG) ? 1 : 0;
318
4.19M
}
319
320
txBoolean fxIsKeySymbol(txMachine* the, txID theID)
321
102k
{
322
102k
  txSlot* key = fxGetKey(the, theID);
323
102k
  return (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
324
102k
}
325
326
txID fxNewName(txMachine* the, txSlot* theSlot)
327
1.91M
{
328
1.91M
  txU1* string;
329
1.91M
  txU4 sum;
330
1.91M
  txU4 modulo;
331
1.91M
  txSlot* result;
332
333
1.91M
  string = (txU1*)theSlot->value.string;
334
1.91M
  sum = 0;
335
28.5M
  while(*string != 0) {
336
26.6M
    sum = (sum << 1) + *string++;
337
26.6M
  }
338
1.91M
  sum &= 0x7FFFFFFF;
339
1.91M
  modulo = sum % the->nameModulo;
340
1.91M
  result = the->nameTable[modulo];
341
13.8M
  while (result != C_NULL) {
342
13.0M
    if (result->value.key.sum == sum) {
343
12.7M
      if (c_strcmp(result->value.key.string, theSlot->value.string) == 0)
344
1.08M
        return mxGetKeySlotID(result);
345
12.7M
    }
346
11.9M
    result = result->next;
347
11.9M
  }
348
829k
  result = fxFindKey(the);
349
829k
  result->next = the->nameTable[modulo];
350
829k
  result->flag = XS_INTERNAL_FLAG | XS_DONT_ENUM_FLAG;
351
829k
  result->kind = XS_KEY_KIND;
352
829k
  result->value.key.string = theSlot->value.string;
353
829k
  result->value.key.sum = sum;
354
829k
  the->nameTable[modulo] = result;
355
829k
  return result->ID;
356
1.91M
}
357
358
txID fxNewNameC(txMachine* the, txString theString)
359
9.40M
{
360
9.40M
  txU1* string;
361
9.40M
  txU4 sum;
362
9.40M
  txU4 modulo;
363
9.40M
  txSlot* result;
364
365
9.40M
  string = (txU1*)theString;
366
9.40M
  sum = 0;
367
85.3M
  while(c_read8(string) != 0) {
368
75.9M
    sum = (sum << 1) + c_read8(string++);
369
75.9M
  }
370
9.40M
  sum &= 0x7FFFFFFF;
371
9.40M
  modulo = sum % the->nameModulo;
372
9.40M
  result = the->nameTable[modulo];
373
24.7M
  while (result != C_NULL) {
374
15.7M
    if (result->value.key.sum == sum) {
375
13.1M
      if (c_strcmp(result->value.key.string, theString) == 0) {
376
444k
        txID id = mxGetKeySlotID(result);
377
444k
        if (id >= the->keyOffset)
378
444k
          result->flag |= XS_DONT_DELETE_FLAG;
379
444k
        return id;
380
444k
      }
381
13.1M
    }
382
15.3M
    result = result->next;
383
15.3M
  }
384
8.95M
  result = fxFindKey(the);
385
8.95M
  result->next = the->nameTable[modulo];
386
8.95M
  result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
387
8.95M
  result->kind = XS_KEY_KIND;
388
8.95M
  result->value.key.string = C_NULL;
389
8.95M
  result->value.key.sum = sum;
390
8.95M
  the->nameTable[modulo] = result;
391
8.95M
  result->value.key.string = (txString)fxNewChunk(the, mxStringLength(theString) + 1);
392
8.95M
  c_strcpy(result->value.key.string, theString);
393
8.95M
  return result->ID;
394
9.40M
}
395
396
txID fxNewNameX(txMachine* the, txString theString)
397
0
{
398
0
  txU1* string;
399
0
  txU4 sum;
400
0
  txU4 modulo;
401
0
  txSlot* result;
402
  
403
0
  string = (txU1*)theString;
404
0
  sum = 0;
405
0
  while (c_read8(string) != 0) {
406
0
    sum = (sum << 1) + c_read8(string++);
407
0
  }
408
0
  sum &= 0x7FFFFFFF;
409
0
  modulo = sum % the->nameModulo;
410
0
  result = the->nameTable[modulo];
411
0
  while (result != C_NULL) {
412
0
    if (result->value.key.sum == sum) {
413
0
      if (c_strcmp(result->value.key.string, theString) == 0) {
414
0
        txID id = mxGetKeySlotID(result);
415
0
        if (id >= the->keyOffset)
416
0
          result->flag |= XS_DONT_DELETE_FLAG;
417
0
        return id;
418
0
      }
419
0
    }
420
0
    result = result->next;
421
0
  }
422
0
  result = fxFindKey(the);
423
0
  result->next = the->nameTable[modulo];
424
0
  result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
425
0
  result->kind = XS_KEY_X_KIND;
426
0
  result->value.key.string = theString;
427
0
  result->value.key.sum = sum;
428
0
  the->nameTable[modulo] = result;
429
0
  return result->ID;
430
0
}
431
432
txSlot* fxAt(txMachine* the, txSlot* slot)
433
15.7M
{
434
15.7M
  txIndex index;
435
15.7M
  txString string;
436
15.7M
again:
437
15.7M
  if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the, slot->value.integer, &index)) {
438
3.50M
    slot->value.at.id = XS_NO_ID;
439
3.50M
    slot->value.at.index = index;
440
3.50M
  }
441
12.2M
  else if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the, slot->value.number, &index)) {
442
12.0M
    slot->value.at.id = XS_NO_ID;
443
12.0M
    slot->value.at.index = index;
444
12.0M
  }
445
265k
  else if (slot->kind == XS_SYMBOL_KIND) {
446
4.57k
    slot->value.at.id = slot->value.symbol;
447
4.57k
    slot->value.at.index = 0;
448
4.57k
  }
449
260k
    else {
450
260k
        if (slot->kind == XS_REFERENCE_KIND) {
451
3.74k
            fxToPrimitive(the, slot, XS_STRING_HINT);
452
3.74k
            goto again;
453
3.74k
        }
454
256k
        string = fxToString(the, slot);
455
256k
        if (fxStringToIndex(the, string, &index)) {
456
1.01k
            slot->value.at.id = XS_NO_ID;
457
1.01k
            slot->value.at.index = index;
458
1.01k
        }
459
255k
        else {
460
255k
      txID id;
461
255k
            if (slot->kind == XS_STRING_X_KIND)
462
0
                id = fxNewNameX(the, string);
463
255k
            else
464
255k
                id = fxNewName(the, slot);
465
255k
            slot->value.at.id = id;
466
255k
            slot->value.at.index = 0;
467
255k
        }
468
256k
    }
469
15.7M
  slot->kind = XS_AT_KIND;
470
15.7M
  return slot;
471
15.7M
}
472
473
void fxKeyAt(txMachine* the, txID id, txIndex index, txSlot* slot)
474
2.42M
{
475
2.42M
  if (id) {
476
93.8k
    txSlot* key = fxGetKey(the, id);
477
93.8k
    if (key->flag & XS_DONT_ENUM_FLAG) {
478
89.6k
      if (key->kind == XS_KEY_KIND) {
479
89.6k
        slot->kind = XS_STRING_KIND;
480
89.6k
        slot->value.string = key->value.key.string;
481
89.6k
      }
482
0
      else{
483
0
        slot->kind = XS_STRING_X_KIND;
484
0
        slot->value.string = key->value.key.string;
485
0
      }
486
89.6k
    }
487
4.22k
    else {
488
4.22k
      slot->kind = XS_SYMBOL_KIND;
489
4.22k
      slot->value.symbol = id;
490
4.22k
    }
491
93.8k
  }
492
2.33M
  else {
493
2.33M
    char buffer[16];
494
2.33M
    fxCopyStringC(the, slot, fxNumberToString(the, index, buffer, sizeof(buffer), 0, 0));
495
2.33M
  }
496
2.42M
}
497
498
void fxIDToString(txMachine* the, txID id, txString theBuffer, txSize theSize)
499
206k
{
500
206k
  if (id != XS_NO_ID) {
501
206k
    txBoolean adorn;
502
206k
    txString string = fxGetKeyString(the, id, &adorn);
503
206k
    if (adorn)
504
2
      c_snprintf(theBuffer, theSize, "[%s]", string);
505
206k
    else
506
206k
      c_snprintf(theBuffer, theSize, "%s", string);
507
206k
  }
508
12
  else {
509
12
    theBuffer[0] = '?';
510
12
    theBuffer[1] = 0;
511
12
  }
512
206k
}