Coverage Report

Created: 2025-12-24 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/moddable/xs/sources/xsObject.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
void fxBuildObject(txMachine* the)
41
34.2k
{
42
34.2k
  txSlot* slot;
43
34.2k
  fxNewHostFunction(the, mxCallback(fx_Object_assign), 2, XS_NO_ID, XS_NO_ID);
44
34.2k
  mxAssignObjectFunction = *the->stack;
45
34.2k
  mxPop();
46
34.2k
  fxNewHostFunction(the, mxCallback(fx_Object_copy), 2, XS_NO_ID, XS_NO_ID);
47
34.2k
  mxCopyObjectFunction = *the->stack;
48
34.2k
  mxPop();
49
34.2k
  fxNewHostFunction(the, mxCallback(fxOrdinaryToPrimitive), 2, XS_NO_ID, XS_NO_ID);
50
34.2k
  mxOrdinaryToPrimitiveFunction = *the->stack;
51
34.2k
  mxPop();
52
  
53
34.2k
  mxPush(mxObjectPrototype);
54
34.2k
  slot = fxLastProperty(the, the->stack->value.reference);
55
34.2k
  slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Object_prototype___proto__get), mxCallback(fx_Object_prototype___proto__set), mxID(___proto__), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
56
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype_hasOwnProperty), 1, mxID(_hasOwnProperty), XS_DONT_ENUM_FLAG);
57
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype___defineGetter__), 2, mxID(___defineGetter__), XS_DONT_ENUM_FLAG);
58
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype___defineSetter__), 2, mxID(___defineSetter__), XS_DONT_ENUM_FLAG);
59
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype___lookupGetter__), 1, mxID(___lookupGetter__), XS_DONT_ENUM_FLAG);
60
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype___lookupSetter__), 1, mxID(___lookupSetter__), XS_DONT_ENUM_FLAG);
61
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype_isPrototypeOf), 1, mxID(_isPrototypeOf), XS_DONT_ENUM_FLAG);
62
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype_propertyIsEnumerable), 1, mxID(_propertyIsEnumerable), XS_DONT_ENUM_FLAG);
63
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype_toLocaleString), 0, mxID(_toLocaleString), XS_DONT_ENUM_FLAG);
64
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
65
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_prototype_valueOf), 0, mxID(_valueOf), XS_DONT_ENUM_FLAG);
66
34.2k
  slot = fxBuildHostConstructor(the, mxCallback(fx_Object), 1, mxID(_Object));
67
34.2k
  mxObjectConstructor = *the->stack;
68
34.2k
  slot = fxLastProperty(the, slot);
69
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_assign), 2, mxID(_assign), XS_DONT_ENUM_FLAG);
70
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_create), 2, mxID(_create), XS_DONT_ENUM_FLAG);
71
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_defineProperties), 2, mxID(_defineProperties), XS_DONT_ENUM_FLAG);
72
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_defineProperty), 3, mxID(_defineProperty), XS_DONT_ENUM_FLAG);
73
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_entries), 1, mxID(_entries), XS_DONT_ENUM_FLAG);
74
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_freeze), 1, mxID(_freeze), XS_DONT_ENUM_FLAG);
75
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_fromEntries), 1, mxID(_fromEntries), XS_DONT_ENUM_FLAG);
76
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_getOwnPropertyDescriptor), 2, mxID(_getOwnPropertyDescriptor), XS_DONT_ENUM_FLAG);
77
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_getOwnPropertyDescriptors), 1, mxID(_getOwnPropertyDescriptors), XS_DONT_ENUM_FLAG);
78
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_getOwnPropertyNames), 1, mxID(_getOwnPropertyNames), XS_DONT_ENUM_FLAG);
79
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_getOwnPropertySymbols), 1, mxID(_getOwnPropertySymbols), XS_DONT_ENUM_FLAG);
80
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_getPrototypeOf), 1, mxID(_getPrototypeOf), XS_DONT_ENUM_FLAG);
81
34.2k
#if mxECMAScript2024
82
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_groupBy), 2, mxID(_groupBy), XS_DONT_ENUM_FLAG);
83
34.2k
#endif
84
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_hasOwn), 2, mxID(_hasOwn), XS_DONT_ENUM_FLAG);
85
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_is), 2, mxID(_is), XS_DONT_ENUM_FLAG);
86
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_isExtensible), 1, mxID(_isExtensible), XS_DONT_ENUM_FLAG);
87
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_isFrozen), 1, mxID(_isFrozen), XS_DONT_ENUM_FLAG);
88
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_isSealed), 1, mxID(_isSealed), XS_DONT_ENUM_FLAG);
89
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_keys), 1, mxID(_keys), XS_DONT_ENUM_FLAG);
90
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_preventExtensions), 1, mxID(_preventExtensions), XS_DONT_ENUM_FLAG);
91
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_seal), 1, mxID(_seal), XS_DONT_ENUM_FLAG);
92
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_setPrototypeOf), 2, mxID(_setPrototypeOf), XS_DONT_ENUM_FLAG);
93
34.2k
  slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Object_values), 1, mxID(_values), XS_DONT_ENUM_FLAG);
94
34.2k
  mxPop();
95
34.2k
}
96
97
98
txSlot* fxNewObjectInstance(txMachine* the)
99
79.0M
{
100
79.0M
  txSlot* instance;
101
79.0M
  instance = fxNewSlot(the);
102
79.0M
  instance->kind = XS_INSTANCE_KIND;
103
79.0M
  instance->value.instance.garbage = C_NULL;
104
79.0M
  instance->value.instance.prototype = the->stack->value.reference;
105
79.0M
  the->stack->value.reference = instance;
106
79.0M
  the->stack->kind = XS_REFERENCE_KIND;
107
79.0M
  return instance;
108
79.0M
}
109
110
void fx_Object(txMachine* the)
111
256k
{
112
256k
  if (!mxIsUndefined(mxTarget) && !fxIsSameSlot(the, mxTarget, mxFunction)) {
113
5
    mxPushSlot(mxTarget);
114
5
    fxGetPrototypeFromConstructor(the, &mxObjectPrototype);
115
5
    fxNewObjectInstance(the);
116
5
    mxPullSlot(mxResult);
117
5
    return;
118
5
  }
119
256k
  if ((mxArgc == 0) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND)) {
120
106k
    mxPush(mxObjectPrototype);
121
106k
    fxNewObjectInstance(the);
122
106k
    mxPullSlot(mxResult);
123
106k
    return;
124
106k
  }
125
149k
  *mxResult = *mxArgv(0);
126
149k
  fxToInstance(the, mxResult);
127
149k
}
128
129
void fx_Object_prototype___proto__get(txMachine* the)
130
1.94M
{
131
1.94M
  if ((mxThis->kind == XS_UNDEFINED_KIND) || (mxThis->kind == XS_NULL_KIND))
132
3
    mxTypeError("invalid this");
133
1.94M
  mxBehaviorGetPrototype(the, fxToInstance(the, mxThis), mxResult);
134
1.94M
}
135
136
void fx_Object_prototype___proto__set(txMachine* the)
137
166k
{
138
166k
  txSlot* instance;
139
166k
  if ((mxThis->kind == XS_UNDEFINED_KIND) || (mxThis->kind == XS_NULL_KIND))
140
3
    mxTypeError("invalid this");
141
166k
  if ((mxArgc < 1) || ((mxArgv(0)->kind != XS_NULL_KIND) && (mxArgv(0)->kind != XS_REFERENCE_KIND)))
142
46.5k
    return;
143
119k
  if (mxThis->kind == XS_REFERENCE_KIND) {
144
119k
    instance = mxThis->value.reference;
145
119k
    if (!mxBehaviorSetPrototype(the, instance, mxArgv(0)))
146
164
      mxTypeError("invalid prototype");
147
119k
  }
148
119k
}
149
150
void fx_Object_prototype___defineGetter__(txMachine* the)
151
17
{
152
17
  txSlot* instance = fxToInstance(the, mxThis);
153
17
  txSlot* at;
154
17
  txSlot* slot;
155
17
  if ((mxArgc < 2) || (!fxIsCallable(the, mxArgv(1))))
156
14
    mxTypeError("invalid getter");
157
3
  at = fxAt(the, mxArgv(0));
158
3
  mxPushUndefined();
159
3
  slot = the->stack;
160
3
  slot->value.accessor.getter = fxToInstance(the, mxArgv(1));
161
3
  slot->value.accessor.setter = C_NULL;
162
3
  slot->kind = XS_ACCESSOR_KIND;
163
3
  slot->flag = XS_NO_FLAG;
164
3
  if(!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, slot, XS_GETTER_FLAG | XS_DONT_DELETE_FLAG| XS_DONT_ENUM_FLAG))
165
1
    mxTypeError("invalid descriptor");
166
2
  mxPop();
167
2
}
168
169
void fx_Object_prototype___defineSetter__(txMachine* the)
170
30
{
171
30
  txSlot* instance = fxToInstance(the, mxThis);
172
30
  txSlot* at;
173
30
  txSlot* slot;
174
30
  if ((mxArgc < 2) || (!fxIsCallable(the, mxArgv(1))))
175
10
    mxTypeError("invalid setter");
176
20
  at = fxAt(the, mxArgv(0));
177
20
  mxPushUndefined();
178
20
  slot = the->stack;
179
20
  slot->value.accessor.getter = C_NULL;
180
20
  slot->value.accessor.setter = fxToInstance(the, mxArgv(1));
181
20
  slot->kind = XS_ACCESSOR_KIND;
182
20
  slot->flag = XS_NO_FLAG;
183
20
  if(!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, slot, XS_SETTER_FLAG | XS_DONT_DELETE_FLAG| XS_DONT_ENUM_FLAG))
184
1
    mxTypeError("invalid descriptor");
185
19
  mxPop();
186
19
}
187
188
void fx_Object_prototype___lookupGetter__(txMachine* the)
189
100k
{
190
100k
  txSlot* instance = fxToInstance(the, mxThis);
191
100k
  txSlot* at;
192
100k
  txSlot* slot;
193
100k
  if (mxArgc < 1)
194
0
    mxPushUndefined();
195
100k
  else
196
100k
    mxPushSlot(mxArgv(0));
197
100k
  at = fxAt(the, the->stack);
198
100k
  mxPushUndefined();
199
100k
  slot = the->stack;
200
201k
again:
201
201k
  if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, slot)) {
202
100k
    if (slot->kind == XS_ACCESSOR_KIND) {
203
100k
      if (slot->value.accessor.getter) {
204
100k
        mxResult->kind = XS_REFERENCE_KIND;
205
100k
        mxResult->value.reference = slot->value.accessor.getter;
206
100k
      }
207
100k
    }
208
100k
    mxPop();
209
100k
    return;
210
100k
  }
211
100k
  if (mxBehaviorGetPrototype(the, instance, slot)) {
212
100k
    instance = slot->value.reference;
213
100k
    goto again;
214
100k
  }
215
9
  mxPop();
216
9
  mxPop();
217
9
}
218
219
void fx_Object_prototype___lookupSetter__(txMachine* the)
220
9
{
221
9
  txSlot* instance = fxToInstance(the, mxThis);
222
9
  txSlot* at;
223
9
  txSlot* slot;
224
9
  if (mxArgc < 1)
225
0
    mxPushUndefined();
226
9
  else
227
9
    mxPushSlot(mxArgv(0));
228
9
  at = fxAt(the, the->stack);
229
9
  mxPushUndefined();
230
9
  slot = the->stack;
231
17
again:
232
17
  if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, slot)) {
233
4
    if (slot->kind == XS_ACCESSOR_KIND) {
234
2
      if (slot->value.accessor.setter) {
235
1
        mxResult->kind = XS_REFERENCE_KIND;
236
1
        mxResult->value.reference = slot->value.accessor.setter;
237
1
      }
238
2
    }
239
4
    mxPop();
240
4
    return;
241
4
  }
242
13
  if (mxBehaviorGetPrototype(the, instance, slot)) {
243
10
    instance = slot->value.reference;
244
10
    goto again;
245
10
  }
246
3
  mxPop();
247
3
  mxPop();
248
3
}
249
250
void fx_Object_prototype_hasOwnProperty(txMachine* the)
251
167
{
252
167
  txSlot* at;
253
167
  txSlot* instance;
254
167
  if (mxArgc < 1)
255
1
    mxPushUndefined();
256
166
  else
257
166
    mxPushSlot(mxArgv(0));
258
167
  at = fxAt(the, the->stack);
259
167
  instance = fxToInstance(the, mxThis);
260
167
  mxPushUndefined();
261
167
  mxResult->value.boolean = mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack);
262
167
  mxResult->kind = XS_BOOLEAN_KIND;
263
167
  mxPop();
264
167
  mxPop();
265
167
}
266
267
void fx_Object_prototype_isPrototypeOf(txMachine* the)
268
266
{
269
266
  mxResult->kind = XS_BOOLEAN_KIND;
270
266
  mxResult->value.boolean = 0;
271
266
  if (mxArgc > 0) {
272
260
    txSlot* slot = mxArgv(0);
273
260
    if (slot->kind == XS_REFERENCE_KIND) {
274
28
      txSlot* prototype = fxToInstance(the, mxThis);
275
38
      while (mxBehaviorGetPrototype(the, slot->value.reference, slot)) {
276
32
        if (prototype == slot->value.reference) {
277
22
          mxResult->value.boolean = 1;
278
22
          break;
279
22
        }
280
32
      }
281
28
    }
282
260
  }
283
266
}
284
285
void fx_Object_prototype_propertyIsEnumerable(txMachine* the)
286
208
{
287
208
  txSlot* at;
288
208
  txSlot* instance;
289
208
  if (mxArgc < 1)
290
1
    mxPushUndefined();
291
207
  else
292
207
    mxPushSlot(mxArgv(0));
293
208
  at = fxAt(the, the->stack);
294
208
  instance = fxToInstance(the, mxThis);
295
208
  mxPushUndefined();
296
208
  mxResult->value.boolean = mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack) && ((the->stack->flag & XS_DONT_ENUM_FLAG) == 0);
297
208
  mxResult->kind = XS_BOOLEAN_KIND;
298
208
  mxPop();
299
208
  mxPop();
300
208
}
301
302
void fx_Object_prototype_toLocaleString(txMachine* the)
303
38
{
304
38
  mxPushSlot(mxThis);
305
38
  mxDub();
306
38
  mxGetID(mxID(_toString));
307
38
  mxCall();
308
38
  mxRunCount(0);
309
38
  mxPullSlot(mxResult);
310
38
}
311
312
void fx_Object_prototype_toString(txMachine* the)
313
463k
{
314
463k
  txString tag = C_NULL;
315
463k
  txSlot* instance = C_NULL;
316
463k
  txSlot* slot;
317
463k
  txSlot* target;
318
463k
  switch (mxThis->kind) {
319
3.29k
  case XS_UNDEFINED_KIND:
320
3.29k
    tag = "Undefined";
321
3.29k
    break;
322
4
  case XS_NULL_KIND:
323
4
    tag = "Null";
324
4
    break;
325
39
  case XS_BOOLEAN_KIND:
326
39
    instance = mxBooleanPrototype.value.reference;
327
39
    tag = "Boolean";
328
39
    break;
329
13
  case XS_INTEGER_KIND:
330
16
  case XS_NUMBER_KIND:
331
16
    instance = mxNumberPrototype.value.reference;
332
16
    tag = "Number";
333
16
    break;
334
6
  case XS_STRING_KIND:
335
6
  case XS_STRING_X_KIND:
336
6
    instance = mxStringPrototype.value.reference;
337
6
    tag = "String";
338
6
    break;
339
6
  case XS_SYMBOL_KIND:
340
6
    instance = mxSymbolPrototype.value.reference;
341
6
    tag = "Object";
342
6
    break;
343
10
  case XS_BIGINT_KIND:
344
10
  case XS_BIGINT_X_KIND:
345
10
    instance = mxBigIntPrototype.value.reference;
346
10
    tag = "Object";
347
10
    break;
348
460k
  case XS_REFERENCE_KIND:
349
460k
    instance = mxThis->value.reference;
350
460k
    if (fxIsArray(the, instance))
351
44
      tag = "Array";
352
460k
    else {
353
460k
      slot = instance->next;
354
460k
      if (slot) {
355
368k
        if ((slot->ID == XS_ARGUMENTS_SLOPPY_BEHAVIOR) || (slot->ID == XS_ARGUMENTS_STRICT_BEHAVIOR))
356
6.24k
          tag = "Arguments";
357
362k
        else if (slot->flag & XS_INTERNAL_FLAG) {
358
350k
          switch (slot->kind) {
359
71
          case XS_BOOLEAN_KIND:
360
71
            tag = "Boolean";
361
71
            break;
362
1
          case XS_CALLBACK_KIND:
363
1
          case XS_CALLBACK_X_KIND:
364
27
          case XS_CODE_KIND:
365
28
          case XS_CODE_X_KIND:
366
28
            tag = "Function";
367
28
            break;
368
21
          case XS_DATE_KIND:
369
21
            tag = "Date";
370
21
            break;
371
13
          case XS_ERROR_KIND:
372
13
            tag = "Error";
373
13
            break;
374
99.4k
          case XS_GLOBAL_KIND:
375
99.4k
            tag = "global";
376
99.4k
            break;
377
21
          case XS_NUMBER_KIND:
378
21
            tag = "Number";
379
21
            break;
380
1.01k
          case XS_REGEXP_KIND:
381
1.01k
            tag = "RegExp";
382
1.01k
            break;
383
15
          case XS_STRING_KIND:
384
15
          case XS_STRING_X_KIND:
385
15
            tag = "String";
386
15
            break;
387
12
          case XS_BIGINT_KIND:
388
12
          case XS_BIGINT_X_KIND:
389
12
            tag = "Object";
390
12
            break;
391
2.77k
          case XS_PROXY_KIND:
392
3.65k
            while ((target = slot->value.proxy.target)) {
393
3.65k
              slot = target->next;
394
3.65k
              if (!slot || (slot->kind != XS_PROXY_KIND))
395
2.77k
                break;
396
3.65k
            }
397
2.77k
            if (mxIsFunction(target)) {
398
24
              instance = target;
399
24
              tag = "Function";
400
24
            }
401
2.74k
            else
402
2.74k
              tag = "Object";
403
2.77k
            break;
404
246k
          default:
405
246k
            tag = "Object";
406
246k
            break;
407
350k
          }
408
350k
        }
409
11.6k
        else
410
11.6k
                tag = "Object";
411
368k
      }
412
91.9k
      else
413
91.9k
              tag = "Object";
414
460k
    }
415
460k
    break;
416
#if mxHostFunctionPrimitive
417
  case XS_HOST_FUNCTION_KIND:
418
    instance = mxFunctionPrototype.value.reference;
419
    tag = "Function";
420
    break;
421
#endif
422
460k
  default:
423
0
    tag = "Object";
424
0
    break;
425
463k
  }
426
463k
  fxStringX(the, mxResult, "[object ");
427
463k
  if (instance) {
428
460k
    mxPushReference(instance);
429
460k
    mxGetID(mxID(_Symbol_toStringTag));
430
460k
    if ((the->stack->kind == XS_STRING_KIND) || (the->stack->kind == XS_STRING_X_KIND))
431
255k
      fxConcatString(the, mxResult, the->stack);
432
204k
    else
433
204k
      fxConcatStringC(the, mxResult, tag);
434
460k
  }
435
3.29k
  else
436
3.29k
    fxConcatStringC(the, mxResult, tag);
437
463k
  fxConcatStringC(the, mxResult, "]");
438
463k
}
439
440
void fx_Object_prototype_valueOf(txMachine* the)
441
6.68M
{
442
6.68M
  fxToInstance(the, mxThis);
443
6.68M
  *mxResult = *mxThis;
444
6.68M
}
445
446
void fx_Object_assign(txMachine* the)
447
142
{
448
142
  txSlot* target;
449
142
  txInteger c, i;
450
142
  txSlot* instance;
451
142
  txSlot* at;
452
142
  txSlot* property;
453
142
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
454
2
    mxTypeError("invalid target");
455
140
  fxToInstance(the, mxArgv(0));
456
140
  target = mxArgv(0);
457
140
  c = mxArgc;
458
328
  for (i = 1; i < c; i++) {
459
188
    if ((mxArgv(i)->kind == XS_UNDEFINED_KIND) || (mxArgv(i)->kind == XS_NULL_KIND))
460
12
      continue;
461
176
    instance = fxToInstance(the, mxArgv(i));
462
176
    at = fxNewInstance(the);
463
176
    mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
464
176
    mxPushUndefined();
465
176
    property = the->stack;
466
488
    while ((at = at->next)) {
467
312
      if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
468
286
        mxPushReference(instance);
469
286
        mxGetAll(at->value.at.id, at->value.at.index);
470
286
        mxPushSlot(target);
471
286
        mxSetAll(at->value.at.id, at->value.at.index);
472
286
        mxPop();
473
286
      }
474
312
    }
475
176
    mxPop();
476
176
    mxPop();
477
176
  }
478
140
  *mxResult = *target;
479
140
}
480
481
void fx_Object_copy(txMachine* the)
482
8.89k
{
483
8.89k
  txInteger c = mxArgc, i;
484
8.89k
  txSlot* target;
485
8.89k
  txSlot* source;
486
8.89k
  txSlot* at;
487
8.89k
  txSlot* property;
488
8.89k
  if ((c < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
489
0
    mxTypeError("invalid object");
490
8.89k
  target = fxToInstance(the, mxArgv(0));
491
8.89k
  *mxResult = *mxArgv(0);
492
8.89k
  if ((c < 2) || (mxArgv(1)->kind == XS_UNDEFINED_KIND) || (mxArgv(1)->kind == XS_NULL_KIND))
493
7
    return;
494
8.88k
  source = fxToInstance(the, mxArgv(1));
495
8.88k
  at = fxNewInstance(the);
496
8.88k
  mxBehaviorOwnKeys(the, source, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
497
8.88k
  mxPushUndefined();
498
8.88k
  property = the->stack;
499
11.8M
  while ((at = at->next)) {
500
11.8M
    for (i = 2; i < c; i++) {
501
249
      txSlot* exclude = mxArgv(i);
502
249
      if ((exclude->value.at.id == at->value.at.id) && (exclude->value.at.index == at->value.at.index))
503
6
        break;
504
249
    }
505
11.8M
    if (i == c) {
506
11.8M
      if (mxBehaviorGetOwnProperty(the, source, at->value.at.id, at->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
507
11.8M
        mxPushReference(source);
508
11.8M
        mxGetAll(at->value.at.id, at->value.at.index);
509
11.8M
        the->stack->flag = 0;
510
11.8M
        mxBehaviorDefineOwnProperty(the, target, at->value.at.id, at->value.at.index, the->stack, XS_GET_ONLY);
511
11.8M
        mxPop();
512
11.8M
      }
513
11.8M
    }
514
11.8M
    mxCheckMetering();
515
11.8M
  }
516
8.88k
  mxPop(); // property
517
8.88k
  mxPop(); // at
518
8.88k
}
519
520
void fx_Object_create(txMachine* the)
521
50.3k
{
522
50.3k
  txSlot* instance;
523
50.3k
  txSlot* properties;
524
50.3k
  txSlot* at;
525
50.3k
  txSlot* property;
526
50.3k
  txFlag mask;
527
50.3k
  if ((mxArgc < 1) || ((mxArgv(0)->kind != XS_NULL_KIND) && (mxArgv(0)->kind != XS_REFERENCE_KIND)))
528
2
    mxTypeError("invalid prototype");
529
50.3k
  if (mxArgv(0)->kind == XS_NULL_KIND)
530
22
    fxNewInstance(the);
531
50.3k
  else {
532
50.3k
    mxPushSlot(mxArgv(0));
533
50.3k
    fxNewHostInstance(the);
534
50.3k
  }
535
50.3k
  mxPullSlot(mxResult);
536
50.3k
  instance = fxGetInstance(the, mxResult);
537
50.3k
  if ((mxArgc > 1) && (mxArgv(1)->kind != XS_UNDEFINED_KIND)) {
538
88
    properties = fxToInstance(the, mxArgv(1));
539
88
    at = fxNewInstance(the);
540
88
    mxBehaviorOwnKeys(the, properties, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
541
88
    mxPushUndefined();
542
88
    property = the->stack;
543
322
    while ((at = at->next)) {
544
234
      if (mxBehaviorGetOwnProperty(the, properties, at->value.at.id, at->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
545
165
        mxPushReference(properties);
546
165
        mxGetAll(at->value.at.id, at->value.at.index);
547
165
        mask = fxDescriptorToSlot(the, the->stack);
548
165
        if (!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack, mask))
549
0
          mxTypeError("invalid descriptor");
550
165
        mxPop();
551
165
      }
552
234
    }
553
88
    mxPop();
554
88
    mxPop();
555
88
  }
556
50.3k
}
557
558
void fx_Object_defineProperties(txMachine* the)
559
68
{
560
68
  txSlot* instance;
561
68
  txSlot* properties;
562
68
  txSlot* at;
563
68
  txSlot* property;
564
68
  txFlag mask;
565
68
  if ((mxArgc < 1) || (mxArgv(0)->kind != XS_REFERENCE_KIND))
566
2
    mxTypeError("invalid object");
567
66
  if ((mxArgc < 2) || (mxArgv(1)->kind == XS_UNDEFINED_KIND))
568
2
    mxTypeError("invalid properties");
569
64
  instance = fxGetInstance(the, mxArgv(0));
570
64
  properties = fxToInstance(the, mxArgv(1));
571
64
  at = fxNewInstance(the);
572
64
  mxBehaviorOwnKeys(the, properties, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
573
64
  mxPushUndefined();
574
64
  property = the->stack;
575
357
  while ((at = at->next)) {
576
299
    if (mxBehaviorGetOwnProperty(the, properties, at->value.at.id, at->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
577
74
      mxPushReference(properties);
578
74
      mxGetAll(at->value.at.id, at->value.at.index);
579
74
      mask = fxDescriptorToSlot(the, the->stack);
580
74
      if (!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack, mask))
581
6
        mxTypeError("invalid descriptor");
582
68
      mxPop();
583
68
    }
584
299
  }
585
58
  mxPop();
586
58
  mxPop();
587
58
  *mxResult = *mxArgv(0);
588
58
}
589
590
void fx_Object_defineProperty(txMachine* the)
591
224k
{
592
224k
  txSlot* at;
593
224k
  txFlag mask;
594
224k
  if ((mxArgc < 1) || (mxArgv(0)->kind != XS_REFERENCE_KIND))
595
6.51k
    mxTypeError("invalid object");
596
217k
  if (mxArgc < 2)
597
1
    mxTypeError("invalid key");
598
217k
  at = fxAt(the, mxArgv(1));
599
217k
  if ((mxArgc < 3) || (mxArgv(2)->kind != XS_REFERENCE_KIND))
600
7
    mxTypeError("invalid descriptor");
601
217k
  mask = fxDescriptorToSlot(the, mxArgv(2));
602
217k
  if (!mxBehaviorDefineOwnProperty(the, mxArgv(0)->value.reference, at->value.at.id, at->value.at.index, mxArgv(2), mask))
603
65
    mxTypeError("invalid descriptor");
604
217k
  *mxResult = *mxArgv(0);
605
217k
}
606
607
void fx_Object_entries(txMachine* the)
608
50
{
609
50
  txSlot* instance;
610
50
  txSlot* result;
611
50
  txSlot* array;
612
50
  txSlot* property;
613
50
  txSlot** address;
614
50
  txSlot* item;
615
50
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
616
3
    mxTypeError("invalid object");
617
47
  instance = fxToInstance(the, mxArgv(0));
618
47
  mxPush(mxArrayPrototype);
619
47
  result = fxNewArrayInstance(the);
620
47
  mxPullSlot(mxResult);
621
47
  array = result->next;
622
47
  mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG, array);
623
47
  mxPushUndefined();
624
47
  property = the->stack;
625
47
  address = &array->next;
626
539
  while ((item = *address)) {
627
492
    if (mxBehaviorGetOwnProperty(the, instance, item->value.at.id, item->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
628
426
      array->value.array.length++;
629
426
      mxPushUndefined();
630
426
      fxKeyAt(the, item->value.at.id, item->value.at.index, the->stack);
631
426
      mxPushReference(instance);
632
426
      mxGetAll(item->value.at.id, item->value.at.index);
633
426
      fxConstructArrayEntry(the, item);
634
426
      address = &(item->next);
635
426
    }
636
66
    else
637
66
      *address = item->next;
638
492
  }
639
47
  mxPop();
640
47
  fxCacheArray(the, result);
641
47
}
642
643
void fx_Object_freeze(txMachine* the)
644
163
{
645
163
  if (mxArgc > 0) {
646
162
    txSlot* slot = mxArgv(0);
647
162
    if (slot->kind == XS_REFERENCE_KIND) {
648
152
      txSlot* instance = slot->value.reference;
649
152
      txBoolean deep = 0;
650
152
      txSlot* at;
651
152
      txSlot* property;
652
152
      if (!mxBehaviorPreventExtensions(the, instance))
653
1
        mxTypeError("extensible object");
654
151
      if ((mxArgc > 1) && fxToBoolean(the, mxArgv(1)))
655
64
        deep = 1;
656
151
      at = fxNewInstance(the);
657
151
      mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
658
151
      mxPushUndefined();
659
151
      property = the->stack;
660
962
      while ((at = at->next)) {
661
812
        if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
662
811
          txFlag mask = XS_DONT_DELETE_FLAG;
663
811
          property->flag |= XS_DONT_DELETE_FLAG;
664
811
          if (property->kind != XS_ACCESSOR_KIND) {
665
790
            mask |= XS_DONT_SET_FLAG;
666
790
            property->flag |= XS_DONT_SET_FLAG;
667
790
          }
668
811
          property->kind = XS_UNINITIALIZED_KIND;
669
811
          if (!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, property, mask)) {
670
1
            if (!deep)
671
1
              mxTypeError("cannot configure property");
672
1
          }
673
811
        }
674
812
      }
675
150
      mxPop();
676
150
      if (deep) {
677
64
        at = the->stack->value.reference;
678
64
        mxPushUndefined();
679
64
        property = the->stack;
680
264
        while ((at = at->next)) {
681
200
          if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
682
200
            if (property->kind == XS_REFERENCE_KIND) {
683
58
              mxPushSlot(mxThis);
684
58
              mxDub();
685
58
              mxGetID(mxID(_isFrozen));
686
58
              mxCall();
687
58
              mxPushSlot(property);
688
58
              mxRunCount(1);
689
58
              if (!fxRunTest(the)) {
690
53
                mxPushSlot(mxThis);
691
53
                mxPushSlot(mxFunction);
692
53
                mxCall();
693
53
                mxPushSlot(property);
694
53
                mxPushBoolean(1);
695
53
                mxRunCount(2);
696
53
                mxPop();
697
53
              }
698
58
            }
699
142
            else if (property->kind == XS_ACCESSOR_KIND) {
700
2
              if (property->value.accessor.getter) {
701
2
                mxPushSlot(mxThis);
702
2
                mxDub();
703
2
                mxGetID(mxID(_isFrozen));
704
2
                mxCall();
705
2
                mxPushReference(property->value.accessor.getter);
706
2
                mxRunCount(1);
707
2
                if (!fxRunTest(the)) {
708
2
                  mxPushSlot(mxThis);
709
2
                  mxPushSlot(mxFunction);
710
2
                  mxCall();
711
2
                  mxPushReference(property->value.accessor.getter);
712
2
                  mxPushBoolean(1);
713
2
                  mxRunCount(2);
714
2
                  mxPop();
715
2
                }
716
2
              }
717
2
              if (property->value.accessor.setter) {
718
1
                mxPushSlot(mxThis);
719
1
                mxDub();
720
1
                mxGetID(mxID(_isFrozen));
721
1
                mxCall();
722
1
                mxPushReference(property->value.accessor.setter);
723
1
                mxRunCount(1);
724
1
                if (!fxRunTest(the)) {
725
1
                  mxPushSlot(mxThis);
726
1
                  mxPushSlot(mxFunction);
727
1
                  mxCall();
728
1
                  mxPushReference(property->value.accessor.setter);
729
1
                  mxPushBoolean(1);
730
1
                  mxRunCount(2);
731
1
                  mxPop();
732
1
                }
733
1
              }
734
2
            }
735
200
          }
736
200
        }
737
64
        mxPop();
738
64
      }
739
150
      mxPop();
740
150
    }
741
160
    *mxResult = *mxArgv(0);
742
160
  }
743
163
}
744
745
void fx_Object_fromEntries(txMachine* the)
746
31.7k
{
747
31.7k
  txSlot *instance, *iterator, *next, *value, *at;
748
31.7k
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
749
2
    mxTypeError("invalid iterable");
750
31.7k
  mxPush(mxObjectPrototype);
751
31.7k
  instance = fxNewObjectInstance(the);
752
31.7k
  mxPullSlot(mxResult);
753
31.7k
  mxTemporary(iterator);
754
31.7k
  mxTemporary(next);
755
31.7k
  fxGetIterator(the, mxArgv(0), iterator, next, 0);  
756
31.7k
  mxTemporary(value);
757
86.8k
  while (fxIteratorNext(the, iterator, next, value)) {
758
55.0k
    mxTry(the) {
759
55.0k
      if (value->kind != XS_REFERENCE_KIND)
760
2
        mxTypeError("item: not an object");
761
55.0k
      mxPushSlot(value);
762
55.0k
      mxGetIndex(0);
763
55.0k
      mxPushSlot(value);
764
55.0k
      mxGetIndex(1);
765
55.0k
      at = fxAt(the, the->stack + 1);
766
55.0k
      mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack, XS_GET_ONLY);
767
55.0k
      mxPop();
768
55.0k
      mxPop();
769
55.0k
    }
770
55.0k
    mxCatch(the) {
771
2
      fxIteratorReturn(the, iterator, 1);
772
2
      fxJump(the);
773
2
    }
774
55.0k
  }
775
31.7k
  mxPop();
776
31.7k
}
777
778
void fx_Object_getOwnPropertyDescriptor(txMachine* the)
779
91.4k
{
780
91.4k
  txSlot* instance;
781
91.4k
  txSlot* at;
782
91.4k
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
783
8
    mxTypeError("invalid object");
784
91.4k
  instance = fxToInstance(the, mxArgv(0));
785
91.4k
  if (mxArgc < 2)
786
1.62k
    mxPushUndefined();
787
89.8k
  else
788
89.8k
    mxPushSlot(mxArgv(1));
789
91.4k
  at = fxAt(the, the->stack);
790
91.4k
  mxPushUndefined();
791
91.4k
  if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack)) {
792
89.8k
    fxDescribeProperty(the, the->stack, XS_GET_ONLY);
793
89.8k
    mxPullSlot(mxResult);
794
89.8k
  }
795
91.4k
  mxPop();
796
91.4k
  mxPop();
797
91.4k
}
798
799
void fx_Object_getOwnPropertyDescriptors(txMachine* the)
800
23
{
801
23
  txSlot* instance;
802
23
  txSlot* result;
803
23
  txSlot* at;
804
23
  txSlot* property;
805
23
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
806
3
    mxTypeError("invalid object");
807
20
  instance = fxToInstance(the, mxArgv(0));
808
20
  mxPush(mxObjectPrototype);
809
20
  result = fxNewObjectInstance(the);
810
20
  mxPullSlot(mxResult);
811
20
  at = fxNewInstance(the);
812
20
  mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
813
20
  mxPushUndefined();
814
20
  property = the->stack;
815
42
  while ((at = at->next)) {
816
22
    if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
817
16
      fxDescribeProperty(the, property, XS_GET_ONLY);
818
16
      mxBehaviorDefineOwnProperty(the, result, at->value.at.id, at->value.at.index, the->stack, XS_GET_ONLY);
819
16
      mxPop();
820
16
    }
821
22
  }
822
20
  mxPop();
823
20
}
824
825
void fx_Object_getOwnPropertyNames(txMachine* the)
826
76
{
827
76
  txSlot* instance;
828
76
  txSlot* result;
829
76
  txSlot* array;
830
76
  txSlot* item;
831
76
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
832
3
    mxTypeError("invalid object");
833
73
  instance = fxToInstance(the, mxArgv(0));
834
73
  mxPush(mxArrayPrototype);
835
73
  result = fxNewArrayInstance(the);
836
73
  mxPullSlot(mxResult);
837
73
  array = result->next;
838
73
  mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG, array);
839
73
  item = array;
840
1.03k
  while ((item = item->next)) {
841
957
    array->value.array.length++;
842
957
    fxKeyAt(the, item->value.at.id, item->value.at.index, item);
843
957
  }
844
73
  fxCacheArray(the, result);
845
73
}
846
847
void fx_Object_getOwnPropertySymbols(txMachine* the)
848
27
{
849
27
  txSlot* instance;
850
27
  txSlot* result;
851
27
  txSlot* array;
852
27
  txSlot* item;
853
27
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
854
3
    mxTypeError("invalid object");
855
24
  instance = fxToInstance(the, mxArgv(0));
856
24
  mxPush(mxArrayPrototype);
857
24
  result = fxNewArrayInstance(the);
858
24
  mxPullSlot(mxResult);
859
24
  array = result->next;
860
24
  mxBehaviorOwnKeys(the, instance, XS_EACH_SYMBOL_FLAG, array);
861
24
  item = array;
862
33
  while ((item = item->next)) {
863
9
    array->value.array.length++;
864
9
    fxKeyAt(the, item->value.at.id, item->value.at.index, item);
865
9
  }
866
24
  fxCacheArray(the, result);
867
24
}
868
869
void fx_Object_getPrototypeOf(txMachine* the)
870
324
{
871
324
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
872
4
    mxTypeError("invalid object");
873
320
  mxBehaviorGetPrototype(the, fxToInstance(the, mxArgv(0)), mxResult);
874
320
}
875
876
static void fx_Object_groupByAux(txMachine* the)
877
38
{
878
38
  txSlot* instance = mxResult->value.reference;
879
38
  txSlot* at = the->stack;
880
38
  fxAt(the, at);
881
38
  mxPushUndefined();
882
38
  if (!mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack)) {
883
19
    mxPop();
884
19
    mxPush(mxArrayPrototype);
885
19
    fxNewArrayInstance(the);
886
19
    if (!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack, XS_GET_ONLY))
887
0
      mxTypeError("invalid descriptor");
888
19
  }
889
38
}
890
891
void fx_Object_groupBy(txMachine* the)
892
94
{
893
94
  txSlot *instance, *at, *property;
894
94
  instance = fxNewInstance(the);
895
94
  mxPullSlot(mxResult);
896
94
  fxGroupBy(the, fx_Object_groupByAux);
897
94
  at = fxNewInstance(the);
898
94
  mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
899
94
  mxPushUndefined();
900
94
  property = the->stack;
901
112
  while ((at = at->next)) {
902
18
    if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
903
18
      fxCacheArray(the, property->value.reference);
904
18
    }
905
18
  }
906
94
  mxPop();
907
94
  mxPop();
908
94
}
909
910
void fx_Object_hasOwn(txMachine* the)
911
8
{
912
8
  txSlot* instance;
913
8
  txSlot* at;
914
8
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
915
3
    mxTypeError("invalid object");
916
5
  instance = fxToInstance(the, mxArgv(0));
917
5
  if (mxArgc < 2)
918
2
    mxPushUndefined();
919
3
  else
920
3
    mxPushSlot(mxArgv(1));
921
5
  at = fxAt(the, the->stack);
922
5
  mxPushUndefined();
923
5
  mxResult->value.boolean = mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, the->stack);
924
5
  mxResult->kind = XS_BOOLEAN_KIND;
925
5
  mxPop();
926
5
  mxPop();
927
5
}
928
929
void fx_Object_is(txMachine* the)
930
743k
{
931
743k
  if (mxArgc > 0)
932
743k
    mxPushSlot(mxArgv(0));
933
303
  else
934
303
    mxPushUndefined();
935
743k
  if (mxArgc > 1)
936
614k
    mxPushSlot(mxArgv(1));
937
128k
  else
938
128k
    mxPushUndefined();
939
743k
  mxResult->value.boolean = fxIsSameValue(the, the->stack + 1, the->stack, 0);
940
743k
  mxResult->kind = XS_BOOLEAN_KIND;
941
743k
  the->stack += 2;
942
743k
}
943
944
void fx_Object_isExtensible(txMachine* the)
945
327
{
946
327
  mxResult->kind = XS_BOOLEAN_KIND;
947
327
  mxResult->value.boolean = 0;
948
327
  if (mxArgc > 0) {
949
325
    txSlot* slot = mxArgv(0);
950
325
    if (slot->kind == XS_REFERENCE_KIND) {
951
322
      slot = slot->value.reference;
952
322
      mxResult->value.boolean = mxBehaviorIsExtensible(the, slot);
953
322
    }
954
325
  }
955
327
}
956
957
void fx_Object_isFrozen(txMachine* the)
958
108
{
959
108
  mxResult->kind = XS_BOOLEAN_KIND;
960
108
  mxResult->value.boolean = 1;
961
108
  if (mxArgc > 0) {
962
108
    txSlot* slot = mxArgv(0);
963
108
    if (slot->kind == XS_REFERENCE_KIND) {
964
105
      txSlot* instance = slot->value.reference;
965
105
            mxResult->value.boolean = mxBehaviorIsExtensible(the, instance) ? 0 : 1;
966
105
      if (mxResult->value.boolean) {
967
39
        txSlot* at;
968
39
        txSlot* property;
969
39
        at = fxNewInstance(the);
970
39
        mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
971
39
        mxPushUndefined();
972
39
        property = the->stack;
973
209
        while ((at = at->next)) {
974
170
          if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
975
169
            if (property->kind != XS_ACCESSOR_KIND) 
976
168
              if (!(property->flag & XS_DONT_SET_FLAG))
977
15
                mxResult->value.boolean = 0;
978
169
            if (!(property->flag & XS_DONT_DELETE_FLAG))
979
13
              mxResult->value.boolean = 0;
980
169
          }
981
170
        }
982
39
        mxPop();
983
39
        mxPop();
984
39
      }
985
105
    }
986
108
  }
987
108
}
988
989
void fx_Object_isSealed(txMachine* the)
990
28
{
991
28
  mxResult->kind = XS_BOOLEAN_KIND;
992
28
  mxResult->value.boolean = 1;
993
28
  if (mxArgc > 0) {
994
28
    txSlot* slot = mxArgv(0);
995
28
    if (slot->kind == XS_REFERENCE_KIND) {
996
27
      txSlot* instance = slot->value.reference;
997
27
      mxResult->value.boolean = mxBehaviorIsExtensible(the, instance) ? 0 : 1;
998
27
      if (mxResult->value.boolean) {
999
21
        txSlot* at;
1000
21
        txSlot* property;
1001
21
        at = fxNewInstance(the);
1002
21
        mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
1003
21
        mxPushUndefined();
1004
21
        property = the->stack;
1005
394
        while ((at = at->next)) {
1006
373
          if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
1007
371
            if (!(property->flag & XS_DONT_DELETE_FLAG))
1008
0
              mxResult->value.boolean = 0;
1009
371
          }
1010
373
        }
1011
21
        mxPop();
1012
21
        mxPop();
1013
21
      }    
1014
27
    }
1015
28
  }
1016
28
}
1017
1018
void fx_Object_keys(txMachine* the)
1019
76
{
1020
76
  txSlot* instance;
1021
76
  txSlot* result;
1022
76
  txSlot* array;
1023
76
  txSlot* property;
1024
76
  txSlot** address;
1025
76
  txSlot* item;
1026
76
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
1027
3
    mxTypeError("invalid object");
1028
73
  instance = fxToInstance(the, mxArgv(0));
1029
73
  mxPush(mxArrayPrototype);
1030
73
  result = fxNewArrayInstance(the);
1031
73
  mxPullSlot(mxResult);
1032
73
  array = result->next;
1033
73
  mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG, array);
1034
73
  mxPushUndefined();
1035
73
  property = the->stack;
1036
73
  address = &array->next;
1037
568
  while ((item = *address)) {
1038
495
    if (mxBehaviorGetOwnProperty(the, instance, item->value.at.id, item->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
1039
437
      array->value.array.length++;
1040
437
      fxKeyAt(the, item->value.at.id, item->value.at.index, item);
1041
437
      address = &(item->next);
1042
437
    }
1043
58
    else
1044
58
      *address = item->next;
1045
495
  }
1046
73
  mxPop();
1047
73
  fxCacheArray(the, result);
1048
73
}
1049
1050
void fx_Object_preventExtensions(txMachine* the)
1051
73.7k
{
1052
73.7k
  if (mxArgc > 0) {
1053
73.7k
    txSlot* slot = mxArgv(0);
1054
73.7k
    if (slot->kind == XS_REFERENCE_KIND) {
1055
73.7k
      slot = slot->value.reference;
1056
73.7k
      if (!mxBehaviorPreventExtensions(the, slot))
1057
2
        mxTypeError("extensible object");
1058
73.7k
    }
1059
73.7k
    *mxResult = *mxArgv(0);
1060
73.7k
  }
1061
73.7k
}
1062
1063
void fx_Object_seal(txMachine* the)
1064
1.50k
{
1065
1.50k
  if (mxArgc > 0) {
1066
153
    txSlot* slot = mxArgv(0);
1067
153
    if (slot->kind == XS_REFERENCE_KIND) {
1068
85
      txSlot* instance = slot->value.reference;
1069
85
      txSlot* at;
1070
85
      txSlot* property;
1071
85
      if (!mxBehaviorPreventExtensions(the, instance))
1072
1
        mxTypeError("extensible object");
1073
84
      at = fxNewInstance(the);
1074
84
      mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG | XS_EACH_SYMBOL_FLAG, at);
1075
84
      mxPushUndefined();
1076
84
      property = the->stack;
1077
582
      while ((at = at->next)) {
1078
499
        if (mxBehaviorGetOwnProperty(the, instance, at->value.at.id, at->value.at.index, property)) {
1079
499
          txFlag mask = XS_DONT_DELETE_FLAG;
1080
499
          property->flag |= XS_DONT_DELETE_FLAG;
1081
499
          property->kind = XS_UNINITIALIZED_KIND;
1082
499
          if (!mxBehaviorDefineOwnProperty(the, instance, at->value.at.id, at->value.at.index, property, mask))
1083
1
            mxTypeError("cannot configure property");
1084
499
        }
1085
499
      }
1086
83
      mxPop();
1087
83
      mxPop();
1088
83
    }
1089
151
    *mxResult = *mxArgv(0);
1090
151
  }
1091
1.50k
}
1092
1093
void fx_Object_setPrototypeOf(txMachine* the)
1094
94
{
1095
94
  txSlot* instance;
1096
94
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
1097
9
    mxTypeError("invalid object");
1098
85
  if ((mxArgc < 2) || ((mxArgv(1)->kind != XS_NULL_KIND) && (mxArgv(1)->kind != XS_REFERENCE_KIND)))
1099
17
    mxTypeError("invalid prototype");
1100
68
  if (mxArgv(0)->kind == XS_REFERENCE_KIND) {
1101
58
    instance = mxArgv(0)->value.reference;
1102
58
    if (!mxBehaviorSetPrototype(the, instance, mxArgv(1)))
1103
11
      mxTypeError("invalid prototype");
1104
58
  }
1105
57
  *mxResult = *mxArgv(0);
1106
57
}
1107
1108
void fx_Object_values(txMachine* the)
1109
130k
{
1110
130k
  txSlot* instance;
1111
130k
  txSlot* result;
1112
130k
  txSlot* array;
1113
130k
  txSlot* property;
1114
130k
  txSlot** address;
1115
130k
  txSlot* item;
1116
130k
  if ((mxArgc < 1) || (mxArgv(0)->kind == XS_UNDEFINED_KIND) || (mxArgv(0)->kind == XS_NULL_KIND))
1117
4
    mxTypeError("invalid object");
1118
130k
  instance = fxToInstance(the, mxArgv(0));
1119
130k
  mxPush(mxArrayPrototype);
1120
130k
  result = fxNewArrayInstance(the);
1121
130k
  mxPullSlot(mxResult);
1122
130k
  array = result->next;
1123
130k
  mxBehaviorOwnKeys(the, instance, XS_EACH_NAME_FLAG, array);
1124
130k
  mxPushUndefined();
1125
130k
  property = the->stack;
1126
130k
  address = &array->next;
1127
4.89M
  while ((item = *address)) {
1128
4.76M
    if (mxBehaviorGetOwnProperty(the, instance, item->value.at.id, item->value.at.index, property) && !(property->flag & XS_DONT_ENUM_FLAG)) {
1129
4.63M
      array->value.array.length++;
1130
4.63M
      mxPushReference(instance);
1131
4.63M
      mxGetAll(item->value.at.id, item->value.at.index);
1132
4.63M
      mxPullSlot(item);
1133
4.63M
      address = &(item->next);
1134
4.63M
    }
1135
130k
    else
1136
130k
      *address = item->next;
1137
4.76M
  }
1138
130k
  mxPop();
1139
130k
  fxCacheArray(the, result);
1140
130k
}