Coverage Report

Created: 2026-10-17 07:25

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
31.5k
{
44
31.5k
  txSlot* slot;
45
31.5k
  mxPush(mxObjectPrototype);
46
31.5k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
47
31.5k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Symbol_prototype_get_description), C_NULL, mxID(_description), XS_DONT_ENUM_FLAG);
48
31.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
49
31.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_valueOf), 0, mxID(_valueOf), XS_DONT_ENUM_FLAG);
50
31.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_toPrimitive), 1, mxID(_Symbol_toPrimitive), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
51
31.5k
  slot = fxNextStringXProperty(the, slot, "Symbol", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
52
31.5k
  mxSymbolPrototype = *the->stack;
53
31.5k
  slot = fxBuildHostConstructor(the, mxCallback(fx_Symbol), 0, mxID(_Symbol));
54
31.5k
  mxSymbolConstructor = *the->stack;
55
31.5k
  slot = fxLastProperty(the, slot);
56
31.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_for), 1, mxID(_for), XS_DONT_ENUM_FLAG);
57
31.5k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_keyFor), 1, mxID(_keyFor), XS_DONT_ENUM_FLAG);
58
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_asyncIterator), mxID(_asyncIterator), XS_GET_ONLY);
59
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_hasInstance), mxID(_hasInstance), XS_GET_ONLY);
60
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_isConcatSpreadable), mxID(_isConcatSpreadable), XS_GET_ONLY);
61
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_iterator), mxID(_iterator), XS_GET_ONLY);
62
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_match), mxID(_match), XS_GET_ONLY);
63
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_matchAll), mxID(_matchAll), XS_GET_ONLY);
64
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_replace), mxID(_replace), XS_GET_ONLY);
65
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_search), mxID(_search), XS_GET_ONLY);
66
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_species), mxID(_species), XS_GET_ONLY);
67
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_split), mxID(_split), XS_GET_ONLY);
68
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_toPrimitive), mxID(_toPrimitive), XS_GET_ONLY);
69
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_toStringTag), mxID(_toStringTag), XS_GET_ONLY);
70
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_unscopables), mxID(_unscopables), XS_GET_ONLY);
71
31.5k
#if mxExplicitResourceManagement  
72
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_asyncDispose), mxID(_asyncDispose), XS_GET_ONLY);
73
31.5k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_dispose), mxID(_dispose), XS_GET_ONLY);
74
31.5k
#endif
75
31.5k
  mxPop();
76
31.5k
}
77
78
txSlot* fxNewSymbolInstance(txMachine* the)
79
509k
{
80
509k
  txSlot* instance;
81
509k
  instance = fxNewObjectInstance(the);
82
509k
  fxNextSymbolProperty(the, instance, XS_NO_ID, XS_NO_ID, XS_INTERNAL_FLAG);
83
509k
  return instance;
84
509k
}
85
86
void fx_Symbol(txMachine* the)
87
1.21M
{
88
1.21M
  txSlot* instance;
89
1.21M
  txSlot* slot;
90
1.21M
  txSlot* property;
91
1.21M
  if (mxHasTarget)
92
3
    mxTypeError("new: Symbol");
93
1.21M
  instance = fxNewInstance(the);
94
1.21M
  property = fxNextUndefinedProperty(the, instance, XS_NO_ID, XS_INTERNAL_FLAG);
95
1.21M
  if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) {
96
1.08M
    fxToString(the, mxArgv(0));
97
1.08M
    fxNextSlotProperty(the, property, mxArgv(0), XS_NO_ID, XS_INTERNAL_FLAG);
98
1.08M
  }  
99
130k
  else
100
130k
    fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
101
1.21M
  slot = fxFindKey(the);
102
1.21M
  slot->flag = XS_INTERNAL_FLAG;
103
1.21M
  slot->kind = XS_REFERENCE_KIND;
104
1.21M
  slot->value.reference = instance;
105
1.21M
  property->kind = XS_SYMBOL_KIND;
106
1.21M
  property->value.symbol = slot->ID;
107
1.21M
  mxPop();
108
1.21M
  mxResult->kind = XS_SYMBOL_KIND;
109
1.21M
  mxResult->value.symbol = slot->ID;
110
1.21M
}
111
112
void fx_Symbol_for(txMachine* the)
113
1.20k
{
114
1.20k
  txSlot* arg;
115
1.20k
  txString string;
116
1.20k
  txU1* p;
117
1.20k
  txU4 sum;
118
1.20k
  txU4 modulo;
119
1.20k
  txSlot* result;
120
1.20k
  if (mxArgc < 1)
121
1
    arg = &mxUndefinedString;
122
1.20k
  else
123
1.20k
    arg = mxArgv(0);
124
1.20k
  string = fxToString(the, arg);
125
1.20k
  p = (txU1*)string;
126
1.20k
  sum = 0;
127
255k
  while(*p != 0) {
128
254k
    sum = (sum << 1) + *p++;
129
254k
  }
130
1.20k
  sum &= 0x7FFFFFFF;
131
1.20k
  modulo = sum % the->symbolModulo;
132
1.20k
  result = the->symbolTable[modulo];
133
2.86k
  while (result != C_NULL) {
134
2.16k
    if (result->value.key.sum == sum)
135
1.87k
      if (c_strcmp(result->value.key.string, string) == 0)
136
499
        break;
137
1.66k
    result = result->next;
138
1.66k
  }
139
1.20k
  if (result == C_NULL) {
140
703
    result = fxFindKey(the);
141
703
    result->next = the->symbolTable[modulo];
142
703
    result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG;
143
703
    result->kind = (arg->kind == XS_STRING_X_KIND) ? XS_KEY_X_KIND : XS_KEY_KIND;
144
703
    result->value.key.string = arg->value.string;
145
703
    result->value.key.sum = sum;
146
703
    the->symbolTable[modulo] = result;
147
703
  }
148
1.20k
  mxResult->kind = XS_SYMBOL_KIND;
149
1.20k
  mxResult->value.symbol = result->ID;
150
1.20k
}
151
152
void fx_Symbol_keyFor(txMachine* the)
153
23
{
154
23
  txSlot* key;
155
23
  if ((mxArgc == 0) || (mxArgv(0)->kind != XS_SYMBOL_KIND))
156
19
    mxTypeError("sym: not a symbol");
157
4
  key = fxGetKey(the, mxArgv(0)->value.symbol);
158
4
  if (((key->kind == XS_KEY_KIND) || (key->kind == XS_KEY_X_KIND)) && ((key->flag & XS_DONT_ENUM_FLAG) == 0)) {
159
1
    mxResult->kind = (key->kind == XS_KEY_KIND) ? XS_STRING_KIND : XS_STRING_X_KIND;
160
1
    mxResult->value.string = key->value.key.string;
161
1
  }
162
4
}
163
164
void fx_Symbol_prototype_get_description(txMachine* the)
165
58
{
166
58
  txSlot* slot = fxCheckSymbol(the, mxThis);
167
58
  if (!slot) mxTypeError("this: not a symbol");
168
35
  slot = fxGetKey(the, slot->value.symbol);
169
35
  if ((slot->kind == XS_KEY_KIND) || (slot->kind == XS_KEY_X_KIND)) {
170
2
    mxResult->kind = (slot->kind == XS_KEY_KIND) ? XS_STRING_KIND : XS_STRING_X_KIND;
171
2
    mxResult->value.string = slot->value.key.string;
172
2
  }
173
33
  else if (slot->kind == XS_REFERENCE_KIND) {
174
33
    slot = slot->value.reference->next->next;
175
33
    mxResult->kind = slot->kind;
176
33
    mxResult->value = slot->value;
177
33
  }
178
35
}
179
180
void fx_Symbol_prototype_toPrimitive(txMachine* the)
181
483
{
182
483
  txSlot* slot = fxCheckSymbol(the, mxThis);
183
483
  if (!slot) mxTypeError("this: not a symbol");
184
469
  mxResult->kind = slot->kind;
185
469
  mxResult->value = slot->value;
186
469
}
187
188
void fx_Symbol_prototype_toString(txMachine* the)
189
25
{
190
25
  txSlot* slot = fxCheckSymbol(the, mxThis);
191
25
  if (!slot) mxTypeError("this: not a symbol");
192
23
  mxResult->kind = slot->kind;
193
23
  mxResult->value = slot->value;
194
23
  fxSymbolToString(the, mxResult);
195
23
}
196
197
void fx_Symbol_prototype_valueOf(txMachine* the)
198
72
{
199
72
  txSlot* slot = fxCheckSymbol(the, mxThis);
200
72
  if (!slot) mxTypeError("this: not a symbol");
201
58
  mxResult->kind = slot->kind;
202
58
  mxResult->value = slot->value;
203
58
}
204
205
txSlot* fxCheckSymbol(txMachine* the, txSlot* it)
206
638
{
207
638
  txSlot* result = C_NULL;
208
638
  if (it->kind == XS_SYMBOL_KIND)
209
76
    result = it;
210
562
  else if (it->kind == XS_REFERENCE_KIND) {
211
524
    txSlot* instance = it->value.reference;
212
524
    it = instance->next;
213
524
    if ((it) && (it->flag & XS_INTERNAL_FLAG) && (it->kind == XS_SYMBOL_KIND))
214
509
      result = it;
215
524
  }
216
638
  return result;
217
638
}
218
219
void fxSymbolToString(txMachine* the, txSlot* slot)
220
49
{
221
49
  txSlot* key = fxGetKey(the, slot->value.symbol);
222
49
  fxStringX(the, slot, "Symbol(");
223
49
  if ((key->kind == XS_KEY_KIND) || (key->kind == XS_KEY_X_KIND))
224
2
    fxConcatString(the, slot, key);
225
47
  else if (key->kind == XS_REFERENCE_KIND) {
226
47
    key = key->value.reference->next->next;
227
47
    if (key->kind != XS_UNDEFINED_KIND)
228
17
      fxConcatString(the, slot, key);
229
47
  }
230
49
  fxConcatStringC(the, slot, ")");
231
49
}
232
233
txSlot* fxGetKey(txMachine* the, txID theID)
234
52.1M
{
235
52.1M
  txSlot* key;
236
52.1M
  mxCheck(the, 0 < theID);
237
52.1M
  mxCheck(the, theID < the->keyIndex);
238
52.1M
  if (theID < the->keyOffset)
239
0
    key = the->keyArrayHost[theID];
240
52.1M
  else
241
52.1M
    key = the->keyArray[theID - the->keyOffset];
242
52.1M
  mxCheck(the, key->kind != XS_UNDEFINED_KIND);
243
52.1M
  return key;
244
52.1M
}
245
246
char* fxGetKeyName(txMachine* the, txID theID)
247
3.67M
{
248
3.67M
  txSlot* key = fxGetKey(the, theID);
249
3.67M
  if (key->flag & XS_DONT_ENUM_FLAG)
250
3.67M
    return key->value.string;
251
0
  return C_NULL;
252
3.67M
}
253
254
char* fxGetKeyString(txMachine* the, txID theID, txBoolean* adorn)
255
3.92M
{
256
3.92M
  txString result = mxEmptyString.value.string;
257
3.92M
  txSlot* key = fxGetKey(the, theID);
258
3.92M
  txKind kind = key->kind;
259
3.92M
  if ((kind == XS_KEY_KIND) || (kind == XS_KEY_X_KIND))
260
3.92M
    result = key->value.key.string;
261
200
  else if (key->kind == XS_REFERENCE_KIND) {
262
200
    key = key->value.reference->next->next;
263
200
    if (key->kind != XS_UNDEFINED_KIND)
264
198
      result = key->value.string;
265
200
  }
266
3.92M
  if (adorn)
267
3.92M
    *adorn = (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
268
3.92M
  return result;
269
3.92M
}
270
271
void fxPushKeyString(txMachine* the, txID theID, txBoolean* adorn)
272
21.5M
{
273
21.5M
  txSlot* key = fxGetKey(the, theID);
274
21.5M
  txKind kind = key->kind;
275
21.5M
  if (adorn)
276
21.0M
    *adorn = (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
277
21.5M
  if (kind == XS_KEY_KIND)
278
20.6M
    mxPushString(key->value.key.string);
279
814k
  else if (kind == XS_KEY_X_KIND)
280
0
    mxPushStringX(key->value.key.string);
281
814k
  else {
282
814k
    mxCheck(the, key->kind == XS_REFERENCE_KIND);
283
814k
    key = key->value.reference->next->next;
284
814k
    if (key->kind == XS_UNDEFINED_KIND) {
285
2
      *adorn = 0;
286
2
      mxPush(mxEmptyString);
287
2
    }
288
814k
    else
289
814k
      mxPushSlot(key);
290
814k
  }
291
21.5M
}
292
293
txID fxFindName(txMachine* the, txString theString)
294
3.11k
{
295
3.11k
  txU1* aString;
296
3.11k
  txU4 aSum;
297
3.11k
  txU4 aModulo;
298
3.11k
  txSlot* result;
299
  
300
3.11k
  aString = (txU1*)theString;
301
3.11k
  aSum = 0;
302
75.5k
  while (*aString != 0) {
303
72.4k
    aSum = (aSum << 1) + *aString++;
304
72.4k
  }
305
3.11k
  aSum &= 0x7FFFFFFF;
306
3.11k
  aModulo = aSum % the->nameModulo;
307
3.11k
  result = the->nameTable[aModulo];
308
4.04k
  while (result != C_NULL) {
309
2.15k
    if (result->value.key.sum == aSum)
310
1.37k
      if (c_strcmp(result->value.key.string, theString) == 0)
311
1.22k
        return mxGetKeySlotID(result);
312
931
    result = result->next;
313
931
  }
314
1.88k
  return 0;
315
3.11k
}
316
317
txBoolean fxIsKeyName(txMachine* the, txID theID)
318
22.2M
{
319
22.2M
  txSlot* key = fxGetKey(the, theID);
320
22.2M
  return (key->flag & XS_DONT_ENUM_FLAG) ? 1 : 0;
321
22.2M
}
322
323
txBoolean fxIsKeySymbol(txMachine* the, txID theID)
324
148k
{
325
148k
  txSlot* key = fxGetKey(the, theID);
326
148k
  return (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
327
148k
}
328
329
txID fxNewName(txMachine* the, txSlot* theSlot)
330
5.37M
{
331
5.37M
  txU1* string;
332
5.37M
  txU4 sum;
333
5.37M
  txU4 modulo;
334
5.37M
  txSlot* result;
335
336
5.37M
  string = (txU1*)theSlot->value.string;
337
5.37M
  sum = 0;
338
85.6M
  while(*string != 0) {
339
80.3M
    sum = (sum << 1) + *string++;
340
80.3M
  }
341
5.37M
  sum &= 0x7FFFFFFF;
342
5.37M
  modulo = sum % the->nameModulo;
343
5.37M
  result = the->nameTable[modulo];
344
9.96M
  while (result != C_NULL) {
345
7.20M
    if (result->value.key.sum == sum) {
346
5.89M
      if (c_strcmp(result->value.key.string, theSlot->value.string) == 0)
347
2.61M
        return mxGetKeySlotID(result);
348
5.89M
    }
349
4.59M
    result = result->next;
350
4.59M
  }
351
2.75M
  result = fxFindKey(the);
352
2.75M
  result->next = the->nameTable[modulo];
353
2.75M
  result->flag = XS_INTERNAL_FLAG | XS_DONT_ENUM_FLAG;
354
2.75M
  result->kind = XS_KEY_KIND;
355
2.75M
  result->value.key.string = theSlot->value.string;
356
2.75M
  result->value.key.sum = sum;
357
2.75M
  the->nameTable[modulo] = result;
358
2.75M
  return result->ID;
359
5.37M
}
360
361
txID fxNewNameC(txMachine* the, txString theString)
362
21.1M
{
363
21.1M
  txU1* string;
364
21.1M
  txU4 sum;
365
21.1M
  txU4 modulo;
366
21.1M
  txSlot* result;
367
368
21.1M
  string = (txU1*)theString;
369
21.1M
  sum = 0;
370
195M
  while(c_read8(string) != 0) {
371
174M
    sum = (sum << 1) + c_read8(string++);
372
174M
  }
373
21.1M
  sum &= 0x7FFFFFFF;
374
21.1M
  modulo = sum % the->nameModulo;
375
21.1M
  result = the->nameTable[modulo];
376
51.6M
  while (result != C_NULL) {
377
34.0M
    if (result->value.key.sum == sum) {
378
26.9M
      if (c_strcmp(result->value.key.string, theString) == 0) {
379
3.47M
        txID id = mxGetKeySlotID(result);
380
3.47M
        if (id >= the->keyOffset)
381
3.47M
          result->flag |= XS_DONT_DELETE_FLAG;
382
3.47M
        return id;
383
3.47M
      }
384
26.9M
    }
385
30.5M
    result = result->next;
386
30.5M
  }
387
17.6M
  result = fxFindKey(the);
388
17.6M
  result->next = the->nameTable[modulo];
389
17.6M
  result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
390
17.6M
  result->kind = XS_KEY_KIND;
391
17.6M
  result->value.key.string = C_NULL;
392
17.6M
  result->value.key.sum = sum;
393
17.6M
  the->nameTable[modulo] = result;
394
17.6M
  result->value.key.string = (txString)fxNewChunk(the, mxStringLength(theString) + 1);
395
17.6M
  c_strcpy(result->value.key.string, theString);
396
17.6M
  return result->ID;
397
21.1M
}
398
399
txID fxNewNameX(txMachine* the, txString theString)
400
0
{
401
0
  txU1* string;
402
0
  txU4 sum;
403
0
  txU4 modulo;
404
0
  txSlot* result;
405
  
406
0
  string = (txU1*)theString;
407
0
  sum = 0;
408
0
  while (c_read8(string) != 0) {
409
0
    sum = (sum << 1) + c_read8(string++);
410
0
  }
411
0
  sum &= 0x7FFFFFFF;
412
0
  modulo = sum % the->nameModulo;
413
0
  result = the->nameTable[modulo];
414
0
  while (result != C_NULL) {
415
0
    if (result->value.key.sum == sum) {
416
0
      if (c_strcmp(result->value.key.string, theString) == 0) {
417
0
        txID id = mxGetKeySlotID(result);
418
0
        if (id >= the->keyOffset)
419
0
          result->flag |= XS_DONT_DELETE_FLAG;
420
0
        return id;
421
0
      }
422
0
    }
423
0
    result = result->next;
424
0
  }
425
0
  result = fxFindKey(the);
426
0
  result->next = the->nameTable[modulo];
427
0
  result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
428
0
  result->kind = XS_KEY_X_KIND;
429
0
  result->value.key.string = theString;
430
0
  result->value.key.sum = sum;
431
0
  the->nameTable[modulo] = result;
432
0
  return result->ID;
433
0
}
434
435
txSlot* fxAt(txMachine* the, txSlot* slot)
436
42.8M
{
437
42.8M
  txIndex index;
438
42.8M
  txString string;
439
42.8M
again:
440
42.8M
  if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the, slot->value.integer, &index)) {
441
9.55M
    slot->value.at.id = XS_NO_ID;
442
9.55M
    slot->value.at.index = index;
443
9.55M
  }
444
33.3M
  else if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the, slot->value.number, &index)) {
445
32.7M
    slot->value.at.id = XS_NO_ID;
446
32.7M
    slot->value.at.index = index;
447
32.7M
  }
448
563k
  else if (slot->kind == XS_SYMBOL_KIND) {
449
23.9k
    slot->value.at.id = slot->value.symbol;
450
23.9k
    slot->value.at.index = 0;
451
23.9k
  }
452
539k
    else {
453
539k
        if (slot->kind == XS_REFERENCE_KIND) {
454
9.02k
            fxToPrimitive(the, slot, XS_STRING_HINT);
455
9.02k
            goto again;
456
9.02k
        }
457
530k
        string = fxToString(the, slot);
458
530k
        if (fxStringToIndex(the, string, &index)) {
459
9.03k
            slot->value.at.id = XS_NO_ID;
460
9.03k
            slot->value.at.index = index;
461
9.03k
        }
462
521k
        else {
463
521k
      txID id;
464
521k
            if (slot->kind == XS_STRING_X_KIND)
465
0
                id = fxNewNameX(the, string);
466
521k
            else
467
521k
                id = fxNewName(the, slot);
468
521k
            slot->value.at.id = id;
469
521k
            slot->value.at.index = 0;
470
521k
        }
471
530k
    }
472
42.8M
  slot->kind = XS_AT_KIND;
473
42.8M
  return slot;
474
42.8M
}
475
476
void fxKeyAt(txMachine* the, txID id, txIndex index, txSlot* slot)
477
9.27M
{
478
9.27M
  if (id) {
479
182k
    txSlot* key = fxGetKey(the, id);
480
182k
    if (key->flag & XS_DONT_ENUM_FLAG) {
481
171k
      if (key->kind == XS_KEY_KIND) {
482
171k
        slot->kind = XS_STRING_KIND;
483
171k
        slot->value.string = key->value.key.string;
484
171k
      }
485
0
      else{
486
0
        slot->kind = XS_STRING_X_KIND;
487
0
        slot->value.string = key->value.key.string;
488
0
      }
489
171k
    }
490
11.6k
    else {
491
11.6k
      slot->kind = XS_SYMBOL_KIND;
492
11.6k
      slot->value.symbol = id;
493
11.6k
    }
494
182k
  }
495
9.09M
  else {
496
9.09M
    char buffer[16];
497
9.09M
    fxCopyStringC(the, slot, fxNumberToString(the, index, buffer, sizeof(buffer), 0, 0));
498
9.09M
  }
499
9.27M
}
500
501
void fxIDToString(txMachine* the, txID id, txString theBuffer, txSize theSize)
502
1.12M
{
503
1.12M
  if (id != XS_NO_ID) {
504
1.12M
    txBoolean adorn;
505
1.12M
    txString string = fxGetKeyString(the, id, &adorn);
506
1.12M
    if (adorn)
507
2
      c_snprintf(theBuffer, theSize, "[%s]", string);
508
1.12M
    else
509
1.12M
      c_snprintf(theBuffer, theSize, "%s", string);
510
1.12M
  }
511
28
  else {
512
28
    theBuffer[0] = '?';
513
28
    theBuffer[1] = 0;
514
28
  }
515
1.12M
}