@agoric/xsnap 0.14.3-u14.0 → 0.14.3-u16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +3 -3
  2. package/api.js +4 -2
  3. package/build.env +1 -1
  4. package/moddable/modules/data/base64/base64.js +28 -0
  5. package/moddable/modules/data/base64/manifest.json +11 -0
  6. package/moddable/modules/data/base64/modBase64.c +188 -0
  7. package/moddable/modules/data/binaryMessage/BinaryMessage.js +106 -0
  8. package/moddable/modules/data/crc/crc.c +205 -0
  9. package/moddable/modules/data/crc/crc.js +36 -0
  10. package/moddable/modules/data/crc/manifest.json +8 -0
  11. package/moddable/modules/data/hex/hex.js +28 -0
  12. package/moddable/modules/data/hex/manifest.json +11 -0
  13. package/moddable/modules/data/hex/modHex.c +139 -0
  14. package/moddable/modules/data/logical/logical.js +32 -0
  15. package/moddable/modules/data/logical/modLogical.c +98 -0
  16. package/moddable/modules/data/qrcode/manifest.json +9 -0
  17. package/moddable/modules/data/qrcode/qrcode.c +93 -0
  18. package/moddable/modules/data/qrcode/qrcode.js +23 -0
  19. package/moddable/modules/data/qrcode/qrcodegen.c +1025 -0
  20. package/moddable/modules/data/qrcode/qrcodegen.h +267 -0
  21. package/moddable/modules/data/text/decoder/manifest.json +8 -0
  22. package/moddable/modules/data/text/decoder/textdecoder.c +480 -0
  23. package/moddable/modules/data/text/decoder/textdecoder.js +27 -0
  24. package/moddable/modules/data/text/encoder/manifest.json +8 -0
  25. package/moddable/modules/data/text/encoder/textencoder.c +232 -0
  26. package/moddable/modules/data/text/encoder/textencoder.js +24 -0
  27. package/moddable/modules/data/tinyint/tinyint.c +150 -0
  28. package/moddable/modules/data/tinyint/tinyint.js +53 -0
  29. package/moddable/modules/data/url/manifest.json +17 -0
  30. package/moddable/modules/data/url/url.c +1959 -0
  31. package/moddable/modules/data/url/url.js +210 -0
  32. package/moddable/modules/data/wavreader/manifest.json +8 -0
  33. package/moddable/modules/data/wavreader/wavreader.js +128 -0
  34. package/moddable/modules/data/zlib/deflate.c +161 -0
  35. package/moddable/modules/data/zlib/deflate.js +63 -0
  36. package/moddable/modules/data/zlib/inflate.c +145 -0
  37. package/moddable/modules/data/zlib/inflate.js +66 -0
  38. package/moddable/modules/data/zlib/manifest_deflate.json +9 -0
  39. package/moddable/modules/data/zlib/manifest_inflate.json +9 -0
  40. package/moddable/modules/data/zlib/miniz.c +4924 -0
  41. package/moddable/xs/includes/xs.d.ts +73 -0
  42. package/moddable/xs/includes/xs.h +1533 -0
  43. package/moddable/xs/includes/xsmc.h +206 -0
  44. package/moddable/xs/makefiles/lin/makefile +33 -0
  45. package/moddable/xs/makefiles/lin/xsc.mk +118 -0
  46. package/moddable/xs/makefiles/lin/xsid.mk +90 -0
  47. package/moddable/xs/makefiles/lin/xsl.mk +168 -0
  48. package/moddable/xs/makefiles/lin/xst.mk +201 -0
  49. package/moddable/xs/makefiles/mac/makefile +33 -0
  50. package/moddable/xs/makefiles/mac/xsc.mk +130 -0
  51. package/moddable/xs/makefiles/mac/xsid.mk +102 -0
  52. package/moddable/xs/makefiles/mac/xsl.mk +177 -0
  53. package/moddable/xs/makefiles/mac/xst.mk +203 -0
  54. package/moddable/xs/makefiles/mac/xst_no_asan.txt +52 -0
  55. package/moddable/xs/makefiles/win/build.bat +26 -0
  56. package/moddable/xs/makefiles/win/xsc.mak +142 -0
  57. package/moddable/xs/makefiles/win/xsid.mak +113 -0
  58. package/moddable/xs/makefiles/win/xsl.mak +186 -0
  59. package/moddable/xs/makefiles/win/xst.mak +195 -0
  60. package/moddable/xs/platforms/lin_xs.h +99 -0
  61. package/moddable/xs/platforms/mac_xs.h +97 -0
  62. package/moddable/xs/platforms/wasm_xs.h +79 -0
  63. package/moddable/xs/platforms/win_xs.h +104 -0
  64. package/moddable/xs/platforms/xsHost.h +63 -0
  65. package/moddable/xs/platforms/xsPlatform.h +618 -0
  66. package/moddable/xs/sources/xsAPI.c +2555 -0
  67. package/moddable/xs/sources/xsAll.c +294 -0
  68. package/moddable/xs/sources/xsAll.h +2741 -0
  69. package/moddable/xs/sources/xsArguments.c +222 -0
  70. package/moddable/xs/sources/xsArray.c +2657 -0
  71. package/moddable/xs/sources/xsAtomics.c +844 -0
  72. package/moddable/xs/sources/xsBigInt.c +1859 -0
  73. package/moddable/xs/sources/xsBoolean.c +109 -0
  74. package/moddable/xs/sources/xsCode.c +4493 -0
  75. package/moddable/xs/sources/xsCommon.c +1710 -0
  76. package/moddable/xs/sources/xsCommon.h +1142 -0
  77. package/moddable/xs/sources/xsDataView.c +2890 -0
  78. package/moddable/xs/sources/xsDate.c +1541 -0
  79. package/moddable/xs/sources/xsDebug.c +2710 -0
  80. package/moddable/xs/sources/xsDefaults.c +134 -0
  81. package/moddable/xs/sources/xsError.c +353 -0
  82. package/moddable/xs/sources/xsFunction.c +776 -0
  83. package/moddable/xs/sources/xsGenerator.c +865 -0
  84. package/moddable/xs/sources/xsGlobal.c +839 -0
  85. package/moddable/xs/sources/xsJSON.c +1091 -0
  86. package/moddable/xs/sources/xsLexical.c +1969 -0
  87. package/moddable/xs/sources/xsLockdown.c +933 -0
  88. package/moddable/xs/sources/xsMapSet.c +1649 -0
  89. package/moddable/xs/sources/xsMarshall.c +1020 -0
  90. package/moddable/xs/sources/xsMath.c +624 -0
  91. package/moddable/xs/sources/xsMemory.c +1941 -0
  92. package/moddable/xs/sources/xsModule.c +3101 -0
  93. package/moddable/xs/sources/xsNumber.c +560 -0
  94. package/moddable/xs/sources/xsObject.c +1102 -0
  95. package/moddable/xs/sources/xsPlatforms.c +480 -0
  96. package/moddable/xs/sources/xsProfile.c +577 -0
  97. package/moddable/xs/sources/xsPromise.c +1199 -0
  98. package/moddable/xs/sources/xsProperty.c +636 -0
  99. package/moddable/xs/sources/xsProxy.c +1014 -0
  100. package/moddable/xs/sources/xsRegExp.c +1168 -0
  101. package/moddable/xs/sources/xsRun.c +4889 -0
  102. package/moddable/xs/sources/xsScope.c +1293 -0
  103. package/moddable/xs/sources/xsScript.c +288 -0
  104. package/moddable/xs/sources/xsScript.h +1186 -0
  105. package/moddable/xs/sources/xsSnapshot.c +2161 -0
  106. package/moddable/xs/sources/xsSnapshot.h +51 -0
  107. package/moddable/xs/sources/xsSourceMap.c +218 -0
  108. package/moddable/xs/sources/xsString.c +3332 -0
  109. package/moddable/xs/sources/xsSymbol.c +503 -0
  110. package/moddable/xs/sources/xsSyntaxical.c +4193 -0
  111. package/moddable/xs/sources/xsTree.c +1893 -0
  112. package/moddable/xs/sources/xsType.c +1488 -0
  113. package/moddable/xs/sources/xsdtoa.c +6672 -0
  114. package/moddable/xs/sources/xsmc.c +340 -0
  115. package/moddable/xs/sources/xsre.c +7578 -0
  116. package/package.json +37 -20
  117. package/scripts/get_xsnap_version.sh +14 -0
  118. package/scripts/test-package.sh +21 -0
  119. package/src/avaAssertXS.js +6 -2
  120. package/src/avaHandler.cjs +2 -5
  121. package/src/avaXS.js +7 -8
  122. package/src/build.js +161 -28
  123. package/src/replay.js +0 -3
  124. package/src/xsnap.js +105 -91
  125. package/src/xsrepl.js +2 -3
  126. package/xsnap-native/xsnap/makefiles/lin/makefile +10 -0
  127. package/xsnap-native/xsnap/makefiles/lin/xsnap-worker.mk +156 -0
  128. package/xsnap-native/xsnap/makefiles/lin/xsnap.mk +144 -0
  129. package/xsnap-native/xsnap/makefiles/mac/makefile +10 -0
  130. package/xsnap-native/xsnap/makefiles/mac/xsnap-worker.mk +165 -0
  131. package/xsnap-native/xsnap/makefiles/mac/xsnap.mk +153 -0
  132. package/xsnap-native/xsnap/sources/xsnap-worker.c +1008 -0
  133. package/xsnap-native/xsnap/sources/xsnap.c +717 -0
  134. package/xsnap-native/xsnap/sources/xsnap.h +142 -0
  135. package/xsnap-native/xsnap/sources/xsnapPlatform.c +1501 -0
  136. package/xsnap-native/xsnap/sources/xsnapPlatform.h +105 -0
  137. package/CHANGELOG.md +0 -654
@@ -0,0 +1,2657 @@
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
+ #define mxArraySize(ARRAY) (((ARRAY)->value.array.address) ? (((txChunk*)(((txByte*)((ARRAY)->value.array.address)) - sizeof(txChunk)))->size) / sizeof(txSlot) : 0)
41
+
42
+ static txIndex fxCheckArrayLength(txMachine* the, txSlot* slot);
43
+ static txBoolean fxCallThisItem(txMachine* the, txSlot* function, txIndex index, txSlot* item);
44
+ static txSlot* fxCheckArray(txMachine* the, txSlot* slot, txBoolean mutable);
45
+ static txSlot* fxCheckArrayItems(txMachine* the, txSlot* array, txIndex from, txIndex to);
46
+ static int fxCompareArrayItem(txMachine* the, txSlot* function, txSlot* array, txInteger i);
47
+ static txSlot* fxCreateArray(txMachine* the, txFlag flag, txIndex length);
48
+ static txSlot* fxCreateArraySpecies(txMachine* the, txNumber length);
49
+ static void fxFindThisItem(txMachine* the, txSlot* function, txIndex index, txSlot* item);
50
+ static txNumber fxGetArrayLength(txMachine* the, txSlot* reference);
51
+ static txIndex fxGetArrayLimit(txMachine* the, txSlot* reference);
52
+ static void fxMoveThisItem(txMachine* the, txNumber from, txNumber to);
53
+ static void fxReduceThisItem(txMachine* the, txSlot* function, txIndex index);
54
+ static txBoolean fxSetArrayLength(txMachine* the, txSlot* array, txIndex target);
55
+ static void fx_Array_from_aux(txMachine* the, txSlot* function, txSlot* value, txIndex index);
56
+ static txIndex fx_Array_prototype_flatAux(txMachine* the, txSlot* source, txIndex length, txIndex start, txIndex depth, txSlot* function);
57
+
58
+ static txBoolean fxArrayDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* slot, txFlag mask);
59
+ static txBoolean fxArrayDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index);
60
+ static txBoolean fxArrayGetOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* slot);
61
+ static txSlot* fxArrayGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
62
+ static txBoolean fxArrayHasProperty(txMachine* the, txSlot* instance, txID id, txIndex index);
63
+ static void fxArrayOwnKeys(txMachine* the, txSlot* instance, txFlag flag, txSlot* keys);
64
+ static txSlot* fxArraySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
65
+
66
+ const txBehavior ICACHE_FLASH_ATTR gxArrayBehavior = {
67
+ fxArrayGetProperty,
68
+ fxArraySetProperty,
69
+ fxOrdinaryCall,
70
+ fxOrdinaryConstruct,
71
+ fxArrayDefineOwnProperty,
72
+ fxArrayDeleteProperty,
73
+ fxArrayGetOwnProperty,
74
+ fxOrdinaryGetPropertyValue,
75
+ fxOrdinaryGetPrototype,
76
+ fxArrayHasProperty,
77
+ fxOrdinaryIsExtensible,
78
+ fxArrayOwnKeys,
79
+ fxOrdinaryPreventExtensions,
80
+ fxOrdinarySetPropertyValue,
81
+ fxOrdinarySetPrototype,
82
+ };
83
+
84
+ void fxBuildArray(txMachine* the)
85
+ {
86
+ txSlot* instance;
87
+ txSlot* slot;
88
+ txSlot* property;
89
+ txSlot* unscopable;
90
+
91
+ mxPush(mxObjectPrototype);
92
+ instance = fxNewArrayInstance(the);
93
+
94
+ fxNewHostFunction(the, mxCallback(fxArrayLengthGetter), 0, mxID(_length), XS_NO_ID);
95
+ property = mxFunctionInstanceHome(the->stack->value.reference);
96
+ property->value.home.object = instance;
97
+ fxNewHostFunction(the, mxCallback(fxArrayLengthSetter), 1, mxID(_length), XS_NO_ID);
98
+ property = mxFunctionInstanceHome(the->stack->value.reference);
99
+ property->value.home.object = instance;
100
+ mxPushUndefined();
101
+ the->stack->flag = XS_DONT_DELETE_FLAG;
102
+ the->stack->kind = XS_ACCESSOR_KIND;
103
+ the->stack->value.accessor.getter = (the->stack + 2)->value.reference;
104
+ the->stack->value.accessor.setter = (the->stack + 1)->value.reference;
105
+ mxPull(mxArrayLengthAccessor);
106
+ mxPop();
107
+ mxPop();
108
+
109
+ slot = fxLastProperty(the, instance);
110
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_at), 1, mxID(_at), XS_DONT_ENUM_FLAG);
111
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_concat), 1, mxID(_concat), XS_DONT_ENUM_FLAG);
112
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_copyWithin), 2, mxID(_copyWithin), XS_DONT_ENUM_FLAG);
113
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_entries), 0, mxID(_entries), XS_DONT_ENUM_FLAG);
114
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_every), 1, mxID(_every), XS_DONT_ENUM_FLAG);
115
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_fill), 1, mxID(_fill), XS_DONT_ENUM_FLAG);
116
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_filter), 1, mxID(_filter), XS_DONT_ENUM_FLAG);
117
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_find), 1, mxID(_find), XS_DONT_ENUM_FLAG);
118
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_findIndex), 1, mxID(_findIndex), XS_DONT_ENUM_FLAG);
119
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_findLast), 1, mxID(_findLast), XS_DONT_ENUM_FLAG);
120
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_findLastIndex), 1, mxID(_findLastIndex), XS_DONT_ENUM_FLAG);
121
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_flat), 0, mxID(_flat), XS_DONT_ENUM_FLAG);
122
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_flatMap), 1, mxID(_flatMap), XS_DONT_ENUM_FLAG);
123
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_forEach), 1, mxID(_forEach), XS_DONT_ENUM_FLAG);
124
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_includes), 1, mxID(_includes), XS_DONT_ENUM_FLAG);
125
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_indexOf), 1, mxID(_indexOf), XS_DONT_ENUM_FLAG);
126
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_join), 1, mxID(_join), XS_DONT_ENUM_FLAG);
127
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_keys), 0, mxID(_keys), XS_DONT_ENUM_FLAG);
128
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_lastIndexOf), 1, mxID(_lastIndexOf), XS_DONT_ENUM_FLAG);
129
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_map), 1, mxID(_map), XS_DONT_ENUM_FLAG);
130
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_pop), 0, mxID(_pop), XS_DONT_ENUM_FLAG);
131
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_push), 1, mxID(_push), XS_DONT_ENUM_FLAG);
132
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_reduce), 1, mxID(_reduce), XS_DONT_ENUM_FLAG);
133
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_reduceRight), 1, mxID(_reduceRight), XS_DONT_ENUM_FLAG);
134
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_reverse), 0, mxID(_reverse), XS_DONT_ENUM_FLAG);
135
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_shift), 0, mxID(_shift), XS_DONT_ENUM_FLAG);
136
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_slice), 2, mxID(_slice), XS_DONT_ENUM_FLAG);
137
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_some), 1, mxID(_some), XS_DONT_ENUM_FLAG);
138
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_sort), 1, mxID(_sort), XS_DONT_ENUM_FLAG);
139
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_splice), 2, mxID(_splice), XS_DONT_ENUM_FLAG);
140
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_toLocaleString), 0, mxID(_toLocaleString), XS_DONT_ENUM_FLAG);
141
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_toString), 0, mxID(_toString), XS_DONT_ENUM_FLAG);
142
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_unshift), 1, mxID(_unshift), XS_DONT_ENUM_FLAG);
143
+ property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_prototype_values), 0, mxID(_values), XS_DONT_ENUM_FLAG);
144
+ mxPushSlot(property);
145
+ mxPull(mxArrayIteratorFunction);
146
+ slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
147
+ unscopable = fxLastProperty(the, fxNewInstance(the));
148
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_copyWithin), XS_NO_FLAG);
149
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_at), XS_NO_FLAG);
150
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_entries), XS_NO_FLAG);
151
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_fill), XS_NO_FLAG);
152
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_find), XS_NO_FLAG);
153
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_findIndex), XS_NO_FLAG);
154
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_findLast), XS_NO_FLAG);
155
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_findLastIndex), XS_NO_FLAG);
156
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_flat), XS_NO_FLAG);
157
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_flatMap), XS_NO_FLAG);
158
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_includes), XS_NO_FLAG);
159
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_keys), XS_NO_FLAG);
160
+ unscopable = fxNextBooleanProperty(the, unscopable, 1, mxID(_values), XS_NO_FLAG);
161
+ slot = fxNextSlotProperty(the, slot, the->stack++, mxID(_Symbol_unscopables), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
162
+ mxArrayPrototype = *the->stack;
163
+ slot = fxBuildHostConstructor(the, mxCallback(fx_Array), 1, mxID(_Array));
164
+ mxArrayConstructor = *the->stack;
165
+ slot = fxLastProperty(the, slot);
166
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_from), 1, mxID(_from), XS_DONT_ENUM_FLAG);
167
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_isArray), 1, mxID(_isArray), XS_DONT_ENUM_FLAG);
168
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Array_of), 0, mxID(_of), XS_DONT_ENUM_FLAG);
169
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG);
170
+ mxPop();
171
+
172
+ mxPush(mxIteratorPrototype);
173
+ slot = fxLastProperty(the, fxNewObjectInstance(the));
174
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayIterator_prototype_next), 0, mxID(_next), XS_DONT_ENUM_FLAG);
175
+ slot = fxNextStringXProperty(the, slot, "Array Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
176
+ mxPull(mxArrayIteratorPrototype);
177
+ }
178
+
179
+ txNumber fxArgToIndex(txMachine* the, txInteger argi, txNumber index, txNumber length)
180
+ {
181
+ if ((mxArgc > argi) && (mxArgv(argi)->kind != XS_UNDEFINED_KIND)) {
182
+ txNumber i = c_trunc(fxToNumber(the, mxArgv(argi)));
183
+ if (c_isnan(i) || (i == 0))
184
+ i = 0;
185
+ if (i < 0) {
186
+ i = length + i;
187
+ if (i < 0)
188
+ i = 0;
189
+ }
190
+ else if (i > length)
191
+ i = length;
192
+ index = i;
193
+ }
194
+ return index;
195
+ }
196
+
197
+ txNumber fxArgToLastIndex(txMachine* the, txInteger argi, txNumber index, txNumber length)
198
+ {
199
+ if (mxArgc > argi) {
200
+ txNumber i = c_trunc(fxToNumber(the, mxArgv(argi)));
201
+ if (c_isnan(i) || (i == 0))
202
+ i = 0;
203
+ if (i < 0) {
204
+ i = length + i;
205
+ if (i < 0)
206
+ index = 0;
207
+ else
208
+ index = i + 1;
209
+ }
210
+ else if (i < length)
211
+ index = i + 1;
212
+ }
213
+ return index;
214
+ }
215
+
216
+ txNumber fxArgToRange(txMachine* the, txInteger argi, txNumber index, txNumber min, txNumber max)
217
+ {
218
+ if ((mxArgc > argi) && (mxArgv(argi)->kind != XS_UNDEFINED_KIND)) {
219
+ txNumber i = c_trunc(fxToNumber(the, mxArgv(argi)));
220
+ if (c_isnan(i))
221
+ i = min;
222
+ if (i <= min)
223
+ i = min;
224
+ else if (i > max)
225
+ i = max;
226
+ index = i;
227
+ }
228
+ return index;
229
+ }
230
+
231
+ void fxCacheArray(txMachine* the, txSlot* instance)
232
+ {
233
+ txSlot* array = instance->next;
234
+ txIndex length = array->value.array.length;
235
+ if (length) {
236
+ txSlot* address = (txSlot *)fxNewChunk(the, fxMultiplyChunkSizes(the, length, sizeof(txSlot)));
237
+ txSlot* srcSlot = array->next;
238
+ txSlot* dstSlot = address;
239
+ txIndex index = 0;
240
+ while (srcSlot) {
241
+ dstSlot->next = C_NULL;
242
+ *((txIndex*)dstSlot) = index;
243
+ dstSlot->ID = XS_NO_ID;
244
+ dstSlot->flag = XS_NO_FLAG;
245
+ dstSlot->kind = srcSlot->kind;
246
+ dstSlot->value = srcSlot->value;
247
+ srcSlot = srcSlot->next;
248
+ dstSlot++;
249
+ index++;
250
+ }
251
+ array->value.array.address = address;
252
+ array->next = C_NULL;
253
+ }
254
+ }
255
+
256
+ txBoolean fxCallThisItem(txMachine* the, txSlot* function, txIndex index, txSlot* item)
257
+ {
258
+ mxPushSlot(mxThis);
259
+ if (mxHasIndex(index)) {
260
+ /* THIS */
261
+ if (mxArgc > 1)
262
+ mxPushSlot(mxArgv(1));
263
+ else
264
+ mxPushUndefined();
265
+ /* FUNCTION */
266
+ mxPushSlot(function);
267
+ mxCall();
268
+ /* ARGUMENTS */
269
+ mxPushSlot(mxThis);
270
+ mxGetIndex(index);
271
+ if (item) {
272
+ item->kind = the->stack->kind;
273
+ item->value = the->stack->value;
274
+ }
275
+ mxPushUnsigned(index);
276
+ mxPushSlot(mxThis);
277
+ mxRunCount(3);
278
+ return 1;
279
+ }
280
+ return 0;
281
+ }
282
+
283
+ txSlot* fxCheckArray(txMachine* the, txSlot* slot, txBoolean mutable)
284
+ {
285
+ txSlot* instance = fxToInstance(the, slot);
286
+ txSlot* array = instance->next;
287
+ if (array && (array->kind == XS_ARRAY_KIND) && (array->ID == XS_ARRAY_BEHAVIOR)) {
288
+ if (instance->ID) {
289
+ txSlot* alias = the->aliasArray[instance->ID];
290
+ if (alias)
291
+ array = alias->next;
292
+ else if (mutable) {
293
+ instance = fxAliasInstance(the, instance);
294
+ array = instance->next;
295
+ }
296
+ }
297
+ {
298
+ txSlot* address = array->value.array.address;
299
+ txIndex size = (address) ? (((txChunk*)(((txByte*)address) - sizeof(txChunk)))->size) / sizeof(txSlot) : 0;
300
+ txSlot* prototype = instance->value.instance.prototype;
301
+ if (array->value.array.length != size)
302
+ return C_NULL;
303
+ if (mutable && ((instance->flag & XS_DONT_PATCH_FLAG) || (array->flag & XS_DONT_SET_FLAG)))
304
+ return C_NULL;
305
+ while (prototype) {
306
+ txSlot* property = prototype->next;
307
+ while (property) {
308
+ if (property->flag & XS_INTERNAL_FLAG) {
309
+ if ((property->kind == XS_ARRAY_KIND) && (property->value.array.address != C_NULL))
310
+ return C_NULL;
311
+ }
312
+ else
313
+ break;
314
+ property = property->next;
315
+ }
316
+ prototype = prototype->value.instance.prototype;
317
+ }
318
+ return array;
319
+ }
320
+ }
321
+ return C_NULL;
322
+ }
323
+
324
+ txSlot* fxCheckArrayItems(txMachine* the, txSlot* array, txIndex from, txIndex to)
325
+ {
326
+ txSlot* address = array->value.array.address;
327
+ txIndex length = array->value.array.length;
328
+ if (length < from)
329
+ return C_NULL;
330
+ if (length < to)
331
+ return C_NULL;
332
+ address += from;
333
+ while (from < to) {
334
+ if (address->flag)
335
+ return C_NULL;
336
+ if (address->kind == XS_ACCESSOR_KIND)
337
+ return C_NULL;
338
+ address++;
339
+ from++;
340
+ }
341
+ return array;
342
+ }
343
+
344
+ txIndex fxCheckArrayLength(txMachine* the, txSlot* slot)
345
+ {
346
+ if (slot->kind == XS_INTEGER_KIND) {
347
+ if (slot->value.integer >= 0)
348
+ return (txIndex)slot->value.integer;
349
+ }
350
+ else if (slot->kind == XS_NUMBER_KIND) {
351
+ txIndex length = (txIndex)slot->value.number;
352
+ txNumber check = length;
353
+ if (slot->value.number == check)
354
+ return length;
355
+ }
356
+ else {
357
+ txUnsigned length;
358
+ txNumber check;
359
+ mxPushSlot(slot);
360
+ length = fxToUnsigned(the, the->stack);
361
+ mxPop();
362
+ mxPushSlot(slot);
363
+ check = fxToNumber(the, the->stack);
364
+ mxPop();
365
+ if (length == check)
366
+ return length;
367
+ }
368
+ mxRangeError("invalid length");
369
+ return 0;
370
+ }
371
+
372
+ int fxCompareArrayItem(txMachine* the, txSlot* function, txSlot* array, txInteger i)
373
+ {
374
+ txSlot* address = array->value.array.address;
375
+ txSlot* a = address + i;
376
+ txSlot* b = the->stack;
377
+ txSlot* ai = a->next;
378
+ txSlot* bi = b->next;
379
+ int result;
380
+
381
+ if (a->kind == XS_UNDEFINED_KIND)
382
+ result = (b->kind == XS_UNDEFINED_KIND) ? 0 : 1;
383
+ else if (b->kind == XS_UNDEFINED_KIND)
384
+ result = -1;
385
+ else {
386
+ if (function) {
387
+ /* THIS */
388
+ mxPushUndefined();
389
+ /* FUNCTION */
390
+ mxPushSlot(function);
391
+ mxCall();
392
+ /* ARGUMENTS */
393
+ mxPushSlot(a);
394
+ mxPushSlot(b);
395
+ mxRunCount(2);
396
+ if (the->stack->kind == XS_INTEGER_KIND)
397
+ result = the->stack->value.integer;
398
+ else {
399
+ txNumber number = fxToNumber(the, the->stack);
400
+ result = (number < 0) ? -1 : (number > 0) ? 1 : 0;
401
+ }
402
+ mxPop();
403
+ }
404
+ else {
405
+ mxPushSlot(a);
406
+ mxPushSlot(b);
407
+ fxToString(the, the->stack + 1);
408
+ fxToString(the, the->stack);
409
+ result = fxUTF8Compare((the->stack + 1)->value.string, the->stack->value.string);
410
+ mxPop();
411
+ mxPop();
412
+ mxMeterSome(3);
413
+ }
414
+ }
415
+ if (result == 0)
416
+ result = (bi > ai) ? -1 : (bi < ai) ? 1 : 0;
417
+ return result;
418
+ }
419
+
420
+ void fxConstructArrayEntry(txMachine* the, txSlot* entry)
421
+ {
422
+ txSlot* value = the->stack;
423
+ txSlot* key = the->stack + 1;
424
+ txSlot* instance;
425
+ txSlot* array;
426
+ txSlot* item;
427
+ mxPush(mxArrayPrototype);
428
+ instance = fxNewArrayInstance(the);
429
+ array = instance->next;
430
+ fxSetIndexSize(the, array, 2, XS_CHUNK);
431
+ item = array->value.array.address;
432
+ *((txIndex*)item) = 0;
433
+ item->ID = XS_NO_ID;
434
+ item->kind = key->kind;
435
+ item->value = key->value;
436
+ item++;
437
+ *((txIndex*)item) = 1;
438
+ item->ID = XS_NO_ID;
439
+ item->kind = value->kind;
440
+ item->value = value->value;
441
+ entry->kind = the->stack->kind;
442
+ entry->value = the->stack->value;
443
+ the->stack += 3;
444
+ }
445
+
446
+ txSlot* fxCreateArray(txMachine* the, txFlag flag, txIndex length)
447
+ {
448
+ txBoolean resize = 1;
449
+ if (mxIsReference(mxThis) && mxIsConstructor(mxThis->value.reference)) {
450
+ mxPushSlot(mxThis);
451
+ if (the->stack->value.reference != mxArrayConstructor.value.reference)
452
+ resize = 0;
453
+ }
454
+ else
455
+ mxPush(mxArrayConstructor);
456
+ mxNew();
457
+ if (flag) {
458
+ mxPushUnsigned(length);
459
+ mxRunCount(1);
460
+ }
461
+ else
462
+ mxRunCount(0);
463
+ mxPullSlot(mxResult);
464
+ if (resize)
465
+ fxSetIndexSize(the, mxResult->value.reference->next, length, XS_CHUNK);
466
+ return fxCheckArray(the, mxResult, XS_MUTABLE);
467
+ }
468
+
469
+ txSlot* fxCreateArraySpecies(txMachine* the, txNumber length)
470
+ {
471
+ txSlot* instance = fxToInstance(the, mxThis);
472
+ txFlag flag = 1;
473
+ if (fxIsArray(the, instance)) {
474
+ mxPushSlot(mxThis);
475
+ mxGetID(mxID(_constructor));
476
+ if (mxIsReference(the->stack)) {
477
+ mxGetID(mxID(_Symbol_species));
478
+ if (the->stack->kind == XS_NULL_KIND)
479
+ the->stack->kind = XS_UNDEFINED_KIND;
480
+ }
481
+ }
482
+ else
483
+ mxPushUndefined();
484
+ if (the->stack->kind == XS_UNDEFINED_KIND) {
485
+ *the->stack = mxArrayConstructor;
486
+ flag = 0;
487
+ }
488
+ else if (mxIsReference(the->stack) && mxIsConstructor(the->stack->value.reference)) {
489
+ if (the->stack->value.reference != mxArrayConstructor.value.reference)
490
+ flag = 0;
491
+ }
492
+ else
493
+ mxTypeError("invalid constructor");
494
+ mxNew();
495
+ mxPushNumber(length);
496
+ mxRunCount(1);
497
+ mxPullSlot(mxResult);
498
+ return (flag) ? mxResult->value.reference->next : C_NULL;
499
+ }
500
+
501
+ void fxFindThisItem(txMachine* the, txSlot* function, txIndex index, txSlot* item)
502
+ {
503
+ /* THIS */
504
+ if (mxArgc > 1)
505
+ mxPushSlot(mxArgv(1));
506
+ else
507
+ mxPushUndefined();
508
+ /* FUNCTION */
509
+ mxPushSlot(function);
510
+ mxCall();
511
+ /* ARGUMENTS */
512
+ mxPushSlot(mxThis);
513
+ mxGetIndex(index);
514
+ if (item) {
515
+ item->kind = the->stack->kind;
516
+ item->value = the->stack->value;
517
+ }
518
+ mxPushUnsigned(index);
519
+ mxPushSlot(mxThis);
520
+ /* ARGC */
521
+ mxRunCount(3);
522
+ }
523
+
524
+ txNumber fxGetArrayLength(txMachine* the, txSlot* reference)
525
+ {
526
+ txNumber length;
527
+ txSlot* instance = fxToInstance(the, reference);
528
+ mxPushReference(instance);
529
+ mxGetID(mxID(_length));
530
+ length = fxToLength(the, the->stack);
531
+ mxPop();
532
+ return length;
533
+ }
534
+
535
+ txIndex fxGetArrayLimit(txMachine* the, txSlot* reference)
536
+ {
537
+ txNumber length;
538
+ txSlot* instance = fxToInstance(the, reference);
539
+ txSlot* array = instance->next;
540
+ if (array && (array->kind == XS_ARRAY_KIND) && (array->ID == XS_ARRAY_BEHAVIOR)) {
541
+ if (instance->ID) {
542
+ txSlot* alias = the->aliasArray[instance->ID];
543
+ if (alias)
544
+ array = alias->next;
545
+ }
546
+ return array->value.array.length;
547
+ }
548
+ if (array && (array->kind == XS_TYPED_ARRAY_KIND) && (array->ID == XS_TYPED_ARRAY_BEHAVIOR)) {
549
+ txSlot* view = array->next;
550
+ txSlot* buffer = view->next;
551
+ txSlot* data = buffer->value.reference->next;
552
+ if (data->value.arrayBuffer.address == C_NULL)
553
+ mxTypeError("detached buffer");
554
+ return fxGetDataViewSize(the, view, buffer) >> array->value.typedArray.dispatch->shift;
555
+ }
556
+ mxPushReference(instance);
557
+ mxGetID(mxID(_length));
558
+ length = fxToLength(the, the->stack);
559
+ mxPop();
560
+ if (length > 0xFFFFFFFF) { // @@ practical limit for iterations
561
+ txSlot* result = instance->next;
562
+ length = 0;
563
+ while (result && (result->flag & XS_INTERNAL_FLAG)) {
564
+ if (result->kind == XS_ARRAY_KIND) {
565
+ length = array->value.array.length;
566
+ break;
567
+ }
568
+ result = result->next;
569
+ }
570
+ }
571
+ return (txIndex)length;
572
+ }
573
+
574
+ void fxIndexArray(txMachine* the, txSlot* array)
575
+ {
576
+ txSlot* address = array->value.array.address;
577
+ if (address) {
578
+ txIndex size = (((txChunk*)(((txByte*)address) - sizeof(txChunk)))->size) / sizeof(txSlot);
579
+ txIndex index = 0;
580
+ while (index < size) {
581
+ *((txIndex*)address) = index;
582
+ address->flag = XS_NO_FLAG;
583
+ address++;
584
+ index++;
585
+ }
586
+ }
587
+ }
588
+
589
+ txBoolean fxIsArray(txMachine* the, txSlot* instance)
590
+ {
591
+ again:
592
+ if (instance) {
593
+ txSlot* internal = instance->next;
594
+ if (internal && (internal->flag & XS_INTERNAL_FLAG)) {
595
+ if ((internal->kind == XS_ARRAY_KIND) && (internal->ID == XS_ARRAY_BEHAVIOR))
596
+ return 1;
597
+ if (internal->kind == XS_PROXY_KIND) {
598
+ instance = internal->value.proxy.target;
599
+ if (instance)
600
+ goto again;
601
+ mxTypeError("revoked proxy");
602
+
603
+ }
604
+ }
605
+ }
606
+ return 0;
607
+ }
608
+
609
+ void fxMoveThisItem(txMachine* the, txNumber from, txNumber to)
610
+ {
611
+ mxPushSlot(mxThis);
612
+ mxPushNumber(from);
613
+ if (mxHasAt()) {
614
+ mxPushSlot(mxThis);
615
+ mxPushNumber(from);
616
+ mxGetAt();
617
+ mxPushSlot(mxThis);
618
+ mxPushNumber(to);
619
+ mxSetAt();
620
+ mxPop();
621
+ }
622
+ else {
623
+ mxPushSlot(mxThis);
624
+ mxPushNumber(to);
625
+ mxDeleteAt();
626
+ mxPop();
627
+ }
628
+ }
629
+
630
+ txSlot* fxNewArrayInstance(txMachine* the)
631
+ {
632
+ txSlot* instance;
633
+ txSlot* property;
634
+ instance = fxNewObjectInstance(the);
635
+ instance->flag |= XS_EXOTIC_FLAG;
636
+ property = instance->next = fxNewSlot(the);
637
+ property->flag = XS_INTERNAL_FLAG | XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG;
638
+ property->ID = XS_ARRAY_BEHAVIOR;
639
+ property->kind = XS_ARRAY_KIND;
640
+ property->value.array.length = 0;
641
+ property->value.array.address = C_NULL;
642
+ return instance;
643
+ }
644
+
645
+ void fxReduceThisItem(txMachine* the, txSlot* function, txIndex index)
646
+ {
647
+ mxPushSlot(mxThis);
648
+ if (fxHasIndex(the, index)) {
649
+ /* THIS */
650
+ mxPushUndefined();
651
+ /* FUNCTION */
652
+ mxPushSlot(function);
653
+ mxCall();
654
+ /* ARGUMENTS */
655
+ mxPushSlot(mxResult);
656
+ mxPushSlot(mxThis);
657
+ mxGetIndex(index);
658
+ mxPushUnsigned(index);
659
+ mxPushSlot(mxThis);
660
+ mxRunCount(4);
661
+ mxPullSlot(mxResult);
662
+ }
663
+ }
664
+
665
+ txBoolean fxSetArrayLength(txMachine* the, txSlot* array, txIndex length)
666
+ {
667
+ txSlot* address = array->value.array.address;
668
+ txSlot* chunk = address;
669
+ txBoolean success = 1;
670
+ if (address) {
671
+ txSize size = (((txChunk*)(((txByte*)chunk) - sizeof(txChunk)))->size) / sizeof(txSlot);
672
+ txSlot* result = address + size;
673
+ txSlot* limit = result;
674
+ txIndex at;
675
+ while (result > address) {
676
+ result--;
677
+ at = *((txIndex*)result);
678
+ if (length > at) {
679
+ result++;
680
+ break;
681
+ }
682
+ else if (result->flag & XS_DONT_DELETE_FLAG) {
683
+ result++;
684
+ length = at + 1;
685
+ success = 0;
686
+ break;
687
+ }
688
+ }
689
+ if (result < limit) {
690
+ if (result > address) {
691
+ size = mxPtrDiff(result - address);
692
+ chunk = (txSlot*)fxNewChunk(the, fxMultiplyChunkSizes(the, size, sizeof(txSlot)));
693
+ address = array->value.array.address;
694
+ c_memcpy(chunk, address, size * sizeof(txSlot));
695
+ }
696
+ else
697
+ chunk = C_NULL;
698
+ }
699
+ }
700
+ array->value.array.length = length;
701
+ array->value.array.address = chunk;
702
+ return success;
703
+ }
704
+
705
+ void fxSortArrayItems(txMachine* the, txSlot* function, txSlot* array, txNumber LENGTH)
706
+ {
707
+ txSlot* instance = C_NULL;
708
+ txIndex index;
709
+ txSlot* item;
710
+ txIndex length;
711
+ txIndex size;
712
+ again:
713
+ if (!array) {
714
+ LENGTH = fxGetArrayLength(the, mxThis);
715
+ if (LENGTH > 0xFFFFFFFF)
716
+ mxRangeError("array overflow");
717
+ mxPush(mxArrayPrototype);
718
+ instance = fxNewArrayInstance(the);
719
+ array = instance->next;
720
+ item = array;
721
+ index = 0;
722
+ while (index < LENGTH) {
723
+ mxPushSlot(mxThis);
724
+ if (fxHasIndex(the, index)) {
725
+ item->next = fxNewSlot(the);
726
+ item = item->next;
727
+ array->value.array.length++;
728
+ mxPushSlot(mxThis);
729
+ mxGetIndex(index);
730
+ mxPullSlot(item);
731
+ }
732
+ index++;
733
+ }
734
+ fxCacheArray(the, instance);
735
+ }
736
+ length = array->value.array.length;
737
+ size = mxArraySize(array);
738
+ /* like GCC qsort */
739
+ #define CHECK \
740
+ if (size != mxArraySize(array)) { \
741
+ array = C_NULL; \
742
+ goto again; \
743
+ }
744
+ #define COMPARE(INDEX) \
745
+ fxCompareArrayItem(the, function, array, INDEX)
746
+ #define COPY \
747
+ to->next = from->next; \
748
+ to->ID = from->ID; \
749
+ to->kind = from->kind; \
750
+ to->value = from->value
751
+ #define MOVE(FROM,TO) \
752
+ from = array->value.array.address + (FROM); \
753
+ to = array->value.array.address + (TO); \
754
+ COPY
755
+ #define PUSH(INDEX) \
756
+ from = array->value.array.address + (INDEX); \
757
+ mxPushUndefined(); \
758
+ to = the->stack; \
759
+ COPY
760
+ #define PULL(INDEX) \
761
+ from = the->stack++; \
762
+ to = array->value.array.address + (INDEX); \
763
+ COPY
764
+ if (length > 0) {
765
+ txIndex i, j;
766
+ txSlot* from;
767
+ txSlot* to;
768
+ if (length > mxSortThreshold) {
769
+ txIndex lo = 0, hi = length - 1;
770
+ txSortPartition stack[mxSortPartitionCount];
771
+ txSortPartition *top = stack + 1;
772
+ while (stack < top) {
773
+ txIndex mid = lo + ((hi - lo) >> 1);
774
+ PUSH(mid);
775
+ if (COMPARE(lo) > 0) {
776
+ CHECK;
777
+ MOVE(lo, mid);
778
+ PULL(lo);
779
+ PUSH(mid);
780
+ }
781
+ else
782
+ CHECK;
783
+ if (COMPARE(hi) < 0) {
784
+ CHECK;
785
+ MOVE(hi, mid);
786
+ PULL(hi);
787
+ PUSH(mid);
788
+ if (COMPARE(lo) > 0) {
789
+ CHECK;
790
+ MOVE(lo, mid);
791
+ PULL(lo);
792
+ PUSH(mid);
793
+ }
794
+ else
795
+ CHECK;
796
+ }
797
+ else
798
+ CHECK;
799
+ i = lo + 1;
800
+ j = hi - 1;
801
+ do {
802
+ while ((COMPARE(i) < 0) && (i <= j)) { CHECK; i++; }
803
+ CHECK;
804
+ while ((COMPARE(j) > 0) && (i <= j)) { CHECK; j--; }
805
+ CHECK;
806
+ if (i < j) {
807
+ PUSH(i);
808
+ MOVE(j, i);
809
+ PULL(j);
810
+ i++;
811
+ j--;
812
+ }
813
+ else if (i == j) {
814
+ i++;
815
+ j--;
816
+ break;
817
+ }
818
+ } while (i <= j);
819
+ if ((j - lo) <= mxSortThreshold) {
820
+ if ((hi - i) <= mxSortThreshold) {
821
+ top--;
822
+ lo = top->lo;
823
+ hi = top->hi;
824
+ }
825
+ else {
826
+ lo = i;
827
+ }
828
+ }
829
+ else if ((hi - i) <= mxSortThreshold) {
830
+ hi = j;
831
+ }
832
+ else if ((j - lo) > (hi - i)) {
833
+ top->lo = lo;
834
+ top->hi = j;
835
+ top++;
836
+ lo = i;
837
+ }
838
+ else {
839
+ top->lo = i;
840
+ top->hi = hi;
841
+ top++;
842
+ hi = j;
843
+ }
844
+ mxPop();
845
+ }
846
+ }
847
+ for (i = 1; i < length; i++) {
848
+ PUSH(i);
849
+ for (j = i; (j > 0) && (COMPARE(j - 1) > 0); j--) {
850
+ CHECK;
851
+ MOVE(j - 1, j);
852
+ }
853
+ CHECK;
854
+ PULL(j);
855
+ }
856
+ }
857
+ if (instance) {
858
+ index = 0;
859
+ while (index < length) {
860
+ item = array->value.array.address + index;
861
+ mxPushSlot(item);
862
+ mxPushSlot(mxThis);
863
+ mxSetIndex(index);
864
+ mxPop();
865
+ index++;
866
+ }
867
+ while (index < LENGTH) {
868
+ mxPushSlot(mxThis);
869
+ mxDeleteIndex(index);
870
+ index++;
871
+ }
872
+ mxPop();
873
+ }
874
+ else
875
+ fxIndexArray(the, array);
876
+ }
877
+
878
+ txNumber fxToLength(txMachine* the, txSlot* slot)
879
+ {
880
+ again:
881
+ if (slot->kind == XS_INTEGER_KIND) {
882
+ txInteger length = slot->value.integer;
883
+ if (length < 0)
884
+ length = 0;
885
+ slot->value.number = (txNumber)length;
886
+ slot->kind = XS_NUMBER_KIND;
887
+ return (txNumber)length;
888
+ }
889
+ if (slot->kind == XS_NUMBER_KIND) {
890
+ txNumber length = slot->value.number;
891
+ if (c_isnan(length))
892
+ length = 0;
893
+ else if (length <= 0)
894
+ length = 0;
895
+ else if (length > C_MAX_SAFE_INTEGER)
896
+ length = C_MAX_SAFE_INTEGER;
897
+ else
898
+ length = c_trunc(length);
899
+ slot->value.number = length;
900
+ return length;
901
+ }
902
+ fxToNumber(the, slot);
903
+ goto again;
904
+ }
905
+
906
+ void fxArrayLengthGetter(txMachine* the)
907
+ {
908
+ txSlot* instance = fxToInstance(the, mxThis);
909
+ txSlot* array;
910
+ while (instance) {
911
+ if (instance->flag & XS_EXOTIC_FLAG) {
912
+ array = instance->next;
913
+ if ((array->kind == XS_ARRAY_KIND) && (array->ID == XS_ARRAY_BEHAVIOR))
914
+ break;
915
+ }
916
+ instance = fxGetPrototype(the, instance);
917
+ }
918
+ if (!instance)
919
+ return;
920
+ if (instance->ID) {
921
+ txSlot* alias = the->aliasArray[instance->ID];
922
+ if (alias)
923
+ array = alias->next;
924
+ }
925
+ if (((txInteger)array->value.array.length) < 0) {
926
+ mxResult->value.number = array->value.array.length;
927
+ mxResult->kind = XS_NUMBER_KIND;
928
+ }
929
+ else {
930
+ mxResult->value.integer = (txInteger)array->value.array.length;
931
+ mxResult->kind = XS_INTEGER_KIND;
932
+ }
933
+ }
934
+
935
+ void fxArrayLengthSetter(txMachine* the)
936
+ {
937
+ txSlot* instance = fxToInstance(the, mxThis);
938
+ txSlot* array;
939
+ txIndex length;
940
+ while (instance) {
941
+ if (instance->flag & XS_EXOTIC_FLAG) {
942
+ array = instance->next;
943
+ if (array->ID == XS_ARRAY_BEHAVIOR)
944
+ break;
945
+ }
946
+ instance = fxGetPrototype(the, instance);
947
+ }
948
+ if (!instance)
949
+ return;
950
+ if (instance->ID) {
951
+ txSlot* alias = the->aliasArray[instance->ID];
952
+ if (!alias)
953
+ alias = fxAliasInstance(the, instance);
954
+ array = alias->next;
955
+ }
956
+ length = fxCheckArrayLength(the, mxArgv(0));
957
+ if (array->flag & XS_DONT_SET_FLAG) {
958
+ if (the->frame->next->flag & XS_STRICT_FLAG)
959
+ mxTypeError("set length: not writable");
960
+ else
961
+ return;
962
+ }
963
+ fxSetArrayLength(the, array, length);
964
+ mxResult->value.number = array->value.array.length;
965
+ mxResult->kind = XS_NUMBER_KIND;
966
+ }
967
+
968
+ txBoolean fxArrayDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* descriptor, txFlag mask)
969
+ {
970
+ if (id == mxID(_length)) {
971
+ txSlot* array = instance->next;
972
+ txSlot slot;
973
+ txBoolean result = 1;
974
+ txIndex length = ((descriptor->kind != XS_UNINITIALIZED_KIND) && (descriptor->kind != XS_ACCESSOR_KIND)) ? fxCheckArrayLength(the, descriptor) : 0;
975
+ slot.flag = array->flag;
976
+ slot.ID = id;
977
+ slot.kind = XS_NUMBER_KIND;
978
+ slot.value.number = array->value.array.length;
979
+ if (!fxIsPropertyCompatible(the, &slot, descriptor, mask))
980
+ return 0;
981
+ if (instance->ID) {
982
+ txSlot* alias = the->aliasArray[instance->ID];
983
+ if (!alias) {
984
+ alias = fxAliasInstance(the, instance);
985
+ array = alias->next;
986
+ }
987
+ }
988
+ if (descriptor->kind != XS_UNINITIALIZED_KIND) {
989
+ if (array->value.array.length != length)
990
+ result = fxSetArrayLength(the, array, length);
991
+ }
992
+ if ((mask & XS_DONT_SET_FLAG) && (descriptor->flag & XS_DONT_SET_FLAG) && !(array->flag & XS_DONT_SET_FLAG))
993
+ array->flag |= XS_DONT_SET_FLAG;
994
+ return result;
995
+ }
996
+ return fxOrdinaryDefineOwnProperty(the, instance, id, index, descriptor, mask);
997
+ }
998
+
999
+ txBoolean fxArrayDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index)
1000
+ {
1001
+ if (id == mxID(_length))
1002
+ return 0;
1003
+ return fxOrdinaryDeleteProperty(the, instance, id, index);
1004
+ }
1005
+
1006
+ txBoolean fxArrayGetOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* descriptor)
1007
+ {
1008
+ if (id == mxID(_length)) {
1009
+ txSlot* array = instance->next;
1010
+ descriptor->flag = array->flag;
1011
+ descriptor->ID = id;
1012
+ descriptor->kind = XS_NUMBER_KIND;
1013
+ descriptor->value.number = array->value.array.length;
1014
+ return 1;
1015
+ }
1016
+ return fxOrdinaryGetOwnProperty(the, instance, id, index, descriptor);
1017
+ }
1018
+
1019
+ txSlot* fxArrayGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
1020
+ {
1021
+ if (id == mxID(_length))
1022
+ return &mxArrayLengthAccessor;
1023
+ return fxOrdinaryGetProperty(the, instance, id, index, flag);
1024
+ }
1025
+
1026
+ txBoolean fxArrayHasProperty(txMachine* the, txSlot* instance, txID id, txIndex index)
1027
+ {
1028
+ if (id == mxID(_length))
1029
+ return 1;
1030
+ return fxOrdinaryHasProperty(the, instance, id, index);
1031
+ }
1032
+
1033
+ void fxArrayOwnKeys(txMachine* the, txSlot* instance, txFlag flag, txSlot* keys)
1034
+ {
1035
+ txSlot* property = instance->next;
1036
+ keys = fxQueueIndexKeys(the, property, flag, keys);
1037
+ if (flag & XS_EACH_NAME_FLAG)
1038
+ keys = fxQueueKey(the, mxID(_length), 0, keys);
1039
+ property = property->next;
1040
+ fxQueueIDKeys(the, property, flag, keys);
1041
+ }
1042
+
1043
+ txSlot* fxArraySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
1044
+ {
1045
+ if (id == mxID(_length)) {
1046
+ txSlot* array = instance->next;
1047
+ if (array->flag & XS_DONT_SET_FLAG)
1048
+ return array;
1049
+ return &mxArrayLengthAccessor;
1050
+ }
1051
+ return fxOrdinarySetProperty(the, instance, id, index, flag);
1052
+ }
1053
+
1054
+ void fx_Array(txMachine* the)
1055
+ {
1056
+ txSlot* instance;
1057
+ txSlot* array;
1058
+ txSlot* argument;
1059
+ txIndex count = (txIndex)mxArgc;
1060
+ txBoolean flag = 0;
1061
+ txIndex index = 0;
1062
+ txSlot* slot;
1063
+
1064
+ if (mxIsUndefined(mxTarget))
1065
+ mxPushSlot(mxFunction);
1066
+ else
1067
+ mxPushSlot(mxTarget);
1068
+ fxGetPrototypeFromConstructor(the, &mxArrayPrototype);
1069
+ instance = fxNewArrayInstance(the);
1070
+ mxPullSlot(mxResult);
1071
+ array = instance->next;
1072
+
1073
+ if (count == 1) {
1074
+ argument = mxArgv(0);
1075
+ if ((argument->kind == XS_INTEGER_KIND) || (argument->kind == XS_NUMBER_KIND)) {
1076
+ count = fxCheckArrayLength(the, mxArgv(0));
1077
+ flag = 1;
1078
+ }
1079
+ }
1080
+ if (array) {
1081
+ if (flag)
1082
+ fxSetArrayLength(the, array, count);
1083
+ else {
1084
+ fxSetIndexSize(the, array, count, XS_CHUNK);
1085
+ slot = array->value.array.address;
1086
+ while (index < count) {
1087
+ argument = mxArgv(index);
1088
+ *((txIndex*)slot) = index;
1089
+ slot->ID = XS_NO_ID;
1090
+ slot->kind = argument->kind;
1091
+ slot->value = argument->value;
1092
+ slot++;
1093
+ index++;
1094
+ }
1095
+ }
1096
+ }
1097
+ else {
1098
+ mxPushNumber(count);
1099
+ mxPushSlot(mxThis);
1100
+ mxSetID(mxID(_length));
1101
+ mxPop();
1102
+ if (!flag) {
1103
+ while (index < count) {
1104
+ mxPushSlot(mxArgv(index));
1105
+ mxPushSlot(mxThis);
1106
+ mxDefineIndex(index, 0, XS_GET_ONLY);
1107
+ mxPop();
1108
+ index++;
1109
+ }
1110
+ }
1111
+ }
1112
+ }
1113
+
1114
+ void fx_Array_from(txMachine* the)
1115
+ {
1116
+ txSlot* function = (mxArgc > 1) ? fxArgToCallback(the, 1) : C_NULL;
1117
+ txIndex length = 0;
1118
+ txSlot* iterator;
1119
+ txSlot* next;
1120
+ txSlot* value;
1121
+ if (mxArgc > 0) {
1122
+ mxPushSlot(mxArgv(0));
1123
+ mxGetID(mxID(_Symbol_iterator));
1124
+ if (mxIsUndefined(the->stack) || mxIsNull(the->stack)) {
1125
+ txIndex index = 0;
1126
+ mxPushSlot(mxArgv(0));
1127
+ mxGetID(mxID(_length));
1128
+ if (mxIsUndefined(the->stack))
1129
+ length = 0;
1130
+ else
1131
+ length = fxCheckArrayLength(the, the->stack);
1132
+ mxPop();
1133
+ fxCreateArray(the, 1, length);
1134
+ while (index < length) {
1135
+ mxPushSlot(mxArgv(0));
1136
+ mxGetIndex(index);
1137
+ fx_Array_from_aux(the, function, the->stack, index);
1138
+ mxPop();
1139
+ index++;
1140
+ }
1141
+ }
1142
+ else {
1143
+ fxCreateArray(the, 0, 0);
1144
+ mxTemporary(iterator);
1145
+ mxTemporary(next);
1146
+ fxGetIterator(the, mxArgv(0), iterator, next, 0);
1147
+ mxTemporary(value);
1148
+ length = 0;
1149
+ while (fxIteratorNext(the, iterator, next, value)) {
1150
+ mxTry(the) {
1151
+ fx_Array_from_aux(the, function, value, length);
1152
+ length++;
1153
+ }
1154
+ mxCatch(the) {
1155
+ fxIteratorReturn(the, iterator);
1156
+ fxJump(the);
1157
+ }
1158
+ }
1159
+ mxPop();
1160
+ }
1161
+ }
1162
+ else {
1163
+ fxCreateArray(the, 1, length);
1164
+ }
1165
+ mxPushUnsigned(length);
1166
+ mxPushSlot(mxResult);
1167
+ mxSetID(mxID(_length));
1168
+ mxPop();
1169
+ }
1170
+
1171
+ void fx_Array_from_aux(txMachine* the, txSlot* function, txSlot* value, txIndex index)
1172
+ {
1173
+ if (function) {
1174
+ /* THIS */
1175
+ if (mxArgc > 2)
1176
+ mxPushSlot(mxArgv(2));
1177
+ else
1178
+ mxPushUndefined();
1179
+ /* FUNCTION */
1180
+ mxPushSlot(function);
1181
+ mxCall();
1182
+ /* ARGUMENTS */
1183
+ mxPushSlot(value);
1184
+ mxPushInteger(index);
1185
+ mxRunCount(2);
1186
+ }
1187
+ else
1188
+ mxPushSlot(value);
1189
+ mxPushSlot(mxResult);
1190
+ mxDefineIndex(index, 0, XS_GET_ONLY);
1191
+ mxPop();
1192
+ }
1193
+
1194
+ void fx_Array_isArray(txMachine* the)
1195
+ {
1196
+ mxResult->kind = XS_BOOLEAN_KIND;
1197
+ mxResult->value.boolean = (mxArgc > 0) ? fxIsArray(the, fxGetInstance(the, mxArgv(0))) : 0;
1198
+ }
1199
+
1200
+ void fx_Array_of(txMachine* the)
1201
+ {
1202
+ txIndex count = (txIndex)mxArgc, index = 0;
1203
+ txSlot* array = fxCreateArray(the, 1, count);
1204
+ if (array) {
1205
+ txSlot* slot;
1206
+ fxSetIndexSize(the, array, count, XS_CHUNK);
1207
+ slot = array->value.array.address;
1208
+ while (index < count) {
1209
+ txSlot* argument = mxArgv(index);
1210
+ *((txIndex*)slot) = index;
1211
+ slot->ID = XS_NO_ID;
1212
+ slot->kind = argument->kind;
1213
+ slot->value = argument->value;
1214
+ slot++;
1215
+ mxMeterSome(4);
1216
+ index++;
1217
+ }
1218
+ mxMeterSome(4);
1219
+ }
1220
+ else {
1221
+ while (index < count) {
1222
+ mxPushSlot(mxArgv(index));
1223
+ mxPushSlot(mxResult);
1224
+ mxDefineIndex(index, 0, XS_GET_ONLY);
1225
+ mxPop();
1226
+ index++;
1227
+ }
1228
+ mxPushInteger(count);
1229
+ mxPushSlot(mxResult);
1230
+ mxSetID(mxID(_length));
1231
+ mxPop();
1232
+ }
1233
+ }
1234
+
1235
+ void fx_Array_prototype_at(txMachine* the)
1236
+ {
1237
+ txSlot* array = fxCheckArray(the, mxThis, XS_IMMUTABLE);
1238
+ txNumber length = (array) ? array->value.array.length : fxGetArrayLength(the, mxThis);
1239
+ txNumber index = (mxArgc > 0) ? c_trunc(fxToNumber(the, mxArgv(0))) : C_NAN;
1240
+ if (c_isnan(index) || (index == 0))
1241
+ index = 0;
1242
+ if (index < 0)
1243
+ index = length + index;
1244
+ if ((0 <= index) && (index < length)) {
1245
+ mxPushSlot(mxThis);
1246
+ mxPushNumber(index);
1247
+ mxGetAt();
1248
+ mxPullSlot(mxResult);
1249
+ }
1250
+ }
1251
+
1252
+ void fx_Array_prototype_concat(txMachine* the)
1253
+ {
1254
+ txSlot* resultArray = fxCreateArraySpecies(the, 0);
1255
+ txIndex resultLength = 0;
1256
+ txInteger c = mxArgc;
1257
+ txInteger i = -1;
1258
+ if (resultArray) {
1259
+ txSlot* list = fxNewInstance(the);
1260
+ txSlot* slot = list;
1261
+ txSlot* resultSlot;
1262
+ txIndex holeCount = 0;
1263
+ mxPushSlot(mxThis);
1264
+ for (;;) {
1265
+ txSlot* argument = the->stack;
1266
+ txBoolean flag = 0;
1267
+ if (mxIsReference(argument)) {
1268
+ mxPushSlot(argument);
1269
+ mxGetID(mxID(_Symbol_isConcatSpreadable));
1270
+ if (mxIsUndefined(the->stack))
1271
+ flag = fxIsArray(the, argument->value.reference);
1272
+ else
1273
+ flag = fxToBoolean(the, the->stack);
1274
+ mxPop();
1275
+ }
1276
+ if (flag) {
1277
+ txIndex length, index;
1278
+ mxPushSlot(argument);
1279
+ mxGetID(mxID(_length));
1280
+ length = (txIndex)fxToLength(the, the->stack);
1281
+ mxPop();
1282
+ if (resultLength + length < resultLength)
1283
+ mxTypeError("array overflow");
1284
+ index = 0;
1285
+ while (index < length) {
1286
+ mxPushSlot(argument);
1287
+ if (fxHasIndex(the, index)) {
1288
+ mxPushSlot(argument);
1289
+ mxGetIndex(index);
1290
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
1291
+ mxMeterSome(2);
1292
+ mxPop();
1293
+ }
1294
+ else {
1295
+ slot = slot->next = fxNewSlot(the);
1296
+ slot->kind = XS_UNINITIALIZED_KIND;
1297
+ holeCount++;
1298
+ }
1299
+ index++;
1300
+ resultLength++;
1301
+ }
1302
+ }
1303
+ else {
1304
+ slot = fxNextSlotProperty(the, slot, argument, XS_NO_ID, XS_NO_FLAG);
1305
+ mxMeterSome(4);
1306
+ resultLength++;
1307
+ if (resultLength == 0)
1308
+ mxTypeError("array overflow");
1309
+ }
1310
+ mxPop();
1311
+ i++;
1312
+ if (i == c)
1313
+ break;
1314
+ mxPushSlot(mxArgv(i));
1315
+ }
1316
+ fxSetIndexSize(the, resultArray, resultLength - holeCount, XS_CHUNK);
1317
+ resultArray->value.array.length = resultLength;
1318
+ resultSlot = resultArray->value.array.address;
1319
+ slot = list->next;
1320
+ resultLength = 0;
1321
+ while (slot) {
1322
+ if (slot->kind != XS_UNINITIALIZED_KIND) {
1323
+ *((txIndex*)resultSlot) = resultLength;
1324
+ resultSlot->ID = XS_NO_ID;
1325
+ resultSlot->kind = slot->kind;
1326
+ resultSlot->value = slot->value;
1327
+ resultSlot++;
1328
+ }
1329
+ slot = slot->next;
1330
+ resultLength++;
1331
+ }
1332
+ mxMeterSome(3);
1333
+ mxPop();
1334
+ }
1335
+ else {
1336
+ mxPushSlot(mxThis);
1337
+ for (;;) {
1338
+ txSlot* argument = the->stack;
1339
+ txBoolean flag = 0;
1340
+ if (mxIsReference(argument)) {
1341
+ mxPushSlot(argument);
1342
+ mxGetID(mxID(_Symbol_isConcatSpreadable));
1343
+ if (mxIsUndefined(the->stack))
1344
+ flag = fxIsArray(the, argument->value.reference);
1345
+ else
1346
+ flag = fxToBoolean(the, the->stack);
1347
+ mxPop();
1348
+ }
1349
+ if (flag) {
1350
+ txIndex length, index;
1351
+ mxPushSlot(argument);
1352
+ mxGetID(mxID(_length));
1353
+ length = (txIndex)fxToLength(the, the->stack);
1354
+ mxPop();
1355
+ index = 0;
1356
+ while (index < length) {
1357
+ mxPushSlot(argument);
1358
+ if (fxHasIndex(the, index)) {
1359
+ mxPushSlot(argument);
1360
+ mxGetIndex(index);
1361
+ mxPushSlot(mxResult);
1362
+ mxDefineIndex(resultLength, 0, XS_GET_ONLY);
1363
+ mxPop();
1364
+ }
1365
+ index++;
1366
+ resultLength++;
1367
+ }
1368
+ }
1369
+ else {
1370
+ mxPushSlot(argument);
1371
+ mxPushSlot(mxResult);
1372
+ mxDefineIndex(resultLength, 0, XS_GET_ONLY);
1373
+ mxPop();
1374
+ resultLength++;
1375
+ }
1376
+ mxPop();
1377
+ i++;
1378
+ if (i == c)
1379
+ break;
1380
+ mxPushSlot(mxArgv(i));
1381
+ }
1382
+ mxPushInteger(resultLength);
1383
+ mxPushSlot(mxResult);
1384
+ mxSetID(mxID(_length));
1385
+ mxPop();
1386
+ }
1387
+ }
1388
+
1389
+ void fx_Array_prototype_copyWithin(txMachine* the)
1390
+ {
1391
+ txNumber length = fxGetArrayLength(the, mxThis);
1392
+ txNumber to = fxArgToIndex(the, 0, 0, length);
1393
+ txNumber from = fxArgToIndex(the, 1, 0, length);
1394
+ txNumber final = fxArgToIndex(the, 2, length, length);
1395
+ txNumber count = (final > from) ? final - from : 0;
1396
+ txSlot* array = fxCheckArray(the, mxThis, XS_MUTABLE);
1397
+ if (count > length - to)
1398
+ count = length - to;
1399
+ if (array) {
1400
+ if (count > 0) {
1401
+ if (from < to)
1402
+ array = fxCheckArrayItems(the, array, (txIndex)from, (txIndex)(to + count));
1403
+ else
1404
+ array = fxCheckArrayItems(the, array, (txIndex)to, (txIndex)(from + count));
1405
+ }
1406
+ }
1407
+ if (array) {
1408
+ if (count > 0) {
1409
+ c_memmove(array->value.array.address + (txIndex)to, array->value.array.address + (txIndex)from, (txIndex)count * sizeof(txSlot));
1410
+ fxIndexArray(the, array);
1411
+ mxMeterSome((txU4)count * 10);
1412
+ }
1413
+ }
1414
+ else {
1415
+ txNumber direction;
1416
+ if ((from < to) && (to < from + count)) {
1417
+ direction = -1;
1418
+ from += count - 1;
1419
+ to += count - 1;
1420
+ }
1421
+ else
1422
+ direction = 1;
1423
+ while (count > 0) {
1424
+ fxMoveThisItem(the, from, to);
1425
+ from += direction;
1426
+ to += direction;
1427
+ count--;
1428
+ }
1429
+ }
1430
+ mxResult->kind = mxThis->kind;
1431
+ mxResult->value = mxThis->value;
1432
+ }
1433
+
1434
+ void fx_Array_prototype_entries(txMachine* the)
1435
+ {
1436
+ txSlot* property;
1437
+ fxToInstance(the, mxThis);
1438
+ mxPush(mxArrayIteratorPrototype);
1439
+ property = fxLastProperty(the, fxNewIteratorInstance(the, mxThis, mxID(_Array)));
1440
+ property = fxNextIntegerProperty(the, property, 2, XS_NO_ID, XS_INTERNAL_FLAG);
1441
+ mxPullSlot(mxResult);
1442
+ }
1443
+
1444
+ void fx_Array_prototype_every(txMachine* the)
1445
+ {
1446
+ txIndex length = fxGetArrayLimit(the, mxThis);
1447
+ txIndex index = 0;
1448
+ txSlot* function = fxArgToCallback(the, 0);
1449
+ mxResult->kind = XS_BOOLEAN_KIND;
1450
+ mxResult->value.boolean = 1;
1451
+ while (index < length) {
1452
+ if (fxCallThisItem(the, function, index, C_NULL)) {
1453
+ mxResult->value.boolean = fxToBoolean(the, the->stack);
1454
+ mxPop();
1455
+ if (!mxResult->value.boolean)
1456
+ break;
1457
+ }
1458
+ index++;
1459
+ }
1460
+ }
1461
+
1462
+ void fx_Array_prototype_fill(txMachine* the)
1463
+ {
1464
+ txSlot* instance = fxToInstance(the, mxThis);
1465
+ txSlot* array = instance->next;
1466
+ txSlot* value;
1467
+ if (mxArgc > 0)
1468
+ mxPushSlot(mxArgv(0));
1469
+ else
1470
+ mxPushUndefined();
1471
+ value = the->stack;
1472
+ if (array && (array->kind == XS_ARRAY_KIND) && (array->ID == XS_ARRAY_BEHAVIOR)) {
1473
+ txIndex length = array->value.array.length;
1474
+ txIndex start = (txIndex)fxArgToIndex(the, 1, 0, length);
1475
+ txIndex end = (txIndex)fxArgToIndex(the, 2, length, length);
1476
+ txSlot* address;
1477
+ txIndex size;
1478
+ if ((start == 0) && (end == length)) {
1479
+ fxSetIndexSize(the, array, length, XS_CHUNK);
1480
+ fxIndexArray(the, array);
1481
+ }
1482
+ address = array->value.array.address;
1483
+ size = (address) ? (((txChunk*)(((txByte*)address) - sizeof(txChunk)))->size) / sizeof(txSlot) : 0;
1484
+ if (length == size) {
1485
+ while (start < end) {
1486
+ txSlot* slot = array->value.array.address + start;
1487
+ if (slot->flag) {
1488
+ mxPushSlot(value);
1489
+ mxPushSlot(mxThis);
1490
+ mxSetIndex(start);
1491
+ mxPop();
1492
+ mxMeterSome(1);
1493
+ }
1494
+ else {
1495
+ slot->ID = XS_NO_ID;
1496
+ slot->kind = value->kind;
1497
+ slot->value = value->value;
1498
+ mxMeterSome(5);
1499
+ }
1500
+ start++;
1501
+ }
1502
+
1503
+ }
1504
+ else {
1505
+ while (start < end) {
1506
+ mxPushSlot(value);
1507
+ mxPushSlot(mxThis);
1508
+ mxSetIndex(start);
1509
+ mxPop();
1510
+ mxMeterSome(1);
1511
+ start++;
1512
+ }
1513
+ }
1514
+ }
1515
+ else {
1516
+ txNumber length = fxGetArrayLength(the, mxThis);
1517
+ txNumber start = fxArgToIndex(the, 1, 0, length);
1518
+ txNumber end = fxArgToIndex(the, 2, length, length);
1519
+ txSlot* value = the->stack;
1520
+ while (start < end) {
1521
+ mxPushSlot(value);
1522
+ mxPushSlot(mxThis);
1523
+ mxPushNumber(start);
1524
+ mxSetAt();
1525
+ mxPop();
1526
+ start++;
1527
+ }
1528
+ }
1529
+ mxPop();
1530
+ mxResult->kind = mxThis->kind;
1531
+ mxResult->value = mxThis->value;
1532
+ }
1533
+
1534
+ void fx_Array_prototype_filter(txMachine* the)
1535
+ {
1536
+ txIndex length = fxGetArrayLimit(the, mxThis);
1537
+ txIndex index = 0;
1538
+ txSlot* function = fxArgToCallback(the, 0);
1539
+ txSlot* resultArray = fxCreateArraySpecies(the, 0);
1540
+ txIndex resultLength = 0;
1541
+ txSlot* item;
1542
+ mxPushUndefined();
1543
+ item = the->stack;
1544
+ if (resultArray) {
1545
+ txSlot* list = fxNewInstance(the);
1546
+ txSlot* slot = list;
1547
+ txSlot* resultSlot;
1548
+ while (index < length) {
1549
+ if (fxCallThisItem(the, function, index, item)) {
1550
+ if (fxToBoolean(the, the->stack)) {
1551
+ slot = fxNextSlotProperty(the, slot, item, XS_NO_ID, XS_NO_FLAG);
1552
+ mxMeterSome(4);
1553
+ resultLength++;
1554
+ }
1555
+ mxPop();
1556
+ }
1557
+ index++;
1558
+ }
1559
+ fxSetIndexSize(the, resultArray, resultLength, XS_CHUNK);
1560
+ resultSlot = resultArray->value.array.address;
1561
+ slot = list->next;
1562
+ index = 0;
1563
+ while (slot) {
1564
+ *((txIndex*)resultSlot) = index;
1565
+ resultSlot->ID = XS_NO_ID;
1566
+ resultSlot->kind = slot->kind;
1567
+ resultSlot->value = slot->value;
1568
+ resultSlot++;
1569
+ slot = slot->next;
1570
+ index++;
1571
+ }
1572
+ mxPop();
1573
+ mxMeterSome(-1);
1574
+ }
1575
+ else {
1576
+ while (index < length) {
1577
+ if (fxCallThisItem(the, function, index, item)) {
1578
+ if (fxToBoolean(the, the->stack)) {
1579
+ mxPushSlot(item);
1580
+ mxPushSlot(mxResult);
1581
+ mxDefineIndex(resultLength, 0, XS_GET_ONLY);
1582
+ mxPop();
1583
+ resultLength++;
1584
+ }
1585
+ mxPop();
1586
+ }
1587
+ index++;
1588
+ }
1589
+ }
1590
+ mxPop();
1591
+ }
1592
+
1593
+ void fx_Array_prototype_find(txMachine* the)
1594
+ {
1595
+ txIndex length = fxGetArrayLimit(the, mxThis);
1596
+ txIndex index = 0;
1597
+ txSlot* function = fxArgToCallback(the, 0);
1598
+ txSlot* item;
1599
+ mxPushUndefined();
1600
+ item = the->stack;
1601
+ while (index < length) {
1602
+ fxFindThisItem(the, function, index, item);
1603
+ if (fxToBoolean(the, the->stack++)) {
1604
+ mxResult->kind = item->kind;
1605
+ mxResult->value = item->value;
1606
+ break;
1607
+ }
1608
+ index++;
1609
+ }
1610
+ mxPop();
1611
+ }
1612
+
1613
+ void fx_Array_prototype_findIndex(txMachine* the)
1614
+ {
1615
+ txIndex length = fxGetArrayLimit(the, mxThis);
1616
+ txIndex index = 0;
1617
+ txSlot* function = fxArgToCallback(the, 0);
1618
+ fxInteger(the, mxResult, -1);
1619
+ while (index < length) {
1620
+ fxFindThisItem(the, function, index, C_NULL);
1621
+ if (fxToBoolean(the, the->stack++)) {
1622
+ fxUnsigned(the, mxResult, index);
1623
+ break;
1624
+ }
1625
+ index++;
1626
+ }
1627
+ }
1628
+
1629
+ void fx_Array_prototype_findLast(txMachine* the)
1630
+ {
1631
+ txIndex index = fxGetArrayLimit(the, mxThis);
1632
+ txSlot* function = fxArgToCallback(the, 0);
1633
+ txSlot* item;
1634
+ mxPushUndefined();
1635
+ item = the->stack;
1636
+ while (index > 0) {
1637
+ index--;
1638
+ fxFindThisItem(the, function, index, item);
1639
+ if (fxToBoolean(the, the->stack++)) {
1640
+ mxResult->kind = item->kind;
1641
+ mxResult->value = item->value;
1642
+ break;
1643
+ }
1644
+ }
1645
+ mxPop();
1646
+ }
1647
+
1648
+ void fx_Array_prototype_findLastIndex(txMachine* the)
1649
+ {
1650
+ txIndex index = fxGetArrayLimit(the, mxThis);
1651
+ txSlot* function = fxArgToCallback(the, 0);
1652
+ fxInteger(the, mxResult, -1);
1653
+ while (index > 0) {
1654
+ index--;
1655
+ fxFindThisItem(the, function, index, C_NULL);
1656
+ if (fxToBoolean(the, the->stack++)) {
1657
+ fxUnsigned(the, mxResult, index);
1658
+ break;
1659
+ }
1660
+ }
1661
+ }
1662
+
1663
+ void fx_Array_prototype_flat(txMachine* the)
1664
+ {
1665
+ txIndex length, depth = 1;
1666
+ mxPushSlot(mxThis);
1667
+ mxGetID(mxID(_length));
1668
+ length = (txIndex)fxToLength(the, the->stack);
1669
+ mxPop();
1670
+ if ((mxArgc > 0) && !mxIsUndefined(mxArgv(0)))
1671
+ depth = (txIndex)fxToLength(the, mxArgv(0));
1672
+ fxCreateArraySpecies(the, 0);
1673
+ fx_Array_prototype_flatAux(the, mxThis, length, 0, depth, C_NULL);
1674
+ }
1675
+
1676
+ txIndex fx_Array_prototype_flatAux(txMachine* the, txSlot* source, txIndex length, txIndex start, txIndex depth, txSlot* function)
1677
+ {
1678
+ txSlot* item;
1679
+ txIndex index = 0;
1680
+ while (index < length) {
1681
+ mxPushSlot(source);
1682
+ if (fxHasIndex(the, index)) {
1683
+ if (function) {
1684
+ /* THIS */
1685
+ if (mxArgc > 1)
1686
+ mxPushSlot(mxArgv(1));
1687
+ else
1688
+ mxPushUndefined();
1689
+ /* FUNCTION */
1690
+ mxPushSlot(function);
1691
+ mxCall();
1692
+ /* ARGUMENTS */
1693
+ mxPushSlot(source);
1694
+ mxGetIndex(index);
1695
+ mxPushUnsigned(index);
1696
+ mxPushSlot(mxThis);
1697
+ mxRunCount(3);
1698
+ }
1699
+ else {
1700
+ mxPushSlot(source);
1701
+ mxGetIndex(index);
1702
+ }
1703
+ item = the->stack;
1704
+ if ((depth > 0) && mxIsReference(item) && fxIsArray(the, fxToInstance(the, item))) {
1705
+ txIndex itemLength;
1706
+ mxPushSlot(item);
1707
+ mxGetID(mxID(_length));
1708
+ itemLength = (txIndex)fxToLength(the, the->stack);
1709
+ mxPop();
1710
+ start = fx_Array_prototype_flatAux(the, item, itemLength, start, depth - 1, C_NULL);
1711
+ }
1712
+ else {
1713
+ mxPushSlot(mxResult);
1714
+ mxDefineIndex(start, 0, XS_GET_ONLY);
1715
+ start++;
1716
+ }
1717
+ }
1718
+ index++;
1719
+ }
1720
+ return start;
1721
+ }
1722
+
1723
+ void fx_Array_prototype_flatMap(txMachine* the)
1724
+ {
1725
+ txIndex length = (txIndex)fxGetArrayLength(the, mxThis);
1726
+ txSlot* function = fxArgToCallback(the, 0);
1727
+ fxCreateArraySpecies(the, 0);
1728
+ fx_Array_prototype_flatAux(the, mxThis, length, 0, 1, function);
1729
+ }
1730
+
1731
+ void fx_Array_prototype_forEach(txMachine* the)
1732
+ {
1733
+ txIndex length = fxGetArrayLimit(the, mxThis);
1734
+ txIndex index = 0;
1735
+ txSlot* function = fxArgToCallback(the, 0);
1736
+ while (index < length) {
1737
+ if (fxCallThisItem(the, function, index, C_NULL))
1738
+ mxPop();
1739
+ index++;
1740
+ }
1741
+ }
1742
+
1743
+ void fx_Array_prototype_includes(txMachine* the)
1744
+ {
1745
+ txSlot* array = fxCheckArray(the, mxThis, XS_IMMUTABLE);
1746
+ txSlot* argument;
1747
+ if (mxArgc > 0)
1748
+ mxPushSlot(mxArgv(0));
1749
+ else
1750
+ mxPushUndefined();
1751
+ argument = the->stack;
1752
+ fxBoolean(the, mxResult, 0);
1753
+ if (array) {
1754
+ txIndex length = array->value.array.length;
1755
+ if (length) {
1756
+ txIndex index = (txIndex)fxArgToIndex(the, 1, 0, length);
1757
+ while (index < length) {
1758
+ mxPushSlot(mxThis);
1759
+ mxGetIndex(index);
1760
+ if (fxIsSameValue(the, the->stack++, argument, 1)) {
1761
+ mxResult->value.boolean = 1;
1762
+ break;
1763
+ }
1764
+ index++;
1765
+ }
1766
+ }
1767
+ }
1768
+ else {
1769
+ txNumber length = fxGetArrayLength(the, mxThis);
1770
+ if (length) {
1771
+ txNumber index = fxArgToIndex(the, 1, 0, length);
1772
+ while (index < length) {
1773
+ mxPushSlot(mxThis);
1774
+ mxPushNumber(index);
1775
+ mxGetAt();
1776
+ if (fxIsSameValue(the, the->stack++, argument, 1)) {
1777
+ mxResult->value.boolean = 1;
1778
+ break;
1779
+ }
1780
+ index++;
1781
+ }
1782
+ }
1783
+ }
1784
+ mxPop();
1785
+ }
1786
+
1787
+ void fx_Array_prototype_indexOf(txMachine* the)
1788
+ {
1789
+ txSlot* array = fxCheckArray(the, mxThis, XS_IMMUTABLE);
1790
+ txSlot* argument;
1791
+ if (mxArgc > 0)
1792
+ mxPushSlot(mxArgv(0));
1793
+ else
1794
+ mxPushUndefined();
1795
+ argument = the->stack;
1796
+ fxInteger(the, mxResult, -1);
1797
+ if (array) {
1798
+ txIndex length = array->value.array.length;
1799
+ if (length) {
1800
+ txIndex index = (txIndex)fxArgToIndex(the, 1, 0, length);
1801
+ while (index < length) {
1802
+ mxPushSlot(mxThis);
1803
+ if (fxHasIndex(the, index)) {
1804
+ mxPushSlot(mxThis);
1805
+ mxGetIndex(index);
1806
+ if (fxIsSameSlot(the, the->stack++, argument)) {
1807
+ fxUnsigned(the, mxResult, index);
1808
+ break;
1809
+ }
1810
+ }
1811
+ index++;
1812
+ }
1813
+ }
1814
+ }
1815
+ else {
1816
+ txNumber length = fxGetArrayLength(the, mxThis);
1817
+ if (length) {
1818
+ txNumber index = fxArgToIndex(the, 1, 0, length);
1819
+ while (index < length) {
1820
+ mxPushSlot(mxThis);
1821
+ mxPushNumber(index);
1822
+ if (mxHasAt()) {
1823
+ mxPushSlot(mxThis);
1824
+ mxPushNumber(index);
1825
+ mxGetAt();
1826
+ if (fxIsSameSlot(the, the->stack++, argument)) {
1827
+ fxNumber(the, mxResult, index);
1828
+ break;
1829
+ }
1830
+ }
1831
+ index++;
1832
+ }
1833
+ }
1834
+ }
1835
+ mxPop();
1836
+ }
1837
+
1838
+ void fx_Array_prototype_join(txMachine* the)
1839
+ {
1840
+ txIndex length = fxGetArrayLimit(the, mxThis);
1841
+ txIndex index = 0;
1842
+ txString string;
1843
+ txSlot* list = fxNewInstance(the);
1844
+ txSlot* slot = list;
1845
+ txBoolean comma = 0;
1846
+ txInteger size = 0;
1847
+ if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) {
1848
+ mxPushSlot(mxArgv(0));
1849
+ string = fxToString(the, the->stack);
1850
+ the->stack->kind += XS_KEY_KIND - XS_STRING_KIND;
1851
+ the->stack->value.key.sum = mxStringLength(string);
1852
+ }
1853
+ else {
1854
+ mxPushStringX(",");
1855
+ the->stack->kind += XS_KEY_KIND - XS_STRING_KIND;
1856
+ the->stack->value.key.sum = 1;
1857
+ }
1858
+ while (index < length) {
1859
+ if (comma) {
1860
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
1861
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
1862
+ }
1863
+ else
1864
+ comma = 1;
1865
+ mxPushSlot(mxThis);
1866
+ mxGetIndex(index);
1867
+ if ((the->stack->kind != XS_UNDEFINED_KIND) && (the->stack->kind != XS_NULL_KIND)) {
1868
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
1869
+ string = fxToString(the, slot);
1870
+ slot->kind += XS_KEY_KIND - XS_STRING_KIND;
1871
+ slot->value.key.sum = mxStringLength(string);
1872
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
1873
+ }
1874
+ mxPop();
1875
+ index++;
1876
+ }
1877
+ mxPop();
1878
+ string = mxResult->value.string = fxNewChunk(the, fxAddChunkSizes(the, size, 1));
1879
+ slot = list->next;
1880
+ while (slot) {
1881
+ c_memcpy(string, slot->value.key.string, slot->value.key.sum);
1882
+ string += slot->value.key.sum;
1883
+ slot = slot->next;
1884
+ }
1885
+ *string = 0;
1886
+ mxResult->kind = XS_STRING_KIND;
1887
+ mxPop();
1888
+ }
1889
+
1890
+ void fx_Array_prototype_keys(txMachine* the)
1891
+ {
1892
+ txSlot* property;
1893
+ fxToInstance(the, mxThis);
1894
+ mxPush(mxArrayIteratorPrototype);
1895
+ property = fxLastProperty(the, fxNewIteratorInstance(the, mxThis, mxID(_Array)));
1896
+ property = fxNextIntegerProperty(the, property, 1, XS_NO_ID, XS_INTERNAL_FLAG);
1897
+ mxPullSlot(mxResult);
1898
+ }
1899
+
1900
+ void fx_Array_prototype_lastIndexOf(txMachine* the)
1901
+ {
1902
+ txSlot* array = fxCheckArray(the, mxThis, XS_IMMUTABLE);
1903
+ txSlot* argument;
1904
+ if (mxArgc > 0)
1905
+ mxPushSlot(mxArgv(0));
1906
+ else
1907
+ mxPushUndefined();
1908
+ argument = the->stack;
1909
+ fxInteger(the, mxResult, -1);
1910
+ if (array) {
1911
+ txIndex length = array->value.array.length;
1912
+ if (length) {
1913
+ txIndex index = (txIndex)fxArgToLastIndex(the, 1, length, length);
1914
+ while (index > 0) {
1915
+ index--;
1916
+ mxPushSlot(mxThis);
1917
+ if (fxHasIndex(the, index)) {
1918
+ mxPushSlot(mxThis);
1919
+ mxGetIndex(index);
1920
+ if (fxIsSameSlot(the, the->stack++, argument)) {
1921
+ fxUnsigned(the, mxResult, index);
1922
+ break;
1923
+ }
1924
+ }
1925
+ }
1926
+ }
1927
+ }
1928
+ else {
1929
+ txNumber length = fxGetArrayLength(the, mxThis);
1930
+ if (length) {
1931
+ txNumber index = fxArgToLastIndex(the, 1, length, length);
1932
+ while (index > 0) {
1933
+ index--;
1934
+ mxPushSlot(mxThis);
1935
+ mxPushNumber(index);
1936
+ if (mxHasAt()) {
1937
+ mxPushSlot(mxThis);
1938
+ mxPushNumber(index);
1939
+ mxGetAt();
1940
+ if (fxIsSameSlot(the, the->stack++, argument)) {
1941
+ fxNumber(the, mxResult, index);
1942
+ break;
1943
+ }
1944
+ }
1945
+ }
1946
+ }
1947
+ }
1948
+ mxPop();
1949
+ }
1950
+
1951
+ void fx_Array_prototype_map(txMachine* the)
1952
+ {
1953
+ txNumber LENGTH = fxGetArrayLength(the, mxThis);
1954
+ txSlot* function = fxArgToCallback(the, 0);
1955
+ txSlot* resultArray = fxCreateArraySpecies(the, LENGTH);
1956
+ txIndex length = (txIndex)LENGTH;
1957
+ txIndex index = 0;
1958
+ if (resultArray) {
1959
+ txIndex resultLength = 0;
1960
+ fxSetIndexSize(the, resultArray, length, XS_CHUNK);
1961
+ while (index < length) {
1962
+ if (fxCallThisItem(the, function, index, C_NULL)) {
1963
+ txSlot* slot = resultArray->value.array.address + resultLength;
1964
+ *((txIndex*)slot) = index;
1965
+ slot->ID = XS_NO_ID;
1966
+ slot->kind = the->stack->kind;
1967
+ slot->value = the->stack->value;
1968
+ resultLength++;
1969
+ mxMeterSome(2);
1970
+ mxPop();
1971
+ }
1972
+ index++;
1973
+ }
1974
+ if (resultLength < length) {
1975
+ fxSetIndexSize(the, resultArray, resultLength, XS_CHUNK);
1976
+ resultArray->value.array.length = length;
1977
+ }
1978
+ }
1979
+ else {
1980
+ while (index < length) {
1981
+ if (fxCallThisItem(the, function, index, C_NULL)) {
1982
+ mxPushSlot(mxResult);
1983
+ mxDefineIndex(index, 0, XS_GET_ONLY);
1984
+ mxPop();
1985
+ }
1986
+ index++;
1987
+ }
1988
+ }
1989
+ }
1990
+
1991
+ void fx_Array_prototype_pop(txMachine* the)
1992
+ {
1993
+ txSlot* array = fxCheckArray(the, mxThis, XS_MUTABLE);
1994
+ if (array) {
1995
+ txIndex length = array->value.array.length;
1996
+ if (length > 0)
1997
+ array = fxCheckArrayItems(the, array, length - 1, length);
1998
+ }
1999
+ if (array) {
2000
+ txIndex length = array->value.array.length;
2001
+ txSlot* address;
2002
+ mxMeterSome(2);
2003
+ if (length > 0) {
2004
+ length--;
2005
+ address = array->value.array.address + length;
2006
+ mxResult->kind = address->kind;
2007
+ mxResult->value = address->value;
2008
+ fxSetIndexSize(the, array, length, XS_CHUNK);
2009
+ mxMeterSome(8);
2010
+ }
2011
+ mxMeterSome(4);
2012
+ }
2013
+ else {
2014
+ txNumber length = fxGetArrayLength(the, mxThis);
2015
+ if (length > 0) {
2016
+ length--;
2017
+ mxPushSlot(mxThis);
2018
+ mxPushNumber(length);
2019
+ mxGetAt();
2020
+ mxPullSlot(mxResult);
2021
+ mxPushSlot(mxThis);
2022
+ mxPushNumber(length);
2023
+ mxDeleteAt();
2024
+ mxPop();
2025
+ }
2026
+ mxPushNumber(length);
2027
+ mxPushSlot(mxThis);
2028
+ mxSetID(mxID(_length));
2029
+ mxPop();
2030
+ }
2031
+ }
2032
+
2033
+ void fx_Array_prototype_push(txMachine* the)
2034
+ {
2035
+ txIndex c = mxArgc, i = 0;
2036
+ txSlot* array = fxCheckArray(the, mxThis, XS_MUTABLE);
2037
+ if (array) {
2038
+ txIndex length = array->value.array.length;
2039
+ txSlot* address;
2040
+ mxMeterSome(2);
2041
+ if (length + c < length)
2042
+ mxRangeError("array overflow");
2043
+ fxSetIndexSize(the, array, length + c, XS_GROWABLE_CHUNK);
2044
+ address = array->value.array.address + length;
2045
+ while (i < c) {
2046
+ txSlot* argument = mxArgv(i);
2047
+ *((txIndex*)address) = length + i;
2048
+ address->ID = XS_NO_ID;
2049
+ address->kind = argument->kind;
2050
+ address->value = argument->value;
2051
+ address++;
2052
+ mxMeterSome(5);
2053
+ i++;
2054
+ }
2055
+ mxPushUnsigned(length + c);
2056
+ mxMeterSome(2);
2057
+ }
2058
+ else {
2059
+ txNumber length = fxGetArrayLength(the, mxThis);
2060
+ if (length + c > C_MAX_SAFE_INTEGER)
2061
+ mxTypeError("unsafe integer");
2062
+ while (i < c) {
2063
+ mxPushSlot(mxArgv(i));
2064
+ mxPushSlot(mxThis);
2065
+ mxPushNumber(length + i);
2066
+ mxSetAt();
2067
+ mxPop();
2068
+ i++;
2069
+ }
2070
+ mxPushNumber(length + c);
2071
+ mxPushSlot(mxThis);
2072
+ mxSetID(mxID(_length));
2073
+ }
2074
+ mxPullSlot(mxResult);
2075
+ }
2076
+
2077
+ void fx_Array_prototype_reduce(txMachine* the)
2078
+ {
2079
+ txIndex length = fxGetArrayLimit(the, mxThis);
2080
+ txIndex index = 0;
2081
+ txSlot* function = fxArgToCallback(the, 0);
2082
+ if (mxArgc > 1)
2083
+ *mxResult = *mxArgv(1);
2084
+ else {
2085
+ txBoolean flag = 0;
2086
+ while (!flag && (index < length)) {
2087
+ mxPushSlot(mxThis);
2088
+ if (fxHasIndex(the, index)) {
2089
+ mxPushSlot(mxThis);
2090
+ mxGetIndex(index);
2091
+ mxPullSlot(mxResult);
2092
+ flag = 1;
2093
+ }
2094
+ index++;
2095
+ }
2096
+ if (!flag)
2097
+ mxTypeError("no initial value");
2098
+ }
2099
+ while (index < length) {
2100
+ fxReduceThisItem(the, function, index);
2101
+ index++;
2102
+ }
2103
+ }
2104
+
2105
+ void fx_Array_prototype_reduceRight(txMachine* the)
2106
+ {
2107
+ txIndex length = fxGetArrayLimit(the, mxThis);
2108
+ txIndex index = length;
2109
+ txSlot* function = fxArgToCallback(the, 0);
2110
+ if (mxArgc > 1)
2111
+ *mxResult = *mxArgv(1);
2112
+ else {
2113
+ txBoolean flag = 0;
2114
+ while (!flag && (index > 0)) {
2115
+ index--;
2116
+ mxPushSlot(mxThis);
2117
+ if (fxHasIndex(the, index)) {
2118
+ mxPushSlot(mxThis);
2119
+ mxGetIndex(index);
2120
+ mxPullSlot(mxResult);
2121
+ flag = 1;
2122
+ }
2123
+ }
2124
+ if (!flag)
2125
+ mxTypeError("no initial value");
2126
+ }
2127
+ while (index > 0) {
2128
+ index--;
2129
+ fxReduceThisItem(the, function, index);
2130
+ }
2131
+ }
2132
+
2133
+ void fx_Array_prototype_reverse(txMachine* the)
2134
+ {
2135
+ txSlot* lowerSlot;
2136
+ txSlot* upperSlot;
2137
+ txNumber length = fxGetArrayLength(the, mxThis);
2138
+ txNumber middle = c_trunc(length / 2);
2139
+ txNumber lower = 0;
2140
+ while (lower != middle) {
2141
+ txNumber upper = length - lower - 1;
2142
+ mxPushSlot(mxThis);
2143
+ mxPushNumber(lower);
2144
+ if (mxHasAt()) {
2145
+ mxPushSlot(mxThis);
2146
+ mxPushNumber(lower);
2147
+ mxGetAt();
2148
+ lowerSlot = the->stack;
2149
+ }
2150
+ else
2151
+ lowerSlot = C_NULL;
2152
+ mxPushSlot(mxThis);
2153
+ mxPushNumber(upper);
2154
+ if (mxHasAt()) {
2155
+ mxPushSlot(mxThis);
2156
+ mxPushNumber(upper);
2157
+ mxGetAt();
2158
+ upperSlot = the->stack;
2159
+ }
2160
+ else
2161
+ upperSlot = C_NULL;
2162
+ if (upperSlot && lowerSlot) {
2163
+ mxPushSlot(upperSlot);
2164
+ mxPushSlot(mxThis);
2165
+ mxPushNumber(lower);
2166
+ mxSetAt();
2167
+ mxPop();
2168
+ mxPushSlot(lowerSlot);
2169
+ mxPushSlot(mxThis);
2170
+ mxPushNumber(upper);
2171
+ mxSetAt();
2172
+ mxPop();
2173
+ mxPop();
2174
+ mxPop();
2175
+ }
2176
+ else if (upperSlot) {
2177
+ mxPushSlot(upperSlot);
2178
+ mxPushSlot(mxThis);
2179
+ mxPushNumber(lower);
2180
+ mxSetAt();
2181
+ mxPop();
2182
+ mxPushSlot(mxThis);
2183
+ mxPushNumber(upper);
2184
+ mxDeleteAt();
2185
+ mxPop();
2186
+ mxPop();
2187
+ }
2188
+ else if (lowerSlot) {
2189
+ mxPushSlot(mxThis);
2190
+ mxPushNumber(lower);
2191
+ mxDeleteAt();
2192
+ mxPop();
2193
+ mxPushSlot(lowerSlot);
2194
+ mxPushSlot(mxThis);
2195
+ mxPushNumber(upper);
2196
+ mxSetAt();
2197
+ mxPop();
2198
+ mxPop();
2199
+ }
2200
+ lower++;
2201
+ }
2202
+ *mxResult = *mxThis;
2203
+ }
2204
+
2205
+ void fx_Array_prototype_shift(txMachine* the)
2206
+ {
2207
+ txSlot* array = fxCheckArray(the, mxThis, XS_MUTABLE);
2208
+ if (array)
2209
+ array = fxCheckArrayItems(the, array, 0, array->value.array.length);
2210
+ if (array) {
2211
+ txIndex length = array->value.array.length;
2212
+ txSlot* address;
2213
+ mxMeterSome(2);
2214
+ if (length > 0) {
2215
+ mxMeterSome(3);
2216
+ address = array->value.array.address;
2217
+ length--;
2218
+ mxResult->kind = address->kind;
2219
+ mxResult->value = address->value;
2220
+ c_memmove(address, address + 1, length * sizeof(txSlot));
2221
+ fxSetIndexSize(the, array, length, XS_CHUNK);
2222
+ fxIndexArray(the, array);
2223
+ mxMeterSome(length * 10);
2224
+ mxMeterSome(3);
2225
+ }
2226
+ mxMeterSome(4);
2227
+ }
2228
+ else {
2229
+ txNumber length = fxGetArrayLength(the, mxThis);
2230
+ if (length > 0) {
2231
+ txNumber index = 1;
2232
+ mxPushSlot(mxThis);
2233
+ mxGetIndex(0);
2234
+ mxPullSlot(mxResult);
2235
+ while (index < length) {
2236
+ mxPushSlot(mxThis);
2237
+ mxPushNumber(index);
2238
+ if (mxHasAt()) {
2239
+ mxPushSlot(mxThis);
2240
+ mxPushNumber(index);
2241
+ mxGetAt();
2242
+ mxPushSlot(mxThis);
2243
+ mxPushNumber(index - 1);
2244
+ mxSetAt();
2245
+ mxPop();
2246
+ }
2247
+ else {
2248
+ mxPushSlot(mxThis);
2249
+ mxPushNumber(index - 1);
2250
+ mxDeleteAt();
2251
+ mxPop();
2252
+ }
2253
+ index++;
2254
+ }
2255
+ length--;
2256
+ mxPushSlot(mxThis);
2257
+ mxDeleteIndex((txIndex)length);
2258
+ mxPop();
2259
+ }
2260
+ mxPushNumber(length);
2261
+ mxPushSlot(mxThis);
2262
+ mxSetID(mxID(_length));
2263
+ mxPop();
2264
+ }
2265
+ }
2266
+
2267
+ void fx_Array_prototype_slice(txMachine* the)
2268
+ {
2269
+ txNumber LENGTH = fxGetArrayLength(the, mxThis);
2270
+ txNumber START = fxArgToIndex(the, 0, 0, LENGTH);
2271
+ txNumber END = fxArgToIndex(the, 1, LENGTH, LENGTH);
2272
+ txNumber COUNT = (END > START) ? END - START : 0;
2273
+ txSlot* resultArray = fxCreateArraySpecies(the, COUNT);
2274
+ txSlot* array = C_NULL;
2275
+ if (resultArray)
2276
+ array = fxCheckArray(the, mxThis, XS_IMMUTABLE);
2277
+ if (array)
2278
+ array = fxCheckArrayItems(the, array, (txIndex)START, (txIndex)(START + COUNT));
2279
+ if (array) {
2280
+ txIndex start = (txIndex)START;
2281
+ txIndex count = (txIndex)COUNT;
2282
+ if (count) {
2283
+ fxSetIndexSize(the, resultArray, count, XS_CHUNK);
2284
+ c_memcpy(resultArray->value.array.address, array->value.array.address + start, count * sizeof(txSlot));
2285
+ fxIndexArray(the, resultArray);
2286
+ mxMeterSome(count * 10);
2287
+ }
2288
+ mxMeterSome(3);
2289
+ }
2290
+ else {
2291
+ txNumber INDEX = 0;
2292
+ while (START < END) {
2293
+ mxPushSlot(mxThis);
2294
+ mxPushNumber(START);
2295
+ if (mxHasAt()) {
2296
+ mxPushSlot(mxThis);
2297
+ mxPushNumber(START);
2298
+ mxGetAt();
2299
+ mxPushSlot(mxResult);
2300
+ mxPushNumber(INDEX);
2301
+ mxDefineAt(0, XS_GET_ONLY);
2302
+ mxPop();
2303
+ }
2304
+ INDEX++;
2305
+ START++;
2306
+ }
2307
+ mxPushNumber(COUNT);
2308
+ mxPushSlot(mxResult);
2309
+ mxSetID(mxID(_length));
2310
+ }
2311
+ }
2312
+
2313
+ void fx_Array_prototype_some(txMachine* the)
2314
+ {
2315
+ txIndex length = fxGetArrayLimit(the, mxThis);
2316
+ txIndex index = 0;
2317
+ txSlot* function = fxArgToCallback(the, 0);
2318
+ mxResult->kind = XS_BOOLEAN_KIND;
2319
+ mxResult->value.boolean = 0;
2320
+ while (index < length) {
2321
+ if (fxCallThisItem(the, function, index, C_NULL)) {
2322
+ mxResult->value.boolean = fxToBoolean(the, the->stack);
2323
+ mxPop();
2324
+ if (mxResult->value.boolean)
2325
+ break;
2326
+ }
2327
+ index++;
2328
+ }
2329
+ }
2330
+
2331
+
2332
+ void fx_Array_prototype_sort(txMachine* the)
2333
+ {
2334
+ txSlot* array = fxCheckArray(the, mxThis, XS_MUTABLE);
2335
+ txSlot* function = C_NULL;
2336
+ if (mxArgc > 0) {
2337
+ txSlot* slot = mxArgv(0);
2338
+ if (slot->kind != XS_UNDEFINED_KIND) {
2339
+ if (fxIsCallable(the, slot))
2340
+ function = slot;
2341
+ else
2342
+ mxTypeError("compare is no function");
2343
+ }
2344
+ }
2345
+ if (function)
2346
+ fxSortArrayItems(the, function, C_NULL, fxGetArrayLength(the, mxThis));
2347
+ else {
2348
+ if (array)
2349
+ array = fxCheckArrayItems(the, array, 0, array->value.array.length);
2350
+ fxSortArrayItems(the, function, array, fxGetArrayLength(the, mxThis));
2351
+ }
2352
+ mxResult->kind = mxThis->kind;
2353
+ mxResult->value = mxThis->value;
2354
+ }
2355
+
2356
+ void fx_Array_prototype_splice(txMachine* the)
2357
+ {
2358
+ txIndex c = (txIndex)mxArgc;
2359
+ txNumber LENGTH = fxGetArrayLength(the, mxThis);
2360
+ txNumber START = fxArgToIndex(the, 0, 0, LENGTH);
2361
+ txNumber INSERTIONS, DELETIONS;
2362
+ txSlot* resultArray;
2363
+ txSlot* array = C_NULL;
2364
+ if (c == 0) {
2365
+ INSERTIONS = 0;
2366
+ DELETIONS = 0;
2367
+ }
2368
+ else if (c == 1) {
2369
+ INSERTIONS = 0;
2370
+ DELETIONS = LENGTH - START;
2371
+ }
2372
+ else {
2373
+ INSERTIONS = c - 2;
2374
+ DELETIONS = fxArgToRange(the, 1, 0, 0, LENGTH - START);
2375
+ }
2376
+ if (LENGTH + INSERTIONS - DELETIONS > C_MAX_SAFE_INTEGER)
2377
+ mxTypeError("unsafe integer");
2378
+ resultArray = fxCreateArraySpecies(the, DELETIONS);
2379
+ if (resultArray)
2380
+ array = fxCheckArray(the, mxThis, XS_MUTABLE);
2381
+ if (array) {
2382
+ if (INSERTIONS == DELETIONS)
2383
+ array = fxCheckArrayItems(the, array, (txIndex)START, (txIndex)(START + DELETIONS));
2384
+ else
2385
+ array = fxCheckArrayItems(the, array, (txIndex)START, (txIndex)LENGTH);
2386
+ }
2387
+ if (array) {
2388
+ txSlot* address;
2389
+ txIndex length = (txIndex)LENGTH;
2390
+ txIndex start = (txIndex)START;
2391
+ txIndex insertions = (txIndex)INSERTIONS;
2392
+ txIndex deletions = (txIndex)DELETIONS;
2393
+ txIndex index;
2394
+ if (LENGTH + INSERTIONS - DELETIONS > 0xFFFFFFFF)
2395
+ mxTypeError("array overflow");
2396
+ fxSetIndexSize(the, resultArray, deletions, XS_CHUNK);
2397
+ c_memcpy(resultArray->value.array.address, array->value.array.address + start, deletions * sizeof(txSlot));
2398
+ fxIndexArray(the, resultArray);
2399
+ mxMeterSome(deletions * 10);
2400
+ mxMeterSome(4);
2401
+ if (insertions < deletions) {
2402
+ c_memmove(array->value.array.address + start + insertions, array->value.array.address + start + deletions, (length - (start + deletions)) * sizeof(txSlot));
2403
+ fxSetIndexSize(the, array, length - (deletions - insertions), XS_CHUNK);
2404
+ mxMeterSome((length - (start + deletions)) * 10);
2405
+ mxMeterSome((deletions - insertions) * 4);
2406
+ }
2407
+ else if (insertions > deletions) {
2408
+ fxSetIndexSize(the, array, length + (insertions - deletions), XS_CHUNK);
2409
+ c_memmove(array->value.array.address + start + insertions, array->value.array.address + start + deletions, (length - (start + deletions)) * sizeof(txSlot));
2410
+ mxMeterSome((length - (start + deletions)) * 10);
2411
+ }
2412
+ address = array->value.array.address + start;
2413
+ index = 2;
2414
+ while (index < c) {
2415
+ txSlot* argument = mxArgv(index);
2416
+ address->ID = XS_NO_ID;
2417
+ address->kind = argument->kind;
2418
+ address->value = argument->value;
2419
+ address++;
2420
+ mxMeterSome(5);
2421
+ index++;
2422
+ }
2423
+ fxIndexArray(the, array);
2424
+ mxMeterSome(4);
2425
+ }
2426
+ else {
2427
+ txNumber INDEX = 0;
2428
+ while (INDEX < DELETIONS) {
2429
+ txNumber FROM = START + INDEX;
2430
+ mxPushSlot(mxThis);
2431
+ mxPushNumber(FROM);
2432
+ if (mxHasAt()) {
2433
+ mxPushSlot(mxThis);
2434
+ mxPushNumber(FROM);
2435
+ mxGetAt();
2436
+ mxPushSlot(mxResult);
2437
+ mxPushNumber(INDEX);
2438
+ mxDefineAt(0, XS_GET_ONLY);
2439
+ mxPop();
2440
+ }
2441
+ INDEX++;
2442
+ }
2443
+ mxPushNumber(DELETIONS);
2444
+ mxPushSlot(mxResult);
2445
+ mxSetID(mxID(_length));
2446
+ mxPop();
2447
+ if (INSERTIONS < DELETIONS) {
2448
+ INDEX = START;
2449
+ while (INDEX < (LENGTH - DELETIONS)) {
2450
+ fxMoveThisItem(the, INDEX + DELETIONS, INDEX + INSERTIONS);
2451
+ INDEX++;
2452
+ }
2453
+ INDEX = LENGTH;
2454
+ while (INDEX > (LENGTH - DELETIONS + INSERTIONS)) {
2455
+ mxPushSlot(mxThis);
2456
+ mxPushNumber(INDEX - 1);
2457
+ mxDeleteAt();
2458
+ mxPop();
2459
+ INDEX--;
2460
+ }
2461
+ }
2462
+ else if (INSERTIONS > DELETIONS) {
2463
+ INDEX = LENGTH - DELETIONS;
2464
+ while (INDEX > START) {
2465
+ fxMoveThisItem(the, INDEX + DELETIONS - 1, INDEX + INSERTIONS - 1);
2466
+ INDEX--;
2467
+ }
2468
+ }
2469
+ INDEX = 0;
2470
+ while (INDEX < INSERTIONS) {
2471
+ mxPushSlot(mxArgv(2 + (txInteger)INDEX));
2472
+ mxPushSlot(mxThis);
2473
+ mxPushNumber(START + INDEX);
2474
+ mxSetAt();
2475
+ mxPop();
2476
+ INDEX++;
2477
+ }
2478
+ mxPushNumber(LENGTH - DELETIONS + INSERTIONS);
2479
+ mxPushSlot(mxThis);
2480
+ mxSetID(mxID(_length));
2481
+ mxPop();
2482
+ }
2483
+ }
2484
+
2485
+ void fx_Array_prototype_toLocaleString(txMachine* the)
2486
+ {
2487
+ txIndex length = fxGetArrayLimit(the, mxThis);
2488
+ txIndex index = 0;
2489
+ txString string;
2490
+ txSlot* list = fxNewInstance(the);
2491
+ txSlot* slot = list;
2492
+ txBoolean comma = 0;
2493
+ txInteger size = 0;
2494
+
2495
+ mxPushStringX(",");
2496
+ the->stack->kind += XS_KEY_KIND - XS_STRING_KIND;
2497
+ the->stack->value.key.sum = 1;
2498
+ while (index < length) {
2499
+ if (comma) {
2500
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
2501
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
2502
+ }
2503
+ else
2504
+ comma = 1;
2505
+ mxPushSlot(mxThis);
2506
+ mxGetIndex(index);
2507
+ if ((the->stack->kind != XS_UNDEFINED_KIND) && (the->stack->kind != XS_NULL_KIND)) {
2508
+ mxDub();
2509
+ mxGetID(mxID(_toLocaleString));
2510
+ mxCall();
2511
+ mxRunCount(0);
2512
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
2513
+ string = fxToString(the, slot);
2514
+ slot->kind += XS_KEY_KIND - XS_STRING_KIND;
2515
+ slot->value.key.sum = mxStringLength(string);
2516
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
2517
+ }
2518
+ mxPop();
2519
+ index++;
2520
+ }
2521
+ string = mxResult->value.string = fxNewChunk(the, fxAddChunkSizes(the, size, 1));
2522
+ slot = list->next;
2523
+ while (slot) {
2524
+ c_memcpy(string, slot->value.key.string, slot->value.key.sum);
2525
+ string += slot->value.key.sum;
2526
+ slot = slot->next;
2527
+ }
2528
+ *string = 0;
2529
+ mxResult->kind = XS_STRING_KIND;
2530
+ mxPop();
2531
+ }
2532
+
2533
+ void fx_Array_prototype_toString(txMachine* the)
2534
+ {
2535
+ mxPushSlot(mxThis);
2536
+ mxDub();
2537
+ mxGetID(mxID(_join));
2538
+ if (fxIsCallable(the, the->stack)) {
2539
+ mxCall();
2540
+ mxRunCount(0);
2541
+ mxPullSlot(mxResult);
2542
+ }
2543
+ else {
2544
+ mxPop();
2545
+ mxPop();
2546
+ fx_Object_prototype_toString(the);
2547
+ }
2548
+ }
2549
+
2550
+ void fx_Array_prototype_unshift(txMachine* the)
2551
+ {
2552
+ txIndex c = mxArgc, i;
2553
+ txSlot* array = fxCheckArray(the, mxThis, XS_MUTABLE);
2554
+ if (array)
2555
+ array = fxCheckArrayItems(the, array, 0, array->value.array.length);
2556
+ if (array) {
2557
+ txSlot* address;
2558
+ txIndex length = array->value.array.length;
2559
+ if (length + c < length)
2560
+ mxRangeError("array overflow");
2561
+ if (c > 0) {
2562
+ fxSetIndexSize(the, array, length + c, XS_GROWABLE_CHUNK);
2563
+ address = array->value.array.address;
2564
+ c_memmove(address + c, address, length * sizeof(txSlot));
2565
+ mxMeterSome(length * 10);
2566
+ i = 0;
2567
+ while (i < c) {
2568
+ txSlot* argument = mxArgv(i);
2569
+ address->ID = XS_NO_ID;
2570
+ address->kind = argument->kind;
2571
+ address->value = argument->value;
2572
+ address++;
2573
+ mxMeterSome(4);
2574
+ i++;
2575
+ }
2576
+ fxIndexArray(the, array);
2577
+ }
2578
+ mxPushUnsigned(length + c);
2579
+ mxMeterSome(2);
2580
+ }
2581
+ else {
2582
+ txNumber length = fxGetArrayLength(the, mxThis);
2583
+ txNumber index = length;
2584
+ if (c > 0) {
2585
+ if (length + c > C_MAX_SAFE_INTEGER)
2586
+ mxTypeError("unsafe integer");
2587
+ while (index > 0) {
2588
+ fxMoveThisItem(the, index - 1, index + c - 1);
2589
+ index--;
2590
+ }
2591
+ i = 0;
2592
+ while (i < c) {
2593
+ mxPushSlot(mxArgv(i));
2594
+ mxPushSlot(mxThis);
2595
+ mxSetIndex(i);
2596
+ mxPop();
2597
+ i++;
2598
+ }
2599
+ }
2600
+ mxPushNumber(length + c);
2601
+ mxPushSlot(mxThis);
2602
+ mxSetID(mxID(_length));
2603
+ }
2604
+ mxPullSlot(mxResult);
2605
+ }
2606
+
2607
+ void fx_Array_prototype_values(txMachine* the)
2608
+ {
2609
+ txSlot* property;
2610
+ fxToInstance(the, mxThis);
2611
+ mxPush(mxArrayIteratorPrototype);
2612
+ property = fxLastProperty(the, fxNewIteratorInstance(the, mxThis, mxID(_Array)));
2613
+ property = fxNextIntegerProperty(the, property, 0, XS_NO_ID, XS_INTERNAL_FLAG);
2614
+ mxPullSlot(mxResult);
2615
+ }
2616
+
2617
+ void fx_ArrayIterator_prototype_next(txMachine* the)
2618
+ {
2619
+ txSlot* iterator = fxCheckIteratorInstance(the, mxThis, mxID(_Array));
2620
+ txSlot* result = iterator->next;
2621
+ txSlot* iterable = result->next;
2622
+ txSlot* index = iterable->next;
2623
+ txSlot* value = fxCheckIteratorResult(the, result);
2624
+ txSlot* done = value->next;
2625
+ if (!done->value.boolean) {
2626
+ txInteger kind = index->next->value.integer;
2627
+ txIndex length = fxGetArrayLimit(the, iterable);
2628
+ txIndex i = (txIndex)index->value.integer;
2629
+ if (i < length) {
2630
+ switch(kind) {
2631
+ case 0:
2632
+ mxPushSlot(iterable);
2633
+ mxGetIndex(i);
2634
+ mxPullSlot(value);
2635
+ break;
2636
+ case 1:
2637
+ mxPushUnsigned(i);
2638
+ mxPullSlot(value);
2639
+ break;
2640
+ case 2:
2641
+ mxPushUnsigned(i);
2642
+ mxPushSlot(iterable);
2643
+ mxGetIndex(i);
2644
+ fxConstructArrayEntry(the, value);
2645
+ break;
2646
+ }
2647
+ index->value.integer = i + 1;
2648
+ }
2649
+ else {
2650
+ value->kind = XS_UNDEFINED_KIND;
2651
+ done->value.boolean = 1;
2652
+ }
2653
+ }
2654
+ mxResult->kind = result->kind;
2655
+ mxResult->value = result->value;
2656
+ }
2657
+