Coverage Report

Created: 2026-09-28 06:57

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
32.1k
{
44
32.1k
  txSlot* slot;
45
32.1k
  mxPush(mxObjectPrototype);
46
32.1k
  slot = fxLastProperty(the, fxNewObjectInstance(the));
47
32.1k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Symbol_prototype_get_description), C_NULL, mxID(_description), XS_DONT_ENUM_FLAG);
48
32.1k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
49
32.1k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_valueOf), 0, mxID(_valueOf), XS_DONT_ENUM_FLAG);
50
32.1k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_prototype_toPrimitive), 1, mxID(_Symbol_toPrimitive), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
51
32.1k
  slot = fxNextStringXProperty(the, slot, "Symbol", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
52
32.1k
  mxSymbolPrototype = *the->stack;
53
32.1k
  slot = fxBuildHostConstructor(the, mxCallback(fx_Symbol), 0, mxID(_Symbol));
54
32.1k
  mxSymbolConstructor = *the->stack;
55
32.1k
  slot = fxLastProperty(the, slot);
56
32.1k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_for), 1, mxID(_for), XS_DONT_ENUM_FLAG);
57
32.1k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Symbol_keyFor), 1, mxID(_keyFor), XS_DONT_ENUM_FLAG);
58
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_asyncIterator), mxID(_asyncIterator), XS_GET_ONLY);
59
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_hasInstance), mxID(_hasInstance), XS_GET_ONLY);
60
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_isConcatSpreadable), mxID(_isConcatSpreadable), XS_GET_ONLY);
61
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_iterator), mxID(_iterator), XS_GET_ONLY);
62
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_match), mxID(_match), XS_GET_ONLY);
63
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_matchAll), mxID(_matchAll), XS_GET_ONLY);
64
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_replace), mxID(_replace), XS_GET_ONLY);
65
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_search), mxID(_search), XS_GET_ONLY);
66
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_species), mxID(_species), XS_GET_ONLY);
67
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_split), mxID(_split), XS_GET_ONLY);
68
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_toPrimitive), mxID(_toPrimitive), XS_GET_ONLY);
69
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_toStringTag), mxID(_toStringTag), XS_GET_ONLY);
70
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_unscopables), mxID(_unscopables), XS_GET_ONLY);
71
32.1k
#if mxExplicitResourceManagement  
72
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_asyncDispose), mxID(_asyncDispose), XS_GET_ONLY);
73
32.1k
  slot = fxNextSymbolProperty(the, slot, mxID(_Symbol_dispose), mxID(_dispose), XS_GET_ONLY);
74
32.1k
#endif
75
32.1k
  mxPop();
76
32.1k
}
77
78
txSlot* fxNewSymbolInstance(txMachine* the)
79
542k
{
80
542k
  txSlot* instance;
81
542k
  instance = fxNewObjectInstance(the);
82
542k
  fxNextSymbolProperty(the, instance, XS_NO_ID, XS_NO_ID, XS_INTERNAL_FLAG);
83
542k
  return instance;
84
542k
}
85
86
void fx_Symbol(txMachine* the)
87
1.08M
{
88
1.08M
  txSlot* instance;
89
1.08M
  txSlot* slot;
90
1.08M
  txSlot* property;
91
1.08M
  if (mxHasTarget)
92
3
    mxTypeError("new: Symbol");
93
1.08M
  instance = fxNewInstance(the);
94
1.08M
  property = fxNextUndefinedProperty(the, instance, XS_NO_ID, XS_INTERNAL_FLAG);
95
1.08M
  if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) {
96
967k
    fxToString(the, mxArgv(0));
97
967k
    fxNextSlotProperty(the, property, mxArgv(0), XS_NO_ID, XS_INTERNAL_FLAG);
98
967k
  }  
99
118k
  else
100
118k
    fxNextUndefinedProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
101
1.08M
  slot = fxFindKey(the);
102
1.08M
  slot->flag = XS_INTERNAL_FLAG;
103
1.08M
  slot->kind = XS_REFERENCE_KIND;
104
1.08M
  slot->value.reference = instance;
105
1.08M
  property->kind = XS_SYMBOL_KIND;
106
1.08M
  property->value.symbol = slot->ID;
107
1.08M
  mxPop();
108
1.08M
  mxResult->kind = XS_SYMBOL_KIND;
109
1.08M
  mxResult->value.symbol = slot->ID;
110
1.08M
}
111
112
void fx_Symbol_for(txMachine* the)
113
1.42k
{
114
1.42k
  txString string;
115
1.42k
  txU1* p;
116
1.42k
  txU4 sum;
117
1.42k
  txU4 modulo;
118
1.42k
  txSlot* result;
119
1.42k
  if (mxArgc < 1)
120
1
    mxSyntaxError("no key");
121
1.42k
  string = fxToString(the, mxArgv(0));
122
1.42k
  p = (txU1*)string;
123
1.42k
  sum = 0;
124
306k
  while(*p != 0) {
125
304k
    sum = (sum << 1) + *p++;
126
304k
  }
127
1.42k
  sum &= 0x7FFFFFFF;
128
1.42k
  modulo = sum % the->symbolModulo;
129
1.42k
  result = the->symbolTable[modulo];
130
3.70k
  while (result != C_NULL) {
131
2.96k
    if (result->value.key.sum == sum)
132
2.67k
      if (c_strcmp(result->value.key.string, string) == 0)
133
692
        break;
134
2.27k
    result = result->next;
135
2.27k
  }
136
1.42k
  if (result == C_NULL) {
137
733
    result = fxFindKey(the);
138
733
    result->next = the->symbolTable[modulo];
139
733
    result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG;
140
733
    result->kind = (mxArgv(0)->kind == XS_STRING_X_KIND) ? XS_KEY_X_KIND : XS_KEY_KIND;
141
733
    result->value.key.string = mxArgv(0)->value.string;
142
733
    result->value.key.sum = sum;
143
733
    the->symbolTable[modulo] = result;
144
733
  }
145
1.42k
  mxResult->kind = XS_SYMBOL_KIND;
146
1.42k
  mxResult->value.symbol = result->ID;
147
1.42k
}
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
48
{
163
48
  txSlot* slot = fxCheckSymbol(the, mxThis);
164
48
  if (!slot) mxTypeError("this: not a symbol");
165
35
  slot = fxGetKey(the, slot->value.symbol);
166
35
  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
32
  else if (slot->kind == XS_REFERENCE_KIND) {
171
32
    slot = slot->value.reference->next->next;
172
32
    mxResult->kind = slot->kind;
173
32
    mxResult->value = slot->value;
174
32
  }
175
35
}
176
177
void fx_Symbol_prototype_toPrimitive(txMachine* the)
178
1.01k
{
179
1.01k
  txSlot* slot = fxCheckSymbol(the, mxThis);
180
1.01k
  if (!slot) mxTypeError("this: not a symbol");
181
1.00k
  mxResult->kind = slot->kind;
182
1.00k
  mxResult->value = slot->value;
183
1.00k
}
184
185
void fx_Symbol_prototype_toString(txMachine* the)
186
32
{
187
32
  txSlot* slot = fxCheckSymbol(the, mxThis);
188
32
  if (!slot) mxTypeError("this: not a symbol");
189
30
  mxResult->kind = slot->kind;
190
30
  mxResult->value = slot->value;
191
30
  fxSymbolToString(the, mxResult);
192
30
}
193
194
void fx_Symbol_prototype_valueOf(txMachine* the)
195
25
{
196
25
  txSlot* slot = fxCheckSymbol(the, mxThis);
197
25
  if (!slot) mxTypeError("this: not a symbol");
198
14
  mxResult->kind = slot->kind;
199
14
  mxResult->value = slot->value;
200
14
}
201
202
txSlot* fxCheckSymbol(txMachine* the, txSlot* it)
203
1.12k
{
204
1.12k
  txSlot* result = C_NULL;
205
1.12k
  if (it->kind == XS_SYMBOL_KIND)
206
42
    result = it;
207
1.07k
  else if (it->kind == XS_REFERENCE_KIND) {
208
1.05k
    txSlot* instance = it->value.reference;
209
1.05k
    it = instance->next;
210
1.05k
    if ((it) && (it->flag & XS_INTERNAL_FLAG) && (it->kind == XS_SYMBOL_KIND))
211
1.03k
      result = it;
212
1.05k
  }
213
1.12k
  return result;
214
1.12k
}
215
216
void fxSymbolToString(txMachine* the, txSlot* slot)
217
57
{
218
57
  txSlot* key = fxGetKey(the, slot->value.symbol);
219
57
  fxStringX(the, slot, "Symbol(");
220
57
  if ((key->kind == XS_KEY_KIND) || (key->kind == XS_KEY_X_KIND))
221
2
    fxConcatString(the, slot, key);
222
55
  else if (key->kind == XS_REFERENCE_KIND) {
223
55
    key = key->value.reference->next->next;
224
55
    if (key->kind != XS_UNDEFINED_KIND)
225
26
      fxConcatString(the, slot, key);
226
55
  }
227
57
  fxConcatStringC(the, slot, ")");
228
57
}
229
230
txSlot* fxGetKey(txMachine* the, txID theID)
231
44.4M
{
232
44.4M
  txSlot* key;
233
44.4M
  mxCheck(the, 0 < theID);
234
44.4M
  mxCheck(the, theID < the->keyIndex);
235
44.4M
  if (theID < the->keyOffset)
236
0
    key = the->keyArrayHost[theID];
237
44.4M
  else
238
44.4M
    key = the->keyArray[theID - the->keyOffset];
239
44.4M
  mxCheck(the, key->kind != XS_UNDEFINED_KIND);
240
44.4M
  return key;
241
44.4M
}
242
243
char* fxGetKeyName(txMachine* the, txID theID)
244
2.47M
{
245
2.47M
  txSlot* key = fxGetKey(the, theID);
246
2.47M
  if (key->flag & XS_DONT_ENUM_FLAG)
247
2.47M
    return key->value.string;
248
0
  return C_NULL;
249
2.47M
}
250
251
char* fxGetKeyString(txMachine* the, txID theID, txBoolean* adorn)
252
2.42M
{
253
2.42M
  txString result = mxEmptyString.value.string;
254
2.42M
  txSlot* key = fxGetKey(the, theID);
255
2.42M
  txKind kind = key->kind;
256
2.42M
  if ((kind == XS_KEY_KIND) || (kind == XS_KEY_X_KIND))
257
2.42M
    result = key->value.key.string;
258
173
  else if (key->kind == XS_REFERENCE_KIND) {
259
173
    key = key->value.reference->next->next;
260
173
    if (key->kind != XS_UNDEFINED_KIND)
261
171
      result = key->value.string;
262
173
  }
263
2.42M
  if (adorn)
264
2.42M
    *adorn = (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
265
2.42M
  return result;
266
2.42M
}
267
268
void fxPushKeyString(txMachine* the, txID theID, txBoolean* adorn)
269
20.7M
{
270
20.7M
  txSlot* key = fxGetKey(the, theID);
271
20.7M
  txKind kind = key->kind;
272
20.7M
  if (adorn)
273
20.4M
    *adorn = (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
274
20.7M
  if (kind == XS_KEY_KIND)
275
19.9M
    mxPushString(key->value.key.string);
276
828k
  else if (kind == XS_KEY_X_KIND)
277
0
    mxPushStringX(key->value.key.string);
278
828k
  else {
279
828k
    mxCheck(the, key->kind == XS_REFERENCE_KIND);
280
828k
    key = key->value.reference->next->next;
281
828k
    if (key->kind == XS_UNDEFINED_KIND) {
282
2
      *adorn = 0;
283
2
      mxPush(mxEmptyString);
284
2
    }
285
828k
    else
286
828k
      mxPushSlot(key);
287
828k
  }
288
20.7M
}
289
290
txID fxFindName(txMachine* the, txString theString)
291
3.71k
{
292
3.71k
  txU1* aString;
293
3.71k
  txU4 aSum;
294
3.71k
  txU4 aModulo;
295
3.71k
  txSlot* result;
296
  
297
3.71k
  aString = (txU1*)theString;
298
3.71k
  aSum = 0;
299
109k
  while (*aString != 0) {
300
105k
    aSum = (aSum << 1) + *aString++;
301
105k
  }
302
3.71k
  aSum &= 0x7FFFFFFF;
303
3.71k
  aModulo = aSum % the->nameModulo;
304
3.71k
  result = the->nameTable[aModulo];
305
4.35k
  while (result != C_NULL) {
306
1.02k
    if (result->value.key.sum == aSum)
307
670
      if (c_strcmp(result->value.key.string, theString) == 0)
308
372
        return mxGetKeySlotID(result);
309
648
    result = result->next;
310
648
  }
311
3.33k
  return 0;
312
3.71k
}
313
314
txBoolean fxIsKeyName(txMachine* the, txID theID)
315
18.1M
{
316
18.1M
  txSlot* key = fxGetKey(the, theID);
317
18.1M
  return (key->flag & XS_DONT_ENUM_FLAG) ? 1 : 0;
318
18.1M
}
319
320
txBoolean fxIsKeySymbol(txMachine* the, txID theID)
321
129k
{
322
129k
  txSlot* key = fxGetKey(the, theID);
323
129k
  return (key->flag & XS_DONT_ENUM_FLAG) ? 0 : 1;
324
129k
}
325
326
txID fxNewName(txMachine* the, txSlot* theSlot)
327
3.81M
{
328
3.81M
  txU1* string;
329
3.81M
  txU4 sum;
330
3.81M
  txU4 modulo;
331
3.81M
  txSlot* result;
332
333
3.81M
  string = (txU1*)theSlot->value.string;
334
3.81M
  sum = 0;
335
122M
  while(*string != 0) {
336
118M
    sum = (sum << 1) + *string++;
337
118M
  }
338
3.81M
  sum &= 0x7FFFFFFF;
339
3.81M
  modulo = sum % the->nameModulo;
340
3.81M
  result = the->nameTable[modulo];
341
7.26M
  while (result != C_NULL) {
342
5.34M
    if (result->value.key.sum == sum) {
343
4.26M
      if (c_strcmp(result->value.key.string, theSlot->value.string) == 0)
344
1.89M
        return mxGetKeySlotID(result);
345
4.26M
    }
346
3.44M
    result = result->next;
347
3.44M
  }
348
1.92M
  result = fxFindKey(the);
349
1.92M
  result->next = the->nameTable[modulo];
350
1.92M
  result->flag = XS_INTERNAL_FLAG | XS_DONT_ENUM_FLAG;
351
1.92M
  result->kind = XS_KEY_KIND;
352
1.92M
  result->value.key.string = theSlot->value.string;
353
1.92M
  result->value.key.sum = sum;
354
1.92M
  the->nameTable[modulo] = result;
355
1.92M
  return result->ID;
356
3.81M
}
357
358
txID fxNewNameC(txMachine* the, txString theString)
359
18.9M
{
360
18.9M
  txU1* string;
361
18.9M
  txU4 sum;
362
18.9M
  txU4 modulo;
363
18.9M
  txSlot* result;
364
365
18.9M
  string = (txU1*)theString;
366
18.9M
  sum = 0;
367
174M
  while(c_read8(string) != 0) {
368
155M
    sum = (sum << 1) + c_read8(string++);
369
155M
  }
370
18.9M
  sum &= 0x7FFFFFFF;
371
18.9M
  modulo = sum % the->nameModulo;
372
18.9M
  result = the->nameTable[modulo];
373
34.5M
  while (result != C_NULL) {
374
17.0M
    if (result->value.key.sum == sum) {
375
14.3M
      if (c_strcmp(result->value.key.string, theString) == 0) {
376
1.44M
        txID id = mxGetKeySlotID(result);
377
1.44M
        if (id >= the->keyOffset)
378
1.44M
          result->flag |= XS_DONT_DELETE_FLAG;
379
1.44M
        return id;
380
1.44M
      }
381
14.3M
    }
382
15.6M
    result = result->next;
383
15.6M
  }
384
17.4M
  result = fxFindKey(the);
385
17.4M
  result->next = the->nameTable[modulo];
386
17.4M
  result->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
387
17.4M
  result->kind = XS_KEY_KIND;
388
17.4M
  result->value.key.string = C_NULL;
389
17.4M
  result->value.key.sum = sum;
390
17.4M
  the->nameTable[modulo] = result;
391
17.4M
  result->value.key.string = (txString)fxNewChunk(the, mxStringLength(theString) + 1);
392
17.4M
  c_strcpy(result->value.key.string, theString);
393
17.4M
  return result->ID;
394
18.9M
}
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
35.2M
{
434
35.2M
  txIndex index;
435
35.2M
  txString string;
436
35.2M
again:
437
35.2M
  if ((slot->kind == XS_INTEGER_KIND) && fxIntegerToIndex(the, slot->value.integer, &index)) {
438
9.05M
    slot->value.at.id = XS_NO_ID;
439
9.05M
    slot->value.at.index = index;
440
9.05M
  }
441
26.2M
  else if ((slot->kind == XS_NUMBER_KIND) && fxNumberToIndex(the, slot->value.number, &index)) {
442
25.7M
    slot->value.at.id = XS_NO_ID;
443
25.7M
    slot->value.at.index = index;
444
25.7M
  }
445
475k
  else if (slot->kind == XS_SYMBOL_KIND) {
446
19.4k
    slot->value.at.id = slot->value.symbol;
447
19.4k
    slot->value.at.index = 0;
448
19.4k
  }
449
455k
    else {
450
455k
        if (slot->kind == XS_REFERENCE_KIND) {
451
8.84k
            fxToPrimitive(the, slot, XS_STRING_HINT);
452
8.84k
            goto again;
453
8.84k
        }
454
447k
        string = fxToString(the, slot);
455
447k
        if (fxStringToIndex(the, string, &index)) {
456
9.46k
            slot->value.at.id = XS_NO_ID;
457
9.46k
            slot->value.at.index = index;
458
9.46k
        }
459
437k
        else {
460
437k
      txID id;
461
437k
            if (slot->kind == XS_STRING_X_KIND)
462
0
                id = fxNewNameX(the, string);
463
437k
            else
464
437k
                id = fxNewName(the, slot);
465
437k
            slot->value.at.id = id;
466
437k
            slot->value.at.index = 0;
467
437k
        }
468
447k
    }
469
35.2M
  slot->kind = XS_AT_KIND;
470
35.2M
  return slot;
471
35.2M
}
472
473
void fxKeyAt(txMachine* the, txID id, txIndex index, txSlot* slot)
474
6.73M
{
475
6.73M
  if (id) {
476
95.8k
    txSlot* key = fxGetKey(the, id);
477
95.8k
    if (key->flag & XS_DONT_ENUM_FLAG) {
478
86.5k
      if (key->kind == XS_KEY_KIND) {
479
86.5k
        slot->kind = XS_STRING_KIND;
480
86.5k
        slot->value.string = key->value.key.string;
481
86.5k
      }
482
0
      else{
483
0
        slot->kind = XS_STRING_X_KIND;
484
0
        slot->value.string = key->value.key.string;
485
0
      }
486
86.5k
    }
487
9.33k
    else {
488
9.33k
      slot->kind = XS_SYMBOL_KIND;
489
9.33k
      slot->value.symbol = id;
490
9.33k
    }
491
95.8k
  }
492
6.63M
  else {
493
6.63M
    char buffer[16];
494
6.63M
    fxCopyStringC(the, slot, fxNumberToString(the, index, buffer, sizeof(buffer), 0, 0));
495
6.63M
  }
496
6.73M
}
497
498
void fxIDToString(txMachine* the, txID id, txString theBuffer, txSize theSize)
499
838k
{
500
838k
  if (id != XS_NO_ID) {
501
838k
    txBoolean adorn;
502
838k
    txString string = fxGetKeyString(the, id, &adorn);
503
838k
    if (adorn)
504
2
      c_snprintf(theBuffer, theSize, "[%s]", string);
505
838k
    else
506
838k
      c_snprintf(theBuffer, theSize, "%s", string);
507
838k
  }
508
24
  else {
509
24
    theBuffer[0] = '?';
510
24
    theBuffer[1] = 0;
511
24
  }
512
838k
}