Coverage Report

Created: 2026-01-09 07:26

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