Coverage Report

Created: 2026-05-30 06:24

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