Coverage Report

Created: 2026-03-30 06:30

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