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

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,2890 @@
1
+ /*
2
+ * Copyright (c) 2016-2017 Moddable Tech, Inc.
3
+ *
4
+ * This file is part of the Moddable SDK Runtime.
5
+ *
6
+ * The Moddable SDK Runtime is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU Lesser General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * The Moddable SDK Runtime is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public License
17
+ * along with the Moddable SDK Runtime. If not, see <http://www.gnu.org/licenses/>.
18
+ *
19
+ * This file incorporates work covered by the following copyright and
20
+ * permission notice:
21
+ *
22
+ * Copyright (C) 2010-2016 Marvell International Ltd.
23
+ * Copyright (C) 2002-2010 Kinoma, Inc.
24
+ *
25
+ * Licensed under the Apache License, Version 2.0 (the "License");
26
+ * you may not use this file except in compliance with the License.
27
+ * You may obtain a copy of the License at
28
+ *
29
+ * http://www.apache.org/licenses/LICENSE-2.0
30
+ *
31
+ * Unless required by applicable law or agreed to in writing, software
32
+ * distributed under the License is distributed on an "AS IS" BASIS,
33
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
+ * See the License for the specific language governing permissions and
35
+ * limitations under the License.
36
+ */
37
+
38
+ #include "xsAll.h"
39
+
40
+ static txSlot* fxArgToInstance(txMachine* the, txInteger i);
41
+ static txBoolean fxCheckLength(txMachine* the, txSlot* slot, txInteger* index);
42
+
43
+ static txSlot* fxCheckArrayBufferDetached(txMachine* the, txSlot* slot, txBoolean mutable);
44
+ static txSlot* fxCheckArrayBufferInstance(txMachine* the, txSlot* slot);
45
+ static txSlot* fxNewArrayBufferInstance(txMachine* the);
46
+
47
+ static txSlot* fxCheckDataViewInstance(txMachine* the, txSlot* slot);
48
+ static txInteger fxCheckDataViewSize(txMachine* the, txSlot* view, txSlot* buffer, txBoolean mutable);
49
+ static txSlot* fxNewDataViewInstance(txMachine* the);
50
+
51
+ static void fxCallTypedArrayItem(txMachine* the, txSlot* function, txSlot* dispatch, txSlot* view, txSlot* data, txInteger index, txSlot* item);
52
+ static txSlot* fxCheckTypedArrayInstance(txMachine* the, txSlot* slot);
53
+ static txSlot* fxConstructTypedArray(txMachine* the);
54
+ static txSlot* fxNewTypedArrayInstance(txMachine* the, txTypeDispatch* dispatch, txTypeAtomics* atomics);
55
+ static void fxReduceTypedArrayItem(txMachine* the, txSlot* function, txSlot* dispatch, txSlot* view, txSlot* data, txInteger index);
56
+
57
+ static txBoolean fxTypedArrayDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* slot, txFlag mask);
58
+ static txBoolean fxTypedArrayDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index);
59
+ static txBoolean fxTypedArrayGetOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* slot);
60
+ static txSlot* fxTypedArrayGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
61
+ static txBoolean fxTypedArrayGetPropertyValue(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* value, txSlot* receiver);
62
+ static txBoolean fxTypedArrayHasProperty(txMachine* the, txSlot* instance, txID id, txIndex index);
63
+ static void fxTypedArrayOwnKeys(txMachine* the, txSlot* instance, txFlag flag, txSlot* keys);
64
+ static txSlot* fxTypedArraySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag);
65
+ static txBoolean fxTypedArraySetPropertyValue(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* value, txSlot* receiver);
66
+
67
+ static void fx_TypedArray_from_object(txMachine* the, txSlot* instance, txSlot* function, txSlot* _this);
68
+
69
+ const txBehavior ICACHE_FLASH_ATTR gxTypedArrayBehavior = {
70
+ fxTypedArrayGetProperty,
71
+ fxTypedArraySetProperty,
72
+ fxOrdinaryCall,
73
+ fxOrdinaryConstruct,
74
+ fxTypedArrayDefineOwnProperty,
75
+ fxTypedArrayDeleteProperty,
76
+ fxTypedArrayGetOwnProperty,
77
+ fxTypedArrayGetPropertyValue,
78
+ fxOrdinaryGetPrototype,
79
+ fxTypedArrayHasProperty,
80
+ fxOrdinaryIsExtensible,
81
+ fxTypedArrayOwnKeys,
82
+ fxOrdinaryPreventExtensions,
83
+ fxTypedArraySetPropertyValue,
84
+ fxOrdinarySetPrototype,
85
+ };
86
+
87
+ void *fxArrayBuffer(txMachine* the, txSlot* slot, void* data, txInteger byteLength, txInteger maxByteLength)
88
+ {
89
+ txSlot* instance;
90
+ txSlot* arrayBuffer;
91
+ txSlot* bufferInfo;
92
+ if (byteLength < 0)
93
+ mxRangeError("invalid byteLength %ld", byteLength);
94
+ mxPush(mxArrayBufferPrototype);
95
+ instance = fxNewArrayBufferInstance(the);
96
+ arrayBuffer = instance->next;
97
+ arrayBuffer->value.arrayBuffer.address = fxNewChunk(the, byteLength);
98
+ bufferInfo = arrayBuffer->next;
99
+ bufferInfo->value.bufferInfo.length = byteLength;
100
+ bufferInfo->value.bufferInfo.maxLength = maxByteLength;
101
+ if (data != NULL)
102
+ c_memcpy(arrayBuffer->value.arrayBuffer.address, data, byteLength);
103
+ else
104
+ c_memset(arrayBuffer->value.arrayBuffer.address, 0, byteLength);
105
+ mxPullSlot(slot);
106
+ return arrayBuffer->value.arrayBuffer.address;
107
+ }
108
+
109
+ void fxGetArrayBufferData(txMachine* the, txSlot* slot, txInteger byteOffset, void* data, txInteger byteLength)
110
+ {
111
+ txSlot* instance = fxCheckArrayBufferInstance(the, slot);
112
+ txSlot* arrayBuffer = instance->next;
113
+ txSlot* bufferInfo = arrayBuffer->next;
114
+ txInteger length = bufferInfo->value.bufferInfo.length;
115
+ if ((byteOffset < 0) || (length < byteOffset))
116
+ mxRangeError("out of range byteOffset %ld", byteOffset);
117
+ if ((byteLength < 0) || (length < (byteOffset + byteLength)))
118
+ mxRangeError("out of range byteLength %ld", byteLength);
119
+ c_memcpy(data, arrayBuffer->value.arrayBuffer.address + byteOffset, byteLength);
120
+ }
121
+
122
+ txInteger fxGetArrayBufferLength(txMachine* the, txSlot* slot)
123
+ {
124
+ txSlot* instance = fxCheckArrayBufferInstance(the, slot);
125
+ txSlot* arrayBuffer = instance->next;
126
+ txSlot* bufferInfo = arrayBuffer->next;
127
+ return bufferInfo->value.bufferInfo.length;
128
+ }
129
+
130
+ txInteger fxGetArrayBufferMaxLength(txMachine* the, txSlot* slot)
131
+ {
132
+ txSlot* instance = fxCheckArrayBufferInstance(the, slot);
133
+ txSlot* arrayBuffer = instance->next;
134
+ txSlot* bufferInfo = arrayBuffer->next;
135
+ return bufferInfo->value.bufferInfo.maxLength;
136
+ }
137
+
138
+ void fxSetArrayBufferData(txMachine* the, txSlot* slot, txInteger byteOffset, void* data, txInteger byteLength)
139
+ {
140
+ txSlot* instance = fxCheckArrayBufferInstance(the, slot);
141
+ txSlot* arrayBuffer = instance->next;
142
+ txSlot* bufferInfo = arrayBuffer->next;
143
+ txInteger length = bufferInfo->value.bufferInfo.length;
144
+ if ((byteOffset < 0) || (length < byteOffset))
145
+ mxRangeError("out of range byteOffset %ld", byteOffset);
146
+ if ((byteLength < 0) || (length < (byteOffset + byteLength)))
147
+ mxRangeError("out of range byteLength %ld", byteLength);
148
+ c_memcpy(arrayBuffer->value.arrayBuffer.address + byteOffset, data, byteLength);
149
+ }
150
+
151
+ void fxSetArrayBufferLength(txMachine* the, txSlot* slot, txInteger target)
152
+ {
153
+ txSlot* instance = fxCheckArrayBufferInstance(the, slot);
154
+ txSlot* arrayBuffer = instance->next;
155
+ txSlot* bufferInfo = arrayBuffer->next;
156
+ txInteger length = bufferInfo->value.bufferInfo.length;
157
+ txByte* address = arrayBuffer->value.arrayBuffer.address;
158
+ if (bufferInfo->value.bufferInfo.maxLength < 0)
159
+ fxReport(the, "# Use xsArrayBufferResizable instead of xsArrayBuffer\n");
160
+ if (length != target) {
161
+ if (address)
162
+ address = (txByte*)fxRenewChunk(the, address, target);
163
+ if (address) {
164
+ if (length < target)
165
+ c_memset(address + length, 0, target - length);
166
+ }
167
+ else {
168
+ address = (txByte*)fxNewChunk(the, target);
169
+ if (length < target) {
170
+ c_memcpy(address, arrayBuffer->value.arrayBuffer.address, length);
171
+ c_memset(address + length, 0, target - length);
172
+ }
173
+ else
174
+ c_memcpy(address, arrayBuffer->value.arrayBuffer.address, target);
175
+ }
176
+ arrayBuffer->value.arrayBuffer.address = address;
177
+ bufferInfo->value.bufferInfo.length = target;
178
+ }
179
+ }
180
+
181
+ void* fxToArrayBuffer(txMachine* the, txSlot* slot)
182
+ {
183
+ txSlot* instance = fxCheckArrayBufferInstance(the, slot);
184
+ txSlot* arrayBuffer = instance->next;
185
+ return arrayBuffer->value.arrayBuffer.address;
186
+ }
187
+
188
+ void fxBuildDataView(txMachine* the)
189
+ {
190
+ txSlot* instance;
191
+ txSlot* slot;
192
+ txInteger index;
193
+ const txTypeDispatch *dispatch;
194
+ const txTypeAtomics *atomics;
195
+ txSlot* property;
196
+ txSlot* constructor;
197
+
198
+ mxPush(mxObjectPrototype);
199
+ slot = fxLastProperty(the, fxNewObjectInstance(the));
200
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_get_byteLength), C_NULL, mxID(_byteLength), XS_DONT_ENUM_FLAG);
201
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_get_maxByteLength), C_NULL, mxID(_maxByteLength), XS_DONT_ENUM_FLAG);
202
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_get_resizable), C_NULL, mxID(_resizable), XS_DONT_ENUM_FLAG);
203
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_concat), 1, mxID(_concat), XS_DONT_ENUM_FLAG);
204
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_resize), 1, mxID(_resize), XS_DONT_ENUM_FLAG);
205
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_slice), 2, mxID(_slice), XS_DONT_ENUM_FLAG);
206
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_prototype_transfer), 0, mxID(_transfer), XS_DONT_ENUM_FLAG);
207
+ slot = fxNextStringXProperty(the, slot, "ArrayBuffer", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
208
+ mxArrayBufferPrototype = *the->stack;
209
+ slot = fxBuildHostConstructor(the, mxCallback(fx_ArrayBuffer), 1, mxID(_ArrayBuffer));
210
+ mxArrayBufferConstructor = *the->stack;
211
+ slot = fxLastProperty(the, slot);
212
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_fromBigInt), 1, mxID(_fromBigInt), XS_DONT_ENUM_FLAG);
213
+ #ifndef mxCESU8
214
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_fromString), 1, mxID(_fromString), XS_DONT_ENUM_FLAG);
215
+ #endif
216
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_ArrayBuffer_isView), 1, mxID(_isView), XS_DONT_ENUM_FLAG);
217
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG);
218
+ mxPop();
219
+
220
+ mxPush(mxObjectPrototype);
221
+ slot = fxLastProperty(the, fxNewObjectInstance(the));
222
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getBigInt64), 1, mxID(_getBigInt64), XS_DONT_ENUM_FLAG);
223
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setBigInt64), 2, mxID(_setBigInt64), XS_DONT_ENUM_FLAG);
224
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getBigUint64), 1, mxID(_getBigUint64), XS_DONT_ENUM_FLAG);
225
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setBigUint64), 2, mxID(_setBigUint64), XS_DONT_ENUM_FLAG);
226
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getFloat32), 1, mxID(_getFloat32), XS_DONT_ENUM_FLAG);
227
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setFloat32), 2, mxID(_setFloat32), XS_DONT_ENUM_FLAG);
228
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getFloat64), 1, mxID(_getFloat64), XS_DONT_ENUM_FLAG);
229
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setFloat64), 2, mxID(_setFloat64), XS_DONT_ENUM_FLAG);
230
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getInt8), 1, mxID(_getInt8), XS_DONT_ENUM_FLAG);
231
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setInt8), 2, mxID(_setInt8), XS_DONT_ENUM_FLAG);
232
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getInt16), 1, mxID(_getInt16), XS_DONT_ENUM_FLAG);
233
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setInt16), 2, mxID(_setInt16), XS_DONT_ENUM_FLAG);
234
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getInt32), 1, mxID(_getInt32), XS_DONT_ENUM_FLAG);
235
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setInt32), 2, mxID(_setInt32), XS_DONT_ENUM_FLAG);
236
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getUint8), 1, mxID(_getUint8), XS_DONT_ENUM_FLAG);
237
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setUint8), 2, mxID(_setUint8), XS_DONT_ENUM_FLAG);
238
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getUint16), 1, mxID(_getUint16), XS_DONT_ENUM_FLAG);
239
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setUint16), 2, mxID(_setUint16), XS_DONT_ENUM_FLAG);
240
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_getUint32), 1, mxID(_getUint32), XS_DONT_ENUM_FLAG);
241
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_DataView_prototype_setUint32), 2, mxID(_setUint32), XS_DONT_ENUM_FLAG);
242
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_DataView_prototype_buffer_get), C_NULL, mxID(_buffer), XS_DONT_ENUM_FLAG);
243
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_DataView_prototype_byteLength_get), C_NULL, mxID(_byteLength), XS_DONT_ENUM_FLAG);
244
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_DataView_prototype_byteOffset_get), C_NULL, mxID(_byteOffset), XS_DONT_ENUM_FLAG);
245
+ slot = fxNextStringXProperty(the, slot, "DataView", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
246
+ mxDataViewPrototype = *the->stack;
247
+ slot = fxBuildHostConstructor(the, mxCallback(fx_DataView), 1, mxID(_DataView));
248
+ mxDataViewConstructor = *the->stack;
249
+ mxPop();
250
+
251
+ mxPush(mxObjectPrototype);
252
+ instance = fxNewObjectInstance(the);
253
+
254
+ fxNewHostFunction(the, mxCallback(fxTypedArrayGetter), 0, XS_NO_ID, XS_NO_ID);
255
+ property = mxFunctionInstanceHome(the->stack->value.reference);
256
+ property->value.home.object = instance;
257
+ fxNewHostFunction(the, mxCallback(fxTypedArraySetter), 1, XS_NO_ID, XS_NO_ID);
258
+ property = mxFunctionInstanceHome(the->stack->value.reference);
259
+ property->value.home.object = instance;
260
+ mxPushUndefined();
261
+ the->stack->flag = XS_DONT_DELETE_FLAG;
262
+ the->stack->kind = XS_ACCESSOR_KIND;
263
+ the->stack->value.accessor.getter = (the->stack + 2)->value.reference;
264
+ the->stack->value.accessor.setter = (the->stack + 1)->value.reference;
265
+ mxPull(mxTypedArrayAccessor);
266
+ mxPop();
267
+ mxPop();
268
+
269
+ slot = fxLastProperty(the, instance);
270
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_at), 1, mxID(_at), XS_DONT_ENUM_FLAG);
271
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_TypedArray_prototype_buffer_get), C_NULL, mxID(_buffer), XS_DONT_ENUM_FLAG);
272
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_TypedArray_prototype_byteLength_get), C_NULL, mxID(_byteLength), XS_DONT_ENUM_FLAG);
273
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_TypedArray_prototype_byteOffset_get), C_NULL, mxID(_byteOffset), XS_DONT_ENUM_FLAG);
274
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_TypedArray_prototype_length_get), C_NULL, mxID(_length), XS_DONT_ENUM_FLAG);
275
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_TypedArray_prototype_toStringTag_get), C_NULL, mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG);
276
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_copyWithin), 2, mxID(_copyWithin), XS_DONT_ENUM_FLAG);
277
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_entries), 0, mxID(_entries), XS_DONT_ENUM_FLAG);
278
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_every), 1, mxID(_every), XS_DONT_ENUM_FLAG);
279
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_fill), 1, mxID(_fill), XS_DONT_ENUM_FLAG);
280
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_filter), 1, mxID(_filter), XS_DONT_ENUM_FLAG);
281
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_find), 1, mxID(_find), XS_DONT_ENUM_FLAG);
282
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_findIndex), 1, mxID(_findIndex), XS_DONT_ENUM_FLAG);
283
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_findLast), 1, mxID(_findLast), XS_DONT_ENUM_FLAG);
284
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_findLastIndex), 1, mxID(_findLastIndex), XS_DONT_ENUM_FLAG);
285
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_forEach), 1, mxID(_forEach), XS_DONT_ENUM_FLAG);
286
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_includes), 1, mxID(_includes), XS_DONT_ENUM_FLAG);
287
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_indexOf), 1, mxID(_indexOf), XS_DONT_ENUM_FLAG);
288
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_join), 1, mxID(_join), XS_DONT_ENUM_FLAG);
289
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_keys), 0, mxID(_keys), XS_DONT_ENUM_FLAG);
290
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_lastIndexOf), 1, mxID(_lastIndexOf), XS_DONT_ENUM_FLAG);
291
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_map), 1, mxID(_map), XS_DONT_ENUM_FLAG);
292
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_reduce), 1, mxID(_reduce), XS_DONT_ENUM_FLAG);
293
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_reduceRight), 1, mxID(_reduceRight), XS_DONT_ENUM_FLAG);
294
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_reverse), 0, mxID(_reverse), XS_DONT_ENUM_FLAG);
295
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_set), 1, mxID(_set), XS_DONT_ENUM_FLAG);
296
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_slice), 2, mxID(_slice), XS_DONT_ENUM_FLAG);
297
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_some), 1, mxID(_some), XS_DONT_ENUM_FLAG);
298
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_sort), 1, mxID(_sort), XS_DONT_ENUM_FLAG);
299
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_subarray), 2, mxID(_subarray), XS_DONT_ENUM_FLAG);
300
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_toLocaleString), 0, mxID(_toLocaleString), XS_DONT_ENUM_FLAG);
301
+ property = mxBehaviorGetProperty(the, mxArrayPrototype.value.reference, mxID(_toString), 0, XS_OWN);
302
+ slot = fxNextSlotProperty(the, slot, property, mxID(_toString), XS_DONT_ENUM_FLAG);
303
+ property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_prototype_values), 0, mxID(_values), XS_DONT_ENUM_FLAG);
304
+ slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
305
+ mxTypedArrayPrototype = *the->stack;
306
+ constructor = fxBuildHostConstructor(the, mxCallback(fx_TypedArray), 0, mxID(_TypedArray));
307
+ mxTypedArrayConstructor = *the->stack;
308
+ slot = fxLastProperty(the, constructor);
309
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_from), 1, mxID(_from), XS_DONT_ENUM_FLAG);
310
+ slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_TypedArray_of), 0, mxID(_of), XS_DONT_ENUM_FLAG);
311
+ slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG);
312
+ for (index = 0, dispatch = &gxTypeDispatches[0], atomics = &gxTypeAtomics[0]; index < mxTypeArrayCount; index++, dispatch++, atomics++) {
313
+ mxPush(mxTypedArrayPrototype);
314
+ slot = fxLastProperty(the, fxNewObjectInstance(the));
315
+ slot = fxNextIntegerProperty(the, slot, dispatch->size, mxID(_BYTES_PER_ELEMENT), XS_GET_ONLY);
316
+ slot = fxBuildHostConstructor(the, mxCallback(fx_TypedArray), 3, mxID(dispatch->constructorID));
317
+ the->stackPrototypes[-1 - (txInteger)dispatch->constructorID] = *the->stack; //@@
318
+ slot->value.instance.prototype = constructor;
319
+ property = mxFunctionInstanceHome(slot);
320
+ slot = property->next;
321
+ property = fxNextTypeDispatchProperty(the, property, (txTypeDispatch*)dispatch, (txTypeAtomics*)atomics, XS_NO_ID, XS_INTERNAL_FLAG);
322
+ property->next = slot;
323
+ slot = fxLastProperty(the, slot);
324
+ slot = fxNextIntegerProperty(the, slot, dispatch->size, mxID(_BYTES_PER_ELEMENT), XS_GET_ONLY);
325
+ mxPop();
326
+ }
327
+ mxPop();
328
+ }
329
+
330
+ txInteger fxArgToByteLength(txMachine* the, txInteger argi, txInteger length)
331
+ {
332
+ txSlot *arg = mxArgv(argi);
333
+ if ((mxArgc > argi) && (arg->kind != XS_UNDEFINED_KIND)) {
334
+ txNumber value;
335
+ if (XS_INTEGER_KIND == arg->kind) {
336
+ txInteger value = arg->value.integer;
337
+ if (value < 0)
338
+ mxRangeError("out of range byteLength");
339
+ return value;
340
+ }
341
+ value = c_trunc(fxToNumber(the, arg));
342
+ if (c_isnan(value))
343
+ return 0;
344
+ if ((value < 0) || (0x7FFFFFFF < value))
345
+ mxRangeError("out of range byteLength");
346
+ return (txInteger)value;
347
+ }
348
+ return length;
349
+ }
350
+
351
+ txSlot* fxArgToInstance(txMachine* the, txInteger i)
352
+ {
353
+ if (mxArgc > i)
354
+ return fxToInstance(the, mxArgv(i));
355
+ mxTypeError("Cannot coerce undefined to object");
356
+ return C_NULL;
357
+ }
358
+
359
+ txBoolean fxCheckLength(txMachine* the, txSlot* slot, txInteger* index)
360
+ {
361
+ txNumber number = fxToNumber(the, slot);
362
+ txNumber check = c_trunc(number);
363
+ if ((number == check) && (0 <= number) && (number <= 0x7FFFFFFF)) {
364
+ *index = (txInteger)number;
365
+ return 1 ;
366
+ }
367
+ return 0;
368
+ }
369
+
370
+ txSlot* fxCheckArrayBufferDetached(txMachine* the, txSlot* slot, txBoolean mutable)
371
+ {
372
+ slot = slot->value.reference->next;
373
+ if (slot->value.arrayBuffer.address == C_NULL)
374
+ mxTypeError("detached buffer");
375
+ if (mutable && (slot->flag & XS_DONT_SET_FLAG))
376
+ mxTypeError("ArrayBuffer instance is read-only");
377
+ return slot;
378
+ }
379
+
380
+ txSlot* fxCheckArrayBufferInstance(txMachine* the, txSlot* slot)
381
+ {
382
+ if (slot->kind == XS_REFERENCE_KIND) {
383
+ txSlot* instance = slot->value.reference;
384
+ if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_ARRAY_BUFFER_KIND))
385
+ return instance;
386
+ }
387
+ mxTypeError("this is no ArrayBuffer instance");
388
+ return C_NULL;
389
+ }
390
+
391
+ void fxConstructArrayBufferResult(txMachine* the, txSlot* constructor, txInteger length)
392
+ {
393
+ txSlot* instance;
394
+ if (constructor)
395
+ mxPushSlot(constructor);
396
+ else {
397
+ mxPushSlot(mxThis);
398
+ mxGetID(mxID(_constructor));
399
+ }
400
+ fxToSpeciesConstructor(the, &mxArrayBufferConstructor);
401
+ mxNew();
402
+ mxPushInteger(length);
403
+ mxRunCount(1);
404
+ if (the->stack->kind != XS_REFERENCE_KIND)
405
+ mxTypeError("no instance");
406
+ instance = the->stack->value.reference;
407
+ if (!(instance->next) || (instance->next->kind != XS_ARRAY_BUFFER_KIND))
408
+ mxTypeError("no ArrayBuffer instance");
409
+ if (!constructor && (mxThis->value.reference == instance))
410
+ mxTypeError("same ArrayBuffer instance");
411
+ if (instance->next->next->value.bufferInfo.length < length)
412
+ mxTypeError("smaller ArrayBuffer instance");
413
+ mxPullSlot(mxResult);
414
+ }
415
+
416
+ txSlot* fxNewArrayBufferInstance(txMachine* the)
417
+ {
418
+ txSlot* instance;
419
+ txSlot* property;
420
+ instance = fxNewObjectInstance(the);
421
+ property = instance->next = fxNewSlot(the);
422
+ property->flag = XS_INTERNAL_FLAG;
423
+ property->kind = XS_ARRAY_BUFFER_KIND;
424
+ property->value.arrayBuffer.address = C_NULL;
425
+ property->value.arrayBuffer.detachKey = C_NULL;
426
+ property = property->next = fxNewSlot(the);
427
+ property->flag = XS_INTERNAL_FLAG;
428
+ property->kind = XS_BUFFER_INFO_KIND;
429
+ property->value.bufferInfo.length = 0;
430
+ property->value.bufferInfo.maxLength = -1;
431
+ return instance;
432
+ }
433
+
434
+ void fx_ArrayBuffer(txMachine* the)
435
+ {
436
+ txSlot* instance;
437
+ txInteger byteLength;
438
+ txInteger maxByteLength = -1;
439
+ txSlot* property;
440
+ if (mxIsUndefined(mxTarget))
441
+ mxTypeError("call: ArrayBuffer");
442
+ mxPushSlot(mxTarget);
443
+ fxGetPrototypeFromConstructor(the, &mxArrayBufferPrototype);
444
+ instance = fxNewArrayBufferInstance(the);
445
+ mxPullSlot(mxResult);
446
+ byteLength = fxArgToByteLength(the, 0, 0);
447
+ if ((mxArgc > 1) && mxIsReference(mxArgv(1))) {
448
+ mxPushSlot(mxArgv(1));
449
+ mxGetID(mxID(_maxByteLength));
450
+ mxPullSlot(mxArgv(1));
451
+ maxByteLength = fxArgToByteLength(the, 1, -1);
452
+ }
453
+ if (maxByteLength >= 0) {
454
+ if (byteLength > maxByteLength)
455
+ mxRangeError("byteLength > maxByteLength");
456
+ }
457
+ property = instance->next;
458
+ property->value.arrayBuffer.address = fxNewChunk(the, byteLength);
459
+ c_memset(property->value.arrayBuffer.address, 0, byteLength);
460
+ property = property->next;
461
+ property->value.bufferInfo.length = byteLength;
462
+ property->value.bufferInfo.maxLength = maxByteLength;
463
+ }
464
+
465
+ void fx_ArrayBuffer_fromBigInt(txMachine* the)
466
+ {
467
+ txU4 minBytes = 0;
468
+ txBoolean sign = 0;
469
+ int endian = EndianBig;
470
+ if (mxArgc < 1)
471
+ mxTypeError("no argument");
472
+ if (mxArgc > 1) {
473
+ txInteger m = fxToInteger(the, mxArgv(1));
474
+ if (m < 0)
475
+ mxRangeError("minBytes < 0");
476
+ minBytes = (txU4)m;
477
+ }
478
+ if ((mxArgc > 2) && fxToBoolean(the, mxArgv(2)))
479
+ sign = 1;
480
+ if ((mxArgc > 3) && fxToBoolean(the, mxArgv(3)))
481
+ endian = EndianLittle;
482
+ if (gxTypeBigInt.toArrayBuffer) {
483
+ gxTypeBigInt.toArrayBuffer(the, mxArgv(0), minBytes, sign, endian);
484
+ }
485
+ else {
486
+ mxUnknownError("not built-in");
487
+ }
488
+ }
489
+
490
+ #ifndef mxCESU8
491
+ void fx_ArrayBuffer_fromString(txMachine* the)
492
+ {
493
+ txSize length;
494
+ if (mxArgc < 1)
495
+ mxTypeError("no argument");
496
+ length = mxStringLength(fxToString(the, mxArgv(0)));
497
+ fxConstructArrayBufferResult(the, mxThis, length);
498
+ c_memcpy(mxResult->value.reference->next->value.arrayBuffer.address, mxArgv(0)->value.string, length);
499
+ }
500
+ #endif
501
+
502
+ void fx_ArrayBuffer_isView(txMachine* the)
503
+ {
504
+ txSlot* slot;
505
+ mxResult->kind = XS_BOOLEAN_KIND;
506
+ mxResult->value.boolean = 0;
507
+ if (mxArgc > 0) {
508
+ slot = mxArgv(0);
509
+ if (slot->kind == XS_REFERENCE_KIND) {
510
+ slot = slot->value.reference;
511
+ if (slot->next) {
512
+ slot = slot->next;
513
+ if ((slot->kind == XS_DATA_VIEW_KIND) || (slot->kind == XS_TYPED_ARRAY_KIND)) {
514
+ mxResult->value.boolean = 1;
515
+ }
516
+ }
517
+ }
518
+ }
519
+ }
520
+
521
+ void fx_ArrayBuffer_prototype_get_byteLength(txMachine* the)
522
+ {
523
+ txSlot* instance = fxCheckArrayBufferInstance(the, mxThis);
524
+ txSlot* arrayBuffer = instance->next;
525
+ txSlot* bufferInfo = arrayBuffer->next;
526
+ mxResult->kind = XS_INTEGER_KIND;
527
+ if (arrayBuffer->value.arrayBuffer.address == C_NULL)
528
+ mxResult->value.integer = 0;
529
+ else
530
+ mxResult->value.integer = bufferInfo->value.bufferInfo.length;
531
+ }
532
+
533
+ void fx_ArrayBuffer_prototype_get_maxByteLength(txMachine* the)
534
+ {
535
+ txSlot* instance = fxCheckArrayBufferInstance(the, mxThis);
536
+ txSlot* arrayBuffer = instance->next;
537
+ txSlot* bufferInfo = arrayBuffer->next;
538
+ mxResult->kind = XS_INTEGER_KIND;
539
+ if (arrayBuffer->value.arrayBuffer.address == C_NULL)
540
+ mxResult->value.integer = 0;
541
+ else if (bufferInfo->value.bufferInfo.maxLength >= 0)
542
+ mxResult->value.integer = bufferInfo->value.bufferInfo.maxLength;
543
+ else
544
+ mxResult->value.integer = bufferInfo->value.bufferInfo.length;
545
+ }
546
+
547
+ void fx_ArrayBuffer_prototype_get_resizable(txMachine* the)
548
+ {
549
+ txSlot* instance = fxCheckArrayBufferInstance(the, mxThis);
550
+ txSlot* arrayBuffer = instance->next;
551
+ txSlot* bufferInfo = arrayBuffer->next;
552
+ mxResult->kind = XS_BOOLEAN_KIND;
553
+ mxResult->value.boolean = (bufferInfo->value.bufferInfo.maxLength >= 0) ? 1 : 0;
554
+ }
555
+
556
+ void fx_ArrayBuffer_prototype_concat(txMachine* the)
557
+ {
558
+ txSlot* instance = fxCheckArrayBufferInstance(the, mxThis);
559
+ txSlot* arrayBuffer = instance->next;
560
+ txSlot* bufferInfo = arrayBuffer->next;
561
+ txInteger length = bufferInfo->value.bufferInfo.length;
562
+ txInteger c = mxArgc, i = 0;
563
+ txByte* address;
564
+ txSlot* slot;
565
+ while (i < c) {
566
+ arrayBuffer = C_NULL;
567
+ bufferInfo = C_NULL;
568
+ slot = mxArgv(i);
569
+ if (slot->kind == XS_REFERENCE_KIND) {
570
+ slot = slot->value.reference->next;
571
+ if (slot && (slot->kind == XS_ARRAY_BUFFER_KIND)) {
572
+ arrayBuffer = slot;
573
+ bufferInfo = slot->next;
574
+ }
575
+ }
576
+ if (arrayBuffer)
577
+ length = fxAddChunkSizes(the, length, bufferInfo->value.bufferInfo.length);
578
+ else
579
+ mxTypeError("arguments[%ld] is no ArrayBuffer instance", i);
580
+ i++;
581
+ }
582
+ fxConstructArrayBufferResult(the, C_NULL, length);
583
+ arrayBuffer = instance->next;
584
+ bufferInfo = arrayBuffer->next;
585
+ address = mxResult->value.reference->next->value.arrayBuffer.address;
586
+ length = bufferInfo->value.bufferInfo.length;
587
+ c_memcpy(address, arrayBuffer->value.arrayBuffer.address, length);
588
+ address += length;
589
+ i = 0;
590
+ while (i < c) {
591
+ arrayBuffer = mxArgv(i)->value.reference->next;
592
+ bufferInfo = arrayBuffer->next;
593
+ length = bufferInfo->value.bufferInfo.length;
594
+ c_memcpy(address, arrayBuffer->value.arrayBuffer.address, length);
595
+ address += length;
596
+ i++;
597
+ }
598
+ }
599
+
600
+ void fx_ArrayBuffer_prototype_resize(txMachine* the)
601
+ {
602
+ /* txSlot* instance = */ fxCheckArrayBufferInstance(the, mxThis);
603
+ txSlot* arrayBuffer = fxCheckArrayBufferDetached(the, mxThis, XS_MUTABLE);
604
+ txSlot* bufferInfo = arrayBuffer->next;
605
+ txInteger maxByteLength, oldByteLength, newByteLength;
606
+ txByte* chunk;
607
+ maxByteLength = bufferInfo->value.bufferInfo.maxLength;
608
+ if (maxByteLength < 0)
609
+ mxTypeError("not resizable");
610
+ oldByteLength = bufferInfo->value.bufferInfo.length;
611
+ newByteLength = fxArgToByteLength(the, 0, 0);
612
+ if (newByteLength > maxByteLength)
613
+ mxRangeError("newLength > maxByteLength");
614
+ arrayBuffer = fxCheckArrayBufferDetached(the, mxThis, XS_MUTABLE);
615
+ chunk = (txByte*)fxRenewChunk(the, arrayBuffer->value.arrayBuffer.address, newByteLength);
616
+ if (!chunk) {
617
+ chunk = (txByte*)fxNewChunk(the, newByteLength);
618
+ c_memcpy(chunk, arrayBuffer->value.arrayBuffer.address, (newByteLength < oldByteLength) ? newByteLength : oldByteLength);
619
+ }
620
+ if (newByteLength > oldByteLength)
621
+ c_memset(chunk + oldByteLength, 0, newByteLength - oldByteLength);
622
+ arrayBuffer->value.arrayBuffer.address = chunk;
623
+ bufferInfo->value.bufferInfo.length = newByteLength;
624
+ }
625
+
626
+ void fx_ArrayBuffer_prototype_slice(txMachine* the)
627
+ {
628
+ /* txSlot* instance = */ fxCheckArrayBufferInstance(the, mxThis);
629
+ txSlot* arrayBuffer = fxCheckArrayBufferDetached(the, mxThis, XS_IMMUTABLE);
630
+ txSlot* bufferInfo = arrayBuffer->next;
631
+ txInteger length = bufferInfo->value.bufferInfo.length;
632
+ txInteger start = (txInteger)fxArgToIndex(the, 0, 0, length);
633
+ txInteger stop = (txInteger)fxArgToIndex(the, 1, length, length);
634
+ txSlot* resultBuffer;
635
+ if (stop < start)
636
+ stop = start;
637
+ fxConstructArrayBufferResult(the, C_NULL, stop - start);
638
+ resultBuffer = fxCheckArrayBufferDetached(the, mxResult, XS_MUTABLE);
639
+ arrayBuffer = fxCheckArrayBufferDetached(the, mxThis, XS_IMMUTABLE);
640
+ bufferInfo = arrayBuffer->next;
641
+ if (bufferInfo->value.bufferInfo.length < stop)
642
+ mxTypeError("resized this");
643
+ c_memcpy(resultBuffer->value.arrayBuffer.address, arrayBuffer->value.arrayBuffer.address + start, stop - start);
644
+ }
645
+
646
+ void fx_ArrayBuffer_prototype_transfer(txMachine* the)
647
+ {
648
+ /* txSlot* instance = */ fxCheckArrayBufferInstance(the, mxThis);
649
+ txSlot* arrayBuffer = fxCheckArrayBufferDetached(the, mxThis, XS_MUTABLE);
650
+ txSlot* bufferInfo = arrayBuffer->next;
651
+ txInteger oldByteLength = bufferInfo->value.bufferInfo.length;
652
+ txInteger newByteLength = fxArgToByteLength(the, 0, oldByteLength);
653
+ txSlot* resultBuffer;
654
+ fxConstructArrayBufferResult(the, C_NULL, newByteLength);
655
+ resultBuffer = fxCheckArrayBufferDetached(the, mxResult, XS_MUTABLE);
656
+ arrayBuffer = fxCheckArrayBufferDetached(the, mxThis, XS_MUTABLE);
657
+ c_memcpy(resultBuffer->value.arrayBuffer.address, arrayBuffer->value.arrayBuffer.address, (newByteLength < oldByteLength) ? newByteLength : oldByteLength);
658
+ if (newByteLength > oldByteLength)
659
+ c_memset(resultBuffer->value.arrayBuffer.address + oldByteLength, 0, newByteLength - oldByteLength);
660
+ arrayBuffer->value.arrayBuffer.address = C_NULL;
661
+ bufferInfo->value.bufferInfo.length = 0;
662
+ }
663
+
664
+ txSlot* fxCheckDataViewInstance(txMachine* the, txSlot* slot)
665
+ {
666
+ if (slot->kind == XS_REFERENCE_KIND) {
667
+ txSlot* instance = slot->value.reference;
668
+ if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_DATA_VIEW_KIND))
669
+ return instance;
670
+ }
671
+ mxTypeError("this is no DataView instance");
672
+ return C_NULL;
673
+ }
674
+
675
+ txInteger fxCheckDataViewSize(txMachine* the, txSlot* view, txSlot* buffer, txBoolean mutable)
676
+ {
677
+ txInteger size = view->value.dataView.size;
678
+ txSlot* arrayBuffer = buffer->value.reference->next;
679
+ txSlot* bufferInfo = arrayBuffer->next;
680
+ if (arrayBuffer->value.arrayBuffer.address == C_NULL)
681
+ mxTypeError("detached buffer");
682
+ if (mutable && (arrayBuffer->flag & XS_DONT_SET_FLAG))
683
+ mxTypeError("read-only buffer");
684
+ if (bufferInfo->value.bufferInfo.maxLength >= 0) {
685
+ txInteger offset = view->value.dataView.offset;
686
+ txInteger byteLength = bufferInfo->value.bufferInfo.length;
687
+ if (offset > byteLength)
688
+ mxTypeError("out of bounds view");
689
+ else if (size < 0)
690
+ size = byteLength - offset;
691
+ else if (offset + size > byteLength)
692
+ mxTypeError("out of bounds view");
693
+ }
694
+ return size;
695
+ }
696
+
697
+ txSlot* fxGetBufferInfo(txMachine* the, txSlot* buffer)
698
+ {
699
+ txSlot* arrayBuffer = buffer->value.reference->next;
700
+ txSlot* bufferInfo = arrayBuffer->next;
701
+ if (arrayBuffer->kind == XS_ARRAY_BUFFER_KIND) {
702
+ if (arrayBuffer->value.arrayBuffer.address == C_NULL)
703
+ mxTypeError("detached buffer");
704
+ return bufferInfo;
705
+ }
706
+ if (arrayBuffer->kind == XS_HOST_KIND) {
707
+ txInteger byteLength;
708
+ if (bufferInfo && (bufferInfo->kind == XS_BUFFER_INFO_KIND))
709
+ return bufferInfo;
710
+ mxPushSlot(buffer);
711
+ mxGetID(mxID(_byteLength));
712
+ if (!fxCheckLength(the, the->stack, &byteLength))
713
+ mxTypeError("invalid byteLength");
714
+ fxReport(the, "# Use xsSetHostBuffer instead of xsSetHostData\n");
715
+ mxPop();
716
+ bufferInfo = fxNewSlot(the);
717
+ bufferInfo->next = arrayBuffer->next;
718
+ bufferInfo->flag = XS_INTERNAL_FLAG;
719
+ bufferInfo->kind = XS_BUFFER_INFO_KIND;
720
+ bufferInfo->value.bufferInfo.length = byteLength;
721
+ bufferInfo->value.bufferInfo.maxLength = -1;
722
+ arrayBuffer->next = bufferInfo;
723
+ return bufferInfo;
724
+ }
725
+ mxTypeError("invalid buffer");
726
+ return C_NULL;
727
+ }
728
+
729
+ txInteger fxGetDataViewSize(txMachine* the, txSlot* view, txSlot* buffer)
730
+ {
731
+ txInteger size = view->value.dataView.size;
732
+ txSlot* arrayBuffer = buffer->value.reference->next;
733
+ txSlot* bufferInfo = arrayBuffer->next;
734
+ if (arrayBuffer->value.arrayBuffer.address == C_NULL)
735
+ return 0;
736
+ if (bufferInfo->value.bufferInfo.maxLength >= 0) {
737
+ txInteger offset = view->value.dataView.offset;
738
+ txInteger byteLength = bufferInfo->value.bufferInfo.length;
739
+ if (offset > byteLength)
740
+ size = 0;
741
+ else if (size < 0)
742
+ size = byteLength - offset;
743
+ else if (offset + size > byteLength)
744
+ size = 0;
745
+ }
746
+ return size;
747
+ }
748
+
749
+ txSlot* fxNewDataViewInstance(txMachine* the)
750
+ {
751
+ txSlot* instance;
752
+ txSlot* property;
753
+ instance = fxNewObjectInstance(the);
754
+ property = instance->next = fxNewSlot(the);
755
+ property->flag = XS_INTERNAL_FLAG;
756
+ property->kind = XS_DATA_VIEW_KIND;
757
+ property->value.dataView.offset = 0;
758
+ property->value.dataView.size = 0;
759
+ property = fxNextNullProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
760
+ return instance;
761
+ }
762
+
763
+ void fx_DataView(txMachine* the)
764
+ {
765
+ txSlot* slot;
766
+ txBoolean flag = 0;
767
+ txInteger offset, size;
768
+ txSlot* info;
769
+ txSlot* instance;
770
+ txSlot* view;
771
+ txSlot* buffer;
772
+ if (mxIsUndefined(mxTarget))
773
+ mxTypeError("call: DataView");
774
+ if ((mxArgc > 0) && (mxArgv(0)->kind == XS_REFERENCE_KIND)) {
775
+ slot = mxArgv(0)->value.reference->next;
776
+ if (slot && ((slot->kind == XS_ARRAY_BUFFER_KIND) || (slot->kind == XS_HOST_KIND))) {
777
+ flag = 1;
778
+ }
779
+ }
780
+ if (!flag)
781
+ mxTypeError("buffer is no ArrayBuffer instance");
782
+
783
+ offset = fxArgToByteLength(the, 1, 0);
784
+ info = fxGetBufferInfo(the, mxArgv(0));
785
+ if (info->value.bufferInfo.length < offset)
786
+ mxRangeError("out of range byteOffset %ld", offset);
787
+ size = fxArgToByteLength(the, 2, -1);
788
+ if (size >= 0) {
789
+ txInteger end = offset + size;
790
+ if ((info->value.bufferInfo.length < end) || (end < offset))
791
+ mxRangeError("out of range byteLength %ld", size);
792
+ }
793
+ else {
794
+ if (info->value.bufferInfo.maxLength < 0)
795
+ size = info->value.bufferInfo.length - offset;
796
+ }
797
+ mxPushSlot(mxTarget);
798
+ fxGetPrototypeFromConstructor(the, &mxDataViewPrototype);
799
+ instance = fxNewDataViewInstance(the);
800
+ mxPullSlot(mxResult);
801
+ view = instance->next;
802
+ buffer = view->next;
803
+ buffer->kind = XS_REFERENCE_KIND;
804
+ buffer->value.reference = mxArgv(0)->value.reference;
805
+ info = fxGetBufferInfo(the, buffer);
806
+ if (info->value.bufferInfo.maxLength >= 0) {
807
+ if (info->value.bufferInfo.length < offset)
808
+ mxRangeError("out of range byteOffset %ld", offset);
809
+ else if (size >= 0) {
810
+ txInteger end = offset + size;
811
+ if ((info->value.bufferInfo.length < end) || (end < offset))
812
+ mxRangeError("out of range byteLength %ld", size);
813
+ }
814
+ }
815
+ view->value.dataView.offset = offset;
816
+ view->value.dataView.size = size;
817
+ }
818
+
819
+ void fx_DataView_prototype_buffer_get(txMachine* the)
820
+ {
821
+ txSlot* instance = fxCheckDataViewInstance(the, mxThis);
822
+ txSlot* view = instance->next;
823
+ txSlot* buffer = view->next;
824
+ mxResult->kind = buffer->kind;
825
+ mxResult->value = buffer->value;
826
+ }
827
+
828
+ void fx_DataView_prototype_byteLength_get(txMachine* the)
829
+ {
830
+ txSlot* instance = fxCheckDataViewInstance(the, mxThis);
831
+ txSlot* view = instance->next;
832
+ txSlot* buffer = view->next;
833
+ txInteger size = fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
834
+ mxResult->kind = XS_INTEGER_KIND;
835
+ mxResult->value.integer = size;
836
+ }
837
+
838
+ void fx_DataView_prototype_byteOffset_get(txMachine* the)
839
+ {
840
+ txSlot* instance = fxCheckDataViewInstance(the, mxThis);
841
+ txSlot* view = instance->next;
842
+ txSlot* buffer = view->next;
843
+ fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
844
+ mxResult->kind = XS_INTEGER_KIND;
845
+ mxResult->value.integer = view->value.dataView.offset;
846
+ }
847
+
848
+ void fx_DataView_prototype_get(txMachine* the, txNumber delta, txTypeCallback getter)
849
+ {
850
+ txSlot* instance = fxCheckDataViewInstance(the, mxThis);
851
+ txSlot* view = instance->next;
852
+ txSlot* buffer = view->next;
853
+ txInteger offset = fxArgToByteLength(the, 0, 0);
854
+ txInteger size;
855
+ int endian = EndianBig;
856
+ if ((mxArgc > 1) && fxToBoolean(the, mxArgv(1)))
857
+ endian = EndianLittle;
858
+ size = fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
859
+ if ((size < delta) || ((size - delta) < offset))
860
+ mxRangeError("out of range byteOffset");
861
+ offset += view->value.dataView.offset;
862
+ (*getter)(the, buffer->value.reference->next, offset, mxResult, endian);
863
+ }
864
+
865
+ void fx_DataView_prototype_getBigInt64(txMachine* the)
866
+ {
867
+ fx_DataView_prototype_get(the, 8, fxBigInt64Getter);
868
+ }
869
+
870
+ void fx_DataView_prototype_getBigUint64(txMachine* the)
871
+ {
872
+ fx_DataView_prototype_get(the, 8, fxBigUint64Getter);
873
+ }
874
+
875
+ void fx_DataView_prototype_getFloat32(txMachine* the)
876
+ {
877
+ fx_DataView_prototype_get(the, 4, fxFloat32Getter);
878
+ }
879
+
880
+ void fx_DataView_prototype_getFloat64(txMachine* the)
881
+ {
882
+ fx_DataView_prototype_get(the, 8, fxFloat64Getter);
883
+ }
884
+
885
+ void fx_DataView_prototype_getInt8(txMachine* the)
886
+ {
887
+ fx_DataView_prototype_get(the, 1, fxInt8Getter);
888
+ }
889
+
890
+ void fx_DataView_prototype_getInt16(txMachine* the)
891
+ {
892
+ fx_DataView_prototype_get(the, 2, fxInt16Getter);
893
+ }
894
+
895
+ void fx_DataView_prototype_getInt32(txMachine* the)
896
+ {
897
+ fx_DataView_prototype_get(the, 4, fxInt32Getter);
898
+ }
899
+
900
+ void fx_DataView_prototype_getUint8(txMachine* the)
901
+ {
902
+ fx_DataView_prototype_get(the, 1, fxUint8Getter);
903
+ }
904
+
905
+ void fx_DataView_prototype_getUint16(txMachine* the)
906
+ {
907
+ fx_DataView_prototype_get(the, 2, fxUint16Getter);
908
+ }
909
+
910
+ void fx_DataView_prototype_getUint32(txMachine* the)
911
+ {
912
+ fx_DataView_prototype_get(the, 4, fxUint32Getter);
913
+ }
914
+
915
+ void fx_DataView_prototype_set(txMachine* the, txNumber delta, txTypeCoerce coercer, txTypeCallback setter)
916
+ {
917
+ txSlot* instance = fxCheckDataViewInstance(the, mxThis);
918
+ txSlot* view = instance->next;
919
+ txSlot* buffer = view->next;
920
+ txInteger offset = fxArgToByteLength(the, 0, 0);
921
+ txInteger size;
922
+ int endian = EndianBig;
923
+ txSlot* value;
924
+ if (mxArgc > 1)
925
+ mxPushSlot(mxArgv(1));
926
+ else
927
+ mxPushUndefined();
928
+ value = the->stack;
929
+ (*coercer)(the, value);
930
+ if ((mxArgc > 2) && fxToBoolean(the, mxArgv(2)))
931
+ endian = EndianLittle;
932
+ size = fxCheckDataViewSize(the, view, buffer, XS_MUTABLE);
933
+ if ((size < delta) || ((size - delta) < offset))
934
+ mxRangeError("out of range byteOffset");
935
+ offset += view->value.dataView.offset;
936
+ (*setter)(the, buffer->value.reference->next, offset, value, endian);
937
+ mxPop();
938
+ }
939
+
940
+ void fx_DataView_prototype_setBigInt64(txMachine* the)
941
+ {
942
+ fx_DataView_prototype_set(the, 8, fxBigIntCoerce, fxBigInt64Setter);
943
+ }
944
+
945
+ void fx_DataView_prototype_setBigUint64(txMachine* the)
946
+ {
947
+ fx_DataView_prototype_set(the, 8, fxBigIntCoerce, fxBigUint64Setter);
948
+ }
949
+
950
+ void fx_DataView_prototype_setFloat32(txMachine* the)
951
+ {
952
+ fx_DataView_prototype_set(the, 4, fxNumberCoerce, fxFloat32Setter);
953
+ }
954
+
955
+ void fx_DataView_prototype_setFloat64(txMachine* the)
956
+ {
957
+ fx_DataView_prototype_set(the, 8, fxNumberCoerce, fxFloat64Setter);
958
+ }
959
+
960
+ void fx_DataView_prototype_setInt8(txMachine* the)
961
+ {
962
+ fx_DataView_prototype_set(the, 1, fxIntCoerce, fxInt8Setter);
963
+ }
964
+
965
+ void fx_DataView_prototype_setInt16(txMachine* the)
966
+ {
967
+ fx_DataView_prototype_set(the, 2, fxIntCoerce, fxInt16Setter);
968
+ }
969
+
970
+ void fx_DataView_prototype_setInt32(txMachine* the)
971
+ {
972
+ fx_DataView_prototype_set(the, 4, fxIntCoerce, fxInt32Setter);
973
+ }
974
+
975
+ void fx_DataView_prototype_setUint8(txMachine* the)
976
+ {
977
+ fx_DataView_prototype_set(the, 1, fxUintCoerce, fxUint8Setter);
978
+ }
979
+
980
+ void fx_DataView_prototype_setUint16(txMachine* the)
981
+ {
982
+ fx_DataView_prototype_set(the, 2, fxUintCoerce, fxUint16Setter);
983
+ }
984
+
985
+ void fx_DataView_prototype_setUint32(txMachine* the)
986
+ {
987
+ fx_DataView_prototype_set(the, 4, fxUintCoerce, fxUint32Setter);
988
+ }
989
+
990
+
991
+ #define mxTypedArrayDeclarations \
992
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis); \
993
+ txSlot* dispatch = instance->next; \
994
+ txSlot* view = dispatch->next; \
995
+ txSlot* buffer = view->next; \
996
+ txInteger length = fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE) >> dispatch->value.typedArray.dispatch->shift
997
+
998
+ #define mxMutableTypedArrayDeclarations \
999
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis); \
1000
+ txSlot* dispatch = instance->next; \
1001
+ txSlot* view = dispatch->next; \
1002
+ txSlot* buffer = view->next; \
1003
+ txInteger length = fxCheckDataViewSize(the, view, buffer, XS_MUTABLE) >> dispatch->value.typedArray.dispatch->shift
1004
+
1005
+ #define mxResultTypedArrayDeclarations \
1006
+ txSlot* resultInstance = fxCheckTypedArrayInstance(the, mxResult); \
1007
+ txSlot* resultDispatch = resultInstance->next; \
1008
+ txSlot* resultView = resultDispatch->next; \
1009
+ txSlot* resultBuffer = resultView->next; \
1010
+ txInteger resultLength = fxCheckDataViewSize(the, resultView, resultBuffer, XS_MUTABLE) >> resultDispatch->value.typedArray.dispatch->shift
1011
+
1012
+ void fxTypedArrayGetter(txMachine* the)
1013
+ {
1014
+ txSlot* instance = fxToInstance(the, mxThis);
1015
+ txSlot* dispatch;
1016
+ while (instance) {
1017
+ if (instance->flag & XS_EXOTIC_FLAG) {
1018
+ dispatch = instance->next;
1019
+ if (dispatch->ID == XS_TYPED_ARRAY_BEHAVIOR)
1020
+ break;
1021
+ }
1022
+ instance = fxGetPrototype(the, instance);
1023
+ }
1024
+ if (instance) {
1025
+ txID id = the->scratch.value.at.id;
1026
+ txIndex index = the->scratch.value.at.index;
1027
+ txSlot* view = dispatch->next;
1028
+ txSlot* buffer = view->next;
1029
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1030
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1031
+ if ((!id) && (index < length)) {
1032
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, view->value.dataView.offset + (index << shift), mxResult, EndianNative);
1033
+ }
1034
+ }
1035
+ }
1036
+
1037
+ void fxTypedArraySetter(txMachine* the)
1038
+ {
1039
+ txSlot* instance = fxToInstance(the, mxThis);
1040
+ txSlot* dispatch;
1041
+ while (instance) {
1042
+ if (instance->flag & XS_EXOTIC_FLAG) {
1043
+ dispatch = instance->next;
1044
+ if (dispatch->ID == XS_TYPED_ARRAY_BEHAVIOR)
1045
+ break;
1046
+ }
1047
+ instance = fxGetPrototype(the, instance);
1048
+ }
1049
+ if (instance) {
1050
+ txSlot* slot = mxArgv(0);
1051
+ txID id = the->scratch.value.at.id;
1052
+ txIndex index = the->scratch.value.at.index;
1053
+ txSlot* view = dispatch->next;
1054
+ txSlot* buffer = view->next;
1055
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1056
+ txSlot* arrayBuffer = buffer->value.reference->next;
1057
+ txIndex length;
1058
+ dispatch->value.typedArray.dispatch->coerce(the, slot);
1059
+ if (arrayBuffer->flag & XS_DONT_SET_FLAG)
1060
+ mxTypeError("read-only buffer");
1061
+ length = fxGetDataViewSize(the, view, buffer) >> shift;
1062
+ if ((!id) && (index < length)) {
1063
+ (*dispatch->value.typedArray.dispatch->setter)(the, arrayBuffer, view->value.dataView.offset + (index << shift), slot, EndianNative);
1064
+ }
1065
+ }
1066
+ }
1067
+
1068
+ txBoolean fxTypedArrayDefineOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* slot, txFlag mask)
1069
+ {
1070
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1071
+ txSlot* dispatch = instance->next;
1072
+ txSlot* view = dispatch->next;
1073
+ txSlot* buffer = view->next;
1074
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1075
+ txSlot* arrayBuffer = buffer->value.reference->next;
1076
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1077
+ if (id || (index >= length))
1078
+ return 0;
1079
+ if ((mask & XS_DONT_DELETE_FLAG) && (slot->flag & XS_DONT_DELETE_FLAG))
1080
+ return 0;
1081
+ if ((mask & XS_DONT_ENUM_FLAG) && (slot->flag & XS_DONT_ENUM_FLAG))
1082
+ return 0;
1083
+ if (mask & XS_ACCESSOR_FLAG)
1084
+ return 0;
1085
+ if ((mask & XS_DONT_SET_FLAG) && (slot->flag & XS_DONT_SET_FLAG))
1086
+ return 0;
1087
+ if (slot->kind != XS_UNINITIALIZED_KIND) {
1088
+ dispatch->value.typedArray.dispatch->coerce(the, slot);
1089
+ if (arrayBuffer->flag & XS_DONT_SET_FLAG)
1090
+ mxTypeError("read-only buffer");
1091
+ length = fxGetDataViewSize(the, view, buffer) >> shift;
1092
+ if (index < length)
1093
+ (*dispatch->value.typedArray.dispatch->setter)(the, arrayBuffer, view->value.dataView.offset + (index << shift), slot, EndianNative);
1094
+ }
1095
+ return 1;
1096
+ }
1097
+ return fxOrdinaryDefineOwnProperty(the, instance, id, index, slot, mask);
1098
+ }
1099
+
1100
+ txBoolean fxTypedArrayDeleteProperty(txMachine* the, txSlot* instance, txID id, txIndex index)
1101
+ {
1102
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1103
+ txSlot* dispatch = instance->next;
1104
+ txSlot* view = dispatch->next;
1105
+ txSlot* buffer = view->next;
1106
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1107
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1108
+ return ((!id) && (index < length)) ? 0 : 1;
1109
+ }
1110
+ return fxOrdinaryDeleteProperty(the, instance, id, index);
1111
+ }
1112
+
1113
+ txBoolean fxTypedArrayGetOwnProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* slot)
1114
+ {
1115
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1116
+ txSlot* dispatch = instance->next;
1117
+ txSlot* view = dispatch->next;
1118
+ txSlot* buffer = view->next;
1119
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1120
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1121
+ if ((!id) && (index < length)) {
1122
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, view->value.dataView.offset + (index << shift), slot, EndianNative);
1123
+ return 1;
1124
+ }
1125
+ slot->kind = XS_UNDEFINED_KIND;
1126
+ slot->flag = XS_NO_FLAG;
1127
+ return 0;
1128
+ }
1129
+ return fxOrdinaryGetOwnProperty(the, instance, id, index, slot);
1130
+ }
1131
+
1132
+ txSlot* fxTypedArrayGetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
1133
+ {
1134
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1135
+ the->scratch.value.at.id = id;
1136
+ the->scratch.value.at.index = index;
1137
+ return &mxTypedArrayAccessor;
1138
+ }
1139
+ return fxOrdinaryGetProperty(the, instance, id, index, flag);
1140
+ }
1141
+
1142
+ txBoolean fxTypedArrayGetPropertyValue(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* receiver, txSlot* value)
1143
+ {
1144
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1145
+ txSlot* dispatch = instance->next;
1146
+ txSlot* view = dispatch->next;
1147
+ txSlot* buffer = view->next;
1148
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1149
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1150
+ if ((!id) && (index < length)) {
1151
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, view->value.dataView.offset + (index << shift), value, EndianNative);
1152
+ return 1;
1153
+ }
1154
+ value->kind = XS_UNDEFINED_KIND;
1155
+ return 0;
1156
+ }
1157
+ return fxOrdinaryGetPropertyValue(the, instance, id, index, receiver, value);
1158
+ }
1159
+
1160
+ txBoolean fxTypedArrayHasProperty(txMachine* the, txSlot* instance, txID id, txIndex index)
1161
+ {
1162
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1163
+ txSlot* dispatch = instance->next;
1164
+ txSlot* view = dispatch->next;
1165
+ txSlot* buffer = view->next;
1166
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1167
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1168
+ return ((!id) && (index < length)) ? 1 : 0;
1169
+ }
1170
+ return fxOrdinaryHasProperty(the, instance, id, index);
1171
+ }
1172
+
1173
+ void fxTypedArrayOwnKeys(txMachine* the, txSlot* instance, txFlag flag, txSlot* keys)
1174
+ {
1175
+ if (flag & XS_EACH_NAME_FLAG) {
1176
+ txSlot* dispatch = instance->next;
1177
+ txSlot* view = dispatch->next;
1178
+ txSlot* buffer = view->next;
1179
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1180
+ txIndex length = fxGetDataViewSize(the, view, buffer) >> shift;
1181
+ if (length) {
1182
+ txIndex index;
1183
+ for (index = 0; index < length; index++)
1184
+ keys = fxQueueKey(the, 0, index, keys);
1185
+ }
1186
+ }
1187
+ fxOrdinaryOwnKeys(the, instance, flag, keys);
1188
+ }
1189
+
1190
+ txSlot* fxTypedArraySetProperty(txMachine* the, txSlot* instance, txID id, txIndex index, txFlag flag)
1191
+ {
1192
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1193
+ the->scratch.value.at.id = id;
1194
+ the->scratch.value.at.index = index;
1195
+ return &mxTypedArrayAccessor;
1196
+ }
1197
+ return fxOrdinarySetProperty(the, instance, id, index, flag);
1198
+ }
1199
+
1200
+ txBoolean fxTypedArraySetPropertyValue(txMachine* the, txSlot* instance, txID id, txIndex index, txSlot* value, txSlot* receiver)
1201
+ {
1202
+ if ((!id) || fxIsCanonicalIndex(the, id)) {
1203
+ txSlot* dispatch = instance->next;
1204
+ txSlot* view = dispatch->next;
1205
+ txSlot* buffer = view->next;
1206
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1207
+ txSlot* arrayBuffer = buffer->value.reference->next;
1208
+ txIndex length;
1209
+ dispatch->value.typedArray.dispatch->coerce(the, value);
1210
+ if (arrayBuffer->flag & XS_DONT_SET_FLAG)
1211
+ mxTypeError("read-only buffer");
1212
+ length = fxGetDataViewSize(the, view, buffer) >> shift;
1213
+ if ((!id) && (index < length)) {
1214
+ (*dispatch->value.typedArray.dispatch->setter)(the, buffer->value.reference->next, view->value.dataView.offset + (index << shift), value, EndianNative);
1215
+ }
1216
+ return 1;
1217
+ }
1218
+ return fxOrdinarySetPropertyValue(the, instance, id, index, value, receiver);
1219
+ }
1220
+
1221
+ void fxCallTypedArrayItem(txMachine* the, txSlot* function, txSlot* dispatch, txSlot* view, txSlot* data, txInteger index, txSlot* item)
1222
+ {
1223
+ /* THIS */
1224
+ if (mxArgc > 1)
1225
+ mxPushSlot(mxArgv(1));
1226
+ else
1227
+ mxPushUndefined();
1228
+ /* FUNCTION */
1229
+ mxPushSlot(function);
1230
+ mxCall();
1231
+ /* ARGUMENTS */
1232
+ mxPushSlot(mxThis);
1233
+ mxGetIndex(index);
1234
+ if (item) {
1235
+ item->kind = the->stack->kind;
1236
+ item->value = the->stack->value;
1237
+ }
1238
+ mxPushInteger(index);
1239
+ mxPushSlot(mxThis);
1240
+ mxRunCount(3);
1241
+ }
1242
+
1243
+ txSlot* fxCheckTypedArrayInstance(txMachine* the, txSlot* slot)
1244
+ {
1245
+ if (slot->kind == XS_REFERENCE_KIND) {
1246
+ txSlot* instance = slot->value.reference;
1247
+ if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_TYPED_ARRAY_KIND))
1248
+ return instance;
1249
+ }
1250
+ mxTypeError("this is no TypedArray instance");
1251
+ return C_NULL;
1252
+ }
1253
+
1254
+ txSlot* fxConstructTypedArray(txMachine* the)
1255
+ {
1256
+ txSlot* prototype;
1257
+ txSlot* dispatch;
1258
+ txSlot* instance;
1259
+ if (mxIsUndefined(mxTarget))
1260
+ mxTypeError("call: TypedArray");
1261
+ dispatch = mxFunctionInstanceHome(mxFunction->value.reference);
1262
+ dispatch = dispatch->next;
1263
+ prototype = mxBehaviorGetProperty(the, mxFunction->value.reference, mxID(_prototype), 0, XS_ANY);
1264
+ if (!dispatch || (dispatch->kind != XS_TYPED_ARRAY_KIND))
1265
+ mxTypeError("new: TypedArray");
1266
+ mxPushSlot(mxTarget);
1267
+ fxGetPrototypeFromConstructor(the, prototype);
1268
+ instance = fxNewTypedArrayInstance(the, dispatch->value.typedArray.dispatch, dispatch->value.typedArray.atomics);
1269
+ mxPullSlot(mxResult);
1270
+ return instance;
1271
+ }
1272
+
1273
+ void fxCreateTypedArraySpecies(txMachine* the)
1274
+ {
1275
+ txSlot* instance = fxToInstance(the, mxThis);
1276
+ txSlot* dispatch = instance->next;
1277
+ txSlot* constructor = &the->stackPrototypes[-1 - (txInteger)dispatch->value.typedArray.dispatch->constructorID];
1278
+ mxPushSlot(mxThis);
1279
+ mxGetID(mxID(_constructor));
1280
+ fxToSpeciesConstructor(the, constructor);
1281
+ mxNew();
1282
+ }
1283
+
1284
+ txSlot* fxGetTypedArrayValue(txMachine* the, txSlot* instance, txInteger index)
1285
+ {
1286
+ txSlot* dispatch = instance->next;
1287
+ txSlot* view = dispatch->next;
1288
+ txSlot* buffer = view->next;
1289
+ txSlot* data = mxIsReference(buffer) ? fxCheckArrayBufferDetached(the, buffer, XS_IMMUTABLE) : C_NULL;
1290
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1291
+ index <<= shift;
1292
+ if ((0 <= index) && ((index + (1 << shift)) <= view->value.dataView.size)) {
1293
+ (*dispatch->value.typedArray.dispatch->getter)(the, data, view->value.dataView.offset + index, &(the->scratch), EndianNative);
1294
+ return &the->scratch;
1295
+ }
1296
+ return C_NULL;
1297
+ }
1298
+
1299
+ void fxReduceTypedArrayItem(txMachine* the, txSlot* function, txSlot* dispatch, txSlot* view, txSlot* data, txInteger index)
1300
+ {
1301
+ /* THIS */
1302
+ mxPushUndefined();
1303
+ /* FUNCTION */
1304
+ mxPushSlot(function);
1305
+ mxCall();
1306
+ /* ARGUMENTS */
1307
+ mxPushSlot(mxResult);
1308
+ mxPushSlot(mxThis);
1309
+ mxGetIndex(index);
1310
+ mxPushInteger(index);
1311
+ mxPushSlot(mxThis);
1312
+ mxRunCount(4);
1313
+ mxPullSlot(mxResult);
1314
+ }
1315
+
1316
+ txSlot* fxNewTypedArrayInstance(txMachine* the, txTypeDispatch* dispatch, txTypeAtomics* atomics)
1317
+ {
1318
+ txSlot* instance;
1319
+ txSlot* property;
1320
+ instance = fxNewObjectInstance(the);
1321
+ instance->flag |= XS_EXOTIC_FLAG;
1322
+ property = fxNextTypeDispatchProperty(the, instance, dispatch, atomics, XS_TYPED_ARRAY_BEHAVIOR, XS_INTERNAL_FLAG);
1323
+ property = property->next = fxNewSlot(the);
1324
+ property->flag = XS_INTERNAL_FLAG;
1325
+ property->kind = XS_DATA_VIEW_KIND;
1326
+ property->value.dataView.offset = 0;
1327
+ property->value.dataView.size = 0;
1328
+ property = fxNextNullProperty(the, property, XS_NO_ID, XS_INTERNAL_FLAG);
1329
+ return instance;
1330
+ }
1331
+
1332
+ void fx_TypedArray(txMachine* the)
1333
+ {
1334
+ txSlot* instance = fxConstructTypedArray(the);
1335
+ txSlot* dispatch = instance->next;
1336
+ txSlot* view = dispatch->next;
1337
+ txSlot* buffer = view->next;
1338
+ txSlot* data = C_NULL;
1339
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
1340
+ txSlot* slot;
1341
+ if ((mxArgc > 0) && (mxArgv(0)->kind == XS_REFERENCE_KIND)) {
1342
+ slot = mxArgv(0)->value.reference->next;
1343
+ if (slot && ((slot->kind == XS_ARRAY_BUFFER_KIND) || (slot->kind == XS_HOST_KIND))) {
1344
+ txInteger offset = fxArgToByteLength(the, 1, 0);
1345
+ txInteger size;
1346
+ txSlot* info;
1347
+ if (offset & ((1 << shift) - 1))
1348
+ mxRangeError("invalid byteOffset %ld", offset);
1349
+ size = fxArgToByteLength(the, 2, -1);
1350
+ info = fxGetBufferInfo(the, mxArgv(0));
1351
+ if (size >= 0) {
1352
+ txInteger delta = size << shift;
1353
+ txInteger end = fxAddChunkSizes(the, offset, delta);
1354
+ if ((info->value.bufferInfo.length < end) || (end < offset))
1355
+ mxRangeError("out of range length %ld", size);
1356
+ size = delta;
1357
+ }
1358
+ else {
1359
+ if (info->value.bufferInfo.length & ((1 << shift) - 1))
1360
+ mxRangeError("invalid byteLength %ld", info->value.bufferInfo.length);
1361
+ size = info->value.bufferInfo.length - offset;
1362
+ if (size < 0)
1363
+ mxRangeError("out of range byteLength %ld", size);
1364
+ if (info->value.bufferInfo.maxLength >= 0)
1365
+ size = -1;
1366
+ }
1367
+ view->value.dataView.offset = offset;
1368
+ view->value.dataView.size = size;
1369
+ buffer->kind = XS_REFERENCE_KIND;
1370
+ buffer->value.reference = mxArgv(0)->value.reference;
1371
+ }
1372
+ else if (slot && (slot->kind == XS_TYPED_ARRAY_KIND)) {
1373
+ txSlot* sourceDispatch = slot;
1374
+ txSlot* sourceView = sourceDispatch->next;
1375
+ txSlot* sourceBuffer = sourceView->next;
1376
+ txU2 sourceShift = sourceDispatch->value.typedArray.dispatch->shift;
1377
+ txInteger sourceLength = fxCheckDataViewSize(the, sourceView, sourceBuffer, XS_IMMUTABLE) >> sourceShift;
1378
+ txSlot* sourceData = sourceBuffer->value.reference->next;
1379
+ txInteger sourceDelta = sourceDispatch->value.typedArray.dispatch->size;
1380
+ txInteger sourceOffset = sourceView->value.dataView.offset;
1381
+ txInteger offset = 0;
1382
+ txInteger size = sourceLength << shift;
1383
+ /* THIS */
1384
+ mxPushUninitialized();
1385
+ /* FUNCTION */
1386
+ mxPush(mxArrayBufferConstructor);
1387
+ /* TARGET */
1388
+ mxPush(mxArrayBufferConstructor);
1389
+ /* RESULT */
1390
+ mxPushUndefined();
1391
+ mxPushUninitialized();
1392
+ mxPushUninitialized();
1393
+ /* ARGUMENTS */
1394
+ sourceLength = fxGetDataViewSize(the, sourceView, sourceBuffer) >> sourceShift;
1395
+ size = sourceLength << shift;
1396
+ mxPushInteger(size);
1397
+ mxRunCount(1);
1398
+ mxPullSlot(buffer);
1399
+ sourceLength = fxCheckDataViewSize(the, sourceView, sourceBuffer, XS_IMMUTABLE) >> sourceShift;
1400
+ size = sourceLength << shift;
1401
+
1402
+ data = fxCheckArrayBufferDetached(the, buffer, XS_MUTABLE);
1403
+ view->value.dataView.offset = offset;
1404
+ view->value.dataView.size = size;
1405
+ if (dispatch == sourceDispatch)
1406
+ c_memcpy(data->value.arrayBuffer.address + offset, sourceData->value.arrayBuffer.address + sourceOffset, size);
1407
+ else {
1408
+ txBoolean contentType = (dispatch->value.typedArray.dispatch->constructorID == _BigInt64Array)
1409
+ || (dispatch->value.typedArray.dispatch->constructorID == _BigUint64Array);
1410
+ txBoolean sourceContentType = (sourceDispatch->value.typedArray.dispatch->constructorID == _BigInt64Array)
1411
+ || (sourceDispatch->value.typedArray.dispatch->constructorID == _BigUint64Array);
1412
+ if (contentType != sourceContentType)
1413
+ mxTypeError("incompatible content type");
1414
+ mxPushUndefined();
1415
+ while (offset < size) {
1416
+ (*sourceDispatch->value.typedArray.dispatch->getter)(the, sourceData, sourceOffset, the->stack, EndianNative);
1417
+ (*dispatch->value.typedArray.dispatch->coerce)(the, the->stack);
1418
+ (*dispatch->value.typedArray.dispatch->setter)(the, data, offset, the->stack, EndianNative);
1419
+ sourceOffset += sourceDelta;
1420
+ offset += 1 << shift;
1421
+ }
1422
+ mxPop();
1423
+ }
1424
+ }
1425
+ else {
1426
+ fx_TypedArray_from_object(the, instance, C_NULL, C_NULL);
1427
+ }
1428
+ }
1429
+ else {
1430
+ txInteger length = fxArgToByteLength(the, 0, 0);
1431
+ if (length > (0x7FFFFFFF >> shift))
1432
+ mxRangeError("out of range byteLength");
1433
+ length <<= shift;
1434
+ mxPush(mxArrayBufferConstructor);
1435
+ mxNew();
1436
+ mxPushInteger(length);
1437
+ mxRunCount(1);
1438
+ mxPullSlot(buffer);
1439
+ view->value.dataView.offset = 0;
1440
+ view->value.dataView.size = length;
1441
+ }
1442
+ }
1443
+
1444
+ void fx_TypedArray_from(txMachine* the)
1445
+ {
1446
+ txSlot* function = C_NULL;
1447
+ txSlot* _this = C_NULL;
1448
+ if (!mxIsReference(mxThis) || !(mxIsConstructor(mxThis->value.reference)))
1449
+ mxTypeError("this is no constructor");
1450
+ if (mxArgc > 1) {
1451
+ txSlot* slot = mxArgv(1);
1452
+ if (!mxIsUndefined(slot)) {
1453
+ function = slot;
1454
+ if (!fxIsCallable(the, function))
1455
+ mxTypeError("map is no function");
1456
+ if (mxArgc > 2)
1457
+ _this = mxArgv(2);
1458
+ }
1459
+ }
1460
+ fx_TypedArray_from_object(the, C_NULL, function, _this);
1461
+ }
1462
+
1463
+ void fx_TypedArray_from_object(txMachine* the, txSlot* instance, txSlot* function, txSlot* _this)
1464
+ {
1465
+ txSlot* stack = the->stack;
1466
+ txSlot* iterator;
1467
+ txSlot* next;
1468
+ txSlot* value;
1469
+ txSlot* list = C_NULL;
1470
+ txSlot* slot;
1471
+ txSlot* dispatch;
1472
+ txSlot* view;
1473
+ txSlot* buffer;
1474
+ txSlot* data;
1475
+ txU2 shift;
1476
+ txNumber length;
1477
+ mxTemporary(iterator);
1478
+ mxTemporary(next);
1479
+ if (fxGetIterator(the, mxArgv(0), iterator, next, 1)) {
1480
+ list = fxNewInstance(the);
1481
+ slot = list;
1482
+ length = 0;
1483
+ mxTemporary(value);
1484
+ while (fxIteratorNext(the, iterator, next, value)) {
1485
+ slot = fxNextSlotProperty(the, slot, value, XS_NO_ID, XS_NO_FLAG);
1486
+ length++;
1487
+ }
1488
+ }
1489
+ else {
1490
+ mxPushSlot(mxArgv(0));
1491
+ mxGetID(mxID(_length));
1492
+ length = fxToLength(the, the->stack);
1493
+ mxPop();
1494
+ }
1495
+ if (instance) {
1496
+ dispatch = instance->next;
1497
+ view = dispatch->next;
1498
+ buffer = view->next;
1499
+ shift = dispatch->value.typedArray.dispatch->shift;
1500
+ mxPush(mxArrayBufferConstructor);
1501
+ mxNew();
1502
+ mxPushNumber(length * dispatch->value.typedArray.dispatch->size);
1503
+ mxRunCount(1);
1504
+ mxPullSlot(buffer);
1505
+ data = fxCheckArrayBufferDetached(the, buffer, XS_MUTABLE);
1506
+ view->value.dataView.offset = 0;
1507
+ view->value.dataView.size = data->next->value.bufferInfo.length;
1508
+ }
1509
+ else {
1510
+ mxPushSlot(mxThis);
1511
+ mxNew();
1512
+ mxPushNumber(length);
1513
+ mxRunCount(1);
1514
+ mxPullSlot(mxResult);
1515
+ instance = fxToInstance(the, mxResult);
1516
+ if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_TYPED_ARRAY_KIND)) {
1517
+ dispatch = instance->next;
1518
+ view = dispatch->next;
1519
+ buffer = view->next;
1520
+ data = fxCheckArrayBufferDetached(the, buffer, XS_MUTABLE);
1521
+ shift = dispatch->value.typedArray.dispatch->shift;
1522
+ if (view->value.dataView.size < (length * dispatch->value.typedArray.dispatch->size))
1523
+ mxTypeError("too small TypedArray");
1524
+ }
1525
+ else
1526
+ mxTypeError("no TypedArray");
1527
+ }
1528
+ if (list) {
1529
+ txInteger index = 0;
1530
+ slot = list->next;
1531
+ while (slot) {
1532
+ /* ARG0 */
1533
+ if (function) {
1534
+ /* THIS */
1535
+ if (_this)
1536
+ mxPushSlot(_this);
1537
+ else
1538
+ mxPushUndefined();
1539
+ /* FUNCTION */
1540
+ mxPushSlot(function);
1541
+ mxCall();
1542
+ /* ARGUMENTS */
1543
+ mxPushSlot(slot);
1544
+ mxPushInteger(index);
1545
+ mxRunCount(2);
1546
+ }
1547
+ else
1548
+ mxPushSlot(slot);
1549
+ (*dispatch->value.typedArray.dispatch->coerce)(the, the->stack);
1550
+ (*dispatch->value.typedArray.dispatch->setter)(the, data, (index << shift), the->stack, EndianNative);
1551
+ mxPop();
1552
+ index++;
1553
+ slot = slot->next;
1554
+ }
1555
+ }
1556
+ else {
1557
+ txInteger index = 0;
1558
+ txInteger count = (txInteger)length;
1559
+ while (index < count) {
1560
+ if (function) {
1561
+ /* THIS */
1562
+ if (_this)
1563
+ mxPushSlot(_this);
1564
+ else
1565
+ mxPushUndefined();
1566
+ /* FUNCTION */
1567
+ mxPushSlot(function);
1568
+ mxCall();
1569
+ /* ARGUMENTS */
1570
+ mxPushSlot(mxArgv(0));
1571
+ mxGetIndex(index);
1572
+ mxPushInteger(index);
1573
+ mxRunCount(2);
1574
+ }
1575
+ else {
1576
+ mxPushSlot(mxArgv(0));
1577
+ mxGetIndex(index);
1578
+ }
1579
+ (*dispatch->value.typedArray.dispatch->coerce)(the, the->stack);
1580
+ (*dispatch->value.typedArray.dispatch->setter)(the, data, (index << shift), the->stack, EndianNative);
1581
+ mxPop();
1582
+ index++;
1583
+ }
1584
+ }
1585
+ the->stack = stack;
1586
+ }
1587
+
1588
+ void fx_TypedArray_of(txMachine* the)
1589
+ {
1590
+ txInteger count = mxArgc;
1591
+ txInteger index = 0;
1592
+ mxPushSlot(mxThis);
1593
+ mxNew();
1594
+ mxPushInteger(count);
1595
+ mxRunCount(1);
1596
+ mxPullSlot(mxResult);
1597
+ {
1598
+ mxResultTypedArrayDeclarations;
1599
+ txU2 shift = resultDispatch->value.typedArray.dispatch->shift;
1600
+ if (resultLength < count)
1601
+ mxTypeError("insufficient TypedArray");
1602
+ while (index < count) {
1603
+ (*resultDispatch->value.typedArray.dispatch->coerce)(the, mxArgv(index));
1604
+ if (resultBuffer->value.arrayBuffer.address == C_NULL)
1605
+ mxTypeError("detached buffer");
1606
+ (*resultDispatch->value.typedArray.dispatch->setter)(the, resultBuffer->value.reference->next, resultView->value.dataView.offset + (index << shift), mxArgv(index), EndianNative);
1607
+ index++;
1608
+ }
1609
+ }
1610
+ }
1611
+
1612
+ void fx_TypedArray_prototype_at(txMachine* the)
1613
+ {
1614
+ mxTypedArrayDeclarations;
1615
+ txInteger index = (mxArgc > 0) ? fxToInteger(the, mxArgv(0)) : 0;
1616
+ if (index < 0)
1617
+ index = length + index;
1618
+ if ((0 <= index) && (index < length)) {
1619
+ mxPushSlot(mxThis);
1620
+ mxGetIndex(index);
1621
+ mxPullSlot(mxResult);
1622
+ }
1623
+ }
1624
+
1625
+ void fx_TypedArray_prototype_buffer_get(txMachine* the)
1626
+ {
1627
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
1628
+ txSlot* dispatch = instance->next;
1629
+ txSlot* view = dispatch->next;
1630
+ txSlot* buffer = view->next;
1631
+ mxResult->kind = buffer->kind;
1632
+ mxResult->value = buffer->value;
1633
+ }
1634
+
1635
+ void fx_TypedArray_prototype_byteLength_get(txMachine* the)
1636
+ {
1637
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
1638
+ txSlot* dispatch = instance->next;
1639
+ txSlot* view = dispatch->next;
1640
+ txSlot* buffer = view->next;
1641
+ mxResult->kind = XS_INTEGER_KIND;
1642
+ mxResult->value.integer = fxGetDataViewSize(the, view, buffer);
1643
+ }
1644
+
1645
+ void fx_TypedArray_prototype_byteOffset_get(txMachine* the)
1646
+ {
1647
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
1648
+ txSlot* dispatch = instance->next;
1649
+ txSlot* view = dispatch->next;
1650
+ txSlot* buffer = view->next;
1651
+ txInteger offset = view->value.dataView.offset;
1652
+ txInteger size = view->value.dataView.size;
1653
+ txSlot* arrayBuffer = buffer->value.reference->next;
1654
+ txSlot* bufferInfo = arrayBuffer->next;
1655
+ mxResult->kind = XS_INTEGER_KIND;
1656
+ mxResult->value.integer = 0;
1657
+ if (arrayBuffer->value.arrayBuffer.address == C_NULL)
1658
+ return;
1659
+ if (bufferInfo->value.bufferInfo.maxLength >= 0) {
1660
+ txInteger byteLength = bufferInfo->value.bufferInfo.length;
1661
+ if (offset > byteLength)
1662
+ return;
1663
+ size = (size < 0) ? byteLength : offset + size;
1664
+ if (size > byteLength)
1665
+ return;
1666
+ size -= offset;
1667
+ }
1668
+ mxResult->value.integer = offset;
1669
+ }
1670
+
1671
+ void fx_TypedArray_prototype_copyWithin(txMachine* the)
1672
+ {
1673
+ mxMutableTypedArrayDeclarations;
1674
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
1675
+ txInteger target = (txInteger)fxArgToIndex(the, 0, 0, length);
1676
+ txInteger start = (txInteger)fxArgToIndex(the, 1, 0, length);
1677
+ txInteger end = (txInteger)fxArgToIndex(the, 2, length, length);
1678
+ txInteger count = end - start;
1679
+ fxCheckArrayBufferDetached(the, buffer, XS_MUTABLE);
1680
+ if (count > length - target)
1681
+ count = length - target;
1682
+ if (count > 0) {
1683
+ txByte* address = buffer->value.reference->next->value.arrayBuffer.address + view->value.dataView.offset;
1684
+ c_memmove(address + (target * delta), address + (start * delta), count * delta);
1685
+ mxMeterSome((txU4)count * 2);
1686
+ }
1687
+ mxResult->kind = mxThis->kind;
1688
+ mxResult->value = mxThis->value;
1689
+ }
1690
+
1691
+ void fx_TypedArray_prototype_entries(txMachine* the)
1692
+ {
1693
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
1694
+ txSlot* dispatch = instance->next;
1695
+ txSlot* view = dispatch->next;
1696
+ txSlot* buffer = view->next;
1697
+ txSlot* property;
1698
+ fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
1699
+ mxPush(mxArrayIteratorPrototype);
1700
+ property = fxLastProperty(the, fxNewIteratorInstance(the, mxThis, mxID(_Array)));
1701
+ property = fxNextIntegerProperty(the, property, 2, XS_NO_ID, XS_INTERNAL_FLAG);
1702
+ mxPullSlot(mxResult);
1703
+ }
1704
+
1705
+ void fx_TypedArray_prototype_every(txMachine* the)
1706
+ {
1707
+ mxTypedArrayDeclarations;
1708
+ txSlot* function = fxArgToCallback(the, 0);
1709
+ txInteger index = 0;
1710
+ mxResult->kind = XS_BOOLEAN_KIND;
1711
+ mxResult->value.boolean = 1;
1712
+ while (index < length) {
1713
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, C_NULL);
1714
+ mxResult->value.boolean = fxToBoolean(the, the->stack++);
1715
+ if (!mxResult->value.boolean)
1716
+ break;
1717
+ index++;
1718
+ }
1719
+ }
1720
+
1721
+ void fx_TypedArray_prototype_fill(txMachine* the)
1722
+ {
1723
+ mxMutableTypedArrayDeclarations;
1724
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
1725
+ txInteger start = (txInteger)fxArgToIndex(the, 1, 0, length);
1726
+ txInteger end = (txInteger)fxArgToIndex(the, 2, length, length);
1727
+ start *= delta;
1728
+ end *= delta;
1729
+ start += view->value.dataView.offset;
1730
+ end += view->value.dataView.offset;
1731
+ if (mxArgc > 0)
1732
+ mxPushSlot(mxArgv(0));
1733
+ else
1734
+ mxPushUndefined();
1735
+ (*dispatch->value.typedArray.dispatch->coerce)(the, the->stack);
1736
+ fxCheckDataViewSize(the, view, buffer, XS_MUTABLE);
1737
+ while (start < end) {
1738
+ (*dispatch->value.typedArray.dispatch->setter)(the, buffer->value.reference->next, start, the->stack, EndianNative);
1739
+ start += delta;
1740
+ }
1741
+ mxPop();
1742
+ mxResult->kind = mxThis->kind;
1743
+ mxResult->value = mxThis->value;
1744
+ }
1745
+
1746
+ void fx_TypedArray_prototype_filter(txMachine* the)
1747
+ {
1748
+ mxTypedArrayDeclarations;
1749
+ txSlot* function = fxArgToCallback(the, 0);
1750
+ txSlot* list = fxNewInstance(the);
1751
+ txSlot* slot = list;
1752
+ txInteger count = 0;
1753
+ txInteger index = 0;
1754
+ mxPushUndefined();
1755
+ while (index < length) {
1756
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, the->stack);
1757
+ if (fxToBoolean(the, the->stack++)) {
1758
+ count++;
1759
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
1760
+ }
1761
+ index++;
1762
+ }
1763
+ mxPop();
1764
+ fxCreateTypedArraySpecies(the);
1765
+ mxPushNumber(count);
1766
+ mxRunCount(1);
1767
+ mxPullSlot(mxResult);
1768
+ {
1769
+ mxResultTypedArrayDeclarations;
1770
+ txInteger resultOffset = 0;
1771
+ txInteger resultSize = resultDispatch->value.typedArray.dispatch->size;
1772
+ if (resultLength < count)
1773
+ mxTypeError("insufficient buffer");
1774
+ slot = list->next;
1775
+ while (slot) {
1776
+ (*resultDispatch->value.typedArray.dispatch->coerce)(the, slot);
1777
+ (*resultDispatch->value.typedArray.dispatch->setter)(the, resultBuffer->value.reference->next, resultOffset, slot, EndianNative);
1778
+ resultOffset += resultSize;
1779
+ slot = slot->next;
1780
+ }
1781
+ }
1782
+ mxPop();
1783
+ }
1784
+
1785
+ void fx_TypedArray_prototype_find(txMachine* the)
1786
+ {
1787
+ mxTypedArrayDeclarations;
1788
+ txSlot* function = fxArgToCallback(the, 0);
1789
+ txInteger index = 0;
1790
+ mxPushUndefined();
1791
+ while (index < length) {
1792
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, the->stack);
1793
+ if (fxToBoolean(the, the->stack++)) {
1794
+ mxResult->kind = the->stack->kind;
1795
+ mxResult->value = the->stack->value;
1796
+ break;
1797
+ }
1798
+ index++;
1799
+ }
1800
+ mxPop();
1801
+ }
1802
+
1803
+ void fx_TypedArray_prototype_findIndex(txMachine* the)
1804
+ {
1805
+ mxTypedArrayDeclarations;
1806
+ txSlot* function = fxArgToCallback(the, 0);
1807
+ txInteger index = 0;
1808
+ mxResult->kind = XS_INTEGER_KIND;
1809
+ mxResult->value.integer = -1;
1810
+ while (index < length) {
1811
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, C_NULL);
1812
+ if (fxToBoolean(the, the->stack++)) {
1813
+ mxResult->value.integer = index;
1814
+ break;
1815
+ }
1816
+ index++;
1817
+ }
1818
+ }
1819
+
1820
+ void fx_TypedArray_prototype_findLast(txMachine* the)
1821
+ {
1822
+ mxTypedArrayDeclarations;
1823
+ txSlot* function = fxArgToCallback(the, 0);
1824
+ txInteger index = length;
1825
+ mxPushUndefined();
1826
+ while (index > 0) {
1827
+ index--;
1828
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, the->stack);
1829
+ if (fxToBoolean(the, the->stack++)) {
1830
+ mxResult->kind = the->stack->kind;
1831
+ mxResult->value = the->stack->value;
1832
+ break;
1833
+ }
1834
+ }
1835
+ mxPop();
1836
+ }
1837
+
1838
+ void fx_TypedArray_prototype_findLastIndex(txMachine* the)
1839
+ {
1840
+ mxTypedArrayDeclarations;
1841
+ txSlot* function = fxArgToCallback(the, 0);
1842
+ txInteger index = length;
1843
+ mxResult->kind = XS_INTEGER_KIND;
1844
+ mxResult->value.integer = -1;
1845
+ while (index > 0) {
1846
+ index--;
1847
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, C_NULL);
1848
+ if (fxToBoolean(the, the->stack++)) {
1849
+ mxResult->value.integer = index;
1850
+ break;
1851
+ }
1852
+ }
1853
+ }
1854
+
1855
+ void fx_TypedArray_prototype_forEach(txMachine* the)
1856
+ {
1857
+ mxTypedArrayDeclarations;
1858
+ txSlot* function = fxArgToCallback(the, 0);
1859
+ txInteger index = 0;
1860
+ while (index < length) {
1861
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, C_NULL);
1862
+ mxPop();
1863
+ index++;
1864
+ }
1865
+ }
1866
+
1867
+ void fx_TypedArray_prototype_includes(txMachine* the)
1868
+ {
1869
+ mxTypedArrayDeclarations;
1870
+ fxBoolean(the, mxResult, 0);
1871
+ if (length) {
1872
+ txInteger index = (txInteger)fxArgToIndex(the, 1, 0, length);
1873
+ txSlot* argument;
1874
+ if (mxArgc > 0)
1875
+ mxPushSlot(mxArgv(0));
1876
+ else
1877
+ mxPushUndefined();
1878
+ argument = the->stack;
1879
+ while (index < length) {
1880
+ mxPushSlot(mxThis);
1881
+ mxGetIndex(index);
1882
+ if (fxIsSameValue(the, the->stack++, argument, 1)) {
1883
+ mxResult->value.boolean = 1;
1884
+ break;
1885
+ }
1886
+ index++;
1887
+ }
1888
+ mxPop();
1889
+ }
1890
+ }
1891
+
1892
+ void fx_TypedArray_prototype_indexOf(txMachine* the)
1893
+ {
1894
+ mxTypedArrayDeclarations;
1895
+ fxInteger(the, mxResult, -1);
1896
+ if (length) {
1897
+ txInteger index = (txInteger)fxArgToIndex(the, 1, 0, length);
1898
+ txSlot* argument;
1899
+ if (mxArgc > 0)
1900
+ mxPushSlot(mxArgv(0));
1901
+ else
1902
+ mxPushUndefined();
1903
+ argument = the->stack;
1904
+ while (index < length) {
1905
+ mxPushSlot(mxThis);
1906
+ if (fxHasIndex(the, index)) {
1907
+ mxPushSlot(mxThis);
1908
+ mxGetIndex(index);
1909
+ if (fxIsSameSlot(the, the->stack++, argument)) {
1910
+ mxResult->value.integer = index;
1911
+ break;
1912
+ }
1913
+ }
1914
+ index++;
1915
+ }
1916
+ mxPop();
1917
+ }
1918
+ }
1919
+
1920
+ void fx_TypedArray_prototype_join(txMachine* the)
1921
+ {
1922
+ mxTypedArrayDeclarations;
1923
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
1924
+ txInteger offset = view->value.dataView.offset;
1925
+ txInteger limit = offset + (length << dispatch->value.typedArray.dispatch->shift);
1926
+ txString string;
1927
+ txSlot* list = fxNewInstance(the);
1928
+ txSlot* slot = list;
1929
+ txBoolean comma = 0;
1930
+ txInteger size = 0;
1931
+ if ((mxArgc > 0) && (mxArgv(0)->kind != XS_UNDEFINED_KIND)) {
1932
+ mxPushSlot(mxArgv(0));
1933
+ string = fxToString(the, the->stack);
1934
+ the->stack->kind += XS_KEY_KIND - XS_STRING_KIND;
1935
+ the->stack->value.key.sum = mxStringLength(the->stack->value.string);
1936
+ }
1937
+ else {
1938
+ mxPushStringX(",");
1939
+ the->stack->kind += XS_KEY_KIND - XS_STRING_KIND;
1940
+ the->stack->value.key.sum = 1;
1941
+ }
1942
+ length = offset + fxGetDataViewSize(the, view, buffer);
1943
+ while (offset < limit) {
1944
+ if (comma) {
1945
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
1946
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
1947
+ }
1948
+ else
1949
+ comma = 1;
1950
+ if (offset < length) {
1951
+ mxPushUndefined();
1952
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, offset, the->stack, EndianNative);
1953
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
1954
+ string = fxToString(the, slot);
1955
+ slot->kind += XS_KEY_KIND - XS_STRING_KIND;
1956
+ slot->value.key.sum = mxStringLength(string);
1957
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
1958
+ mxPop();
1959
+ }
1960
+ offset += delta;
1961
+ }
1962
+ mxPop();
1963
+ string = mxResult->value.string = fxNewChunk(the, fxAddChunkSizes(the, size, 1));
1964
+ slot = list->next;
1965
+ while (slot) {
1966
+ c_memcpy(string, slot->value.key.string, slot->value.key.sum);
1967
+ string += slot->value.key.sum;
1968
+ slot = slot->next;
1969
+ }
1970
+ *string = 0;
1971
+ mxResult->kind = XS_STRING_KIND;
1972
+ mxPop();
1973
+ }
1974
+
1975
+ void fx_TypedArray_prototype_keys(txMachine* the)
1976
+ {
1977
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
1978
+ txSlot* dispatch = instance->next;
1979
+ txSlot* view = dispatch->next;
1980
+ txSlot* buffer = view->next;
1981
+ txSlot* property;
1982
+ fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
1983
+ mxPush(mxArrayIteratorPrototype);
1984
+ property = fxLastProperty(the, fxNewIteratorInstance(the, mxThis, mxID(_Array)));
1985
+ property = fxNextIntegerProperty(the, property, 1, XS_NO_ID, XS_INTERNAL_FLAG);
1986
+ mxPullSlot(mxResult);
1987
+ }
1988
+
1989
+ void fx_TypedArray_prototype_lastIndexOf(txMachine* the)
1990
+ {
1991
+ mxTypedArrayDeclarations;
1992
+ fxInteger(the, mxResult, -1);
1993
+ if (length) {
1994
+ txIndex index = (txIndex)fxArgToLastIndex(the, 1, length, length);
1995
+ txSlot* argument;
1996
+ if (mxArgc > 0)
1997
+ mxPushSlot(mxArgv(0));
1998
+ else
1999
+ mxPushUndefined();
2000
+ argument = the->stack;
2001
+ while (index > 0) {
2002
+ index--;
2003
+ mxPushSlot(mxThis);
2004
+ if (fxHasIndex(the, index)) {
2005
+ mxPushSlot(mxThis);
2006
+ mxGetIndex(index);
2007
+ if (fxIsSameSlot(the, the->stack++, argument)) {
2008
+ mxResult->value.integer = index;
2009
+ break;
2010
+ }
2011
+ }
2012
+ }
2013
+ mxPop();
2014
+ }
2015
+ }
2016
+
2017
+ void fx_TypedArray_prototype_length_get(txMachine* the)
2018
+ {
2019
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
2020
+ txSlot* dispatch = instance->next;
2021
+ txSlot* view = dispatch->next;
2022
+ txSlot* buffer = view->next;
2023
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
2024
+ mxResult->kind = XS_INTEGER_KIND;
2025
+ mxResult->value.integer = fxGetDataViewSize(the, view, buffer) >> shift;
2026
+ }
2027
+
2028
+ void fx_TypedArray_prototype_map(txMachine* the)
2029
+ {
2030
+ mxTypedArrayDeclarations;
2031
+ txSlot* function = fxArgToCallback(the, 0);
2032
+ fxCreateTypedArraySpecies(the);
2033
+ mxPushNumber(length);
2034
+ mxRunCount(1);
2035
+ mxPullSlot(mxResult);
2036
+ {
2037
+ mxResultTypedArrayDeclarations;
2038
+ txU2 shift = resultDispatch->value.typedArray.dispatch->shift;
2039
+ txInteger index = 0;
2040
+ if (resultLength < length)
2041
+ mxTypeError("insufficient buffer");
2042
+ while (index < length) {
2043
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, C_NULL);
2044
+ if (resultBuffer->value.arrayBuffer.address == C_NULL)
2045
+ mxTypeError("detached buffer");
2046
+ (*resultDispatch->value.typedArray.dispatch->coerce)(the, the->stack);
2047
+ (*resultDispatch->value.typedArray.dispatch->setter)(the, resultBuffer->value.reference->next, resultView->value.dataView.offset + (index << shift), the->stack, EndianNative);
2048
+ mxPop();
2049
+ index++;
2050
+ }
2051
+ }
2052
+ }
2053
+
2054
+ void fx_TypedArray_prototype_reduce(txMachine* the)
2055
+ {
2056
+ mxTypedArrayDeclarations;
2057
+ txSlot* function = fxArgToCallback(the, 0);
2058
+ txInteger index = 0;
2059
+ if (mxArgc > 1)
2060
+ *mxResult = *mxArgv(1);
2061
+ else if (index < length) {
2062
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, view->value.dataView.offset, mxResult, EndianNative);
2063
+ index++;
2064
+ }
2065
+ else
2066
+ mxTypeError("no initial value");
2067
+ while (index < length) {
2068
+ fxReduceTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index);
2069
+ index++;
2070
+ }
2071
+ }
2072
+
2073
+ void fx_TypedArray_prototype_reduceRight(txMachine* the)
2074
+ {
2075
+ mxTypedArrayDeclarations;
2076
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
2077
+ txSlot* function = fxArgToCallback(the, 0);
2078
+ txInteger index = length - 1;
2079
+ if (mxArgc > 1)
2080
+ *mxResult = *mxArgv(1);
2081
+ else if (index >= 0) {
2082
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, view->value.dataView.offset + (index * delta), mxResult, EndianNative);
2083
+ index--;
2084
+ }
2085
+ else
2086
+ mxTypeError("no initial value");
2087
+ while (index >= 0) {
2088
+ fxReduceTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index);
2089
+ index--;
2090
+ }
2091
+ }
2092
+
2093
+ void fx_TypedArray_prototype_reverse(txMachine* the)
2094
+ {
2095
+ mxMutableTypedArrayDeclarations;
2096
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
2097
+ if (length) {
2098
+ txByte tmp;
2099
+ txByte* first = buffer->value.reference->next->value.arrayBuffer.address + view->value.dataView.offset;
2100
+ txByte* last = first + (length << dispatch->value.typedArray.dispatch->shift) - delta;
2101
+ txInteger offset;
2102
+ while (first < last) {
2103
+ for (offset = 0; offset < delta; offset++) {
2104
+ tmp = last[offset];
2105
+ last[offset] = first[offset];
2106
+ first[offset] = tmp;
2107
+ }
2108
+ first += delta;
2109
+ last -= delta;
2110
+ }
2111
+ mxMeterSome(length * 4);
2112
+ }
2113
+ mxResult->kind = mxThis->kind;
2114
+ mxResult->value = mxThis->value;
2115
+ }
2116
+
2117
+ void fx_TypedArray_prototype_set(txMachine* the)
2118
+ {
2119
+ mxMutableTypedArrayDeclarations;
2120
+ txSlot* data = buffer->value.reference->next;
2121
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
2122
+ txSlot* source = fxArgToInstance(the, 0);
2123
+ txInteger target = fxArgToByteLength(the, 1, 0);
2124
+ txInteger offset = view->value.dataView.offset + (target * delta);
2125
+ if (source->next && (source->next->kind == XS_TYPED_ARRAY_KIND)) {
2126
+ txSlot* sourceDispatch = source->next;
2127
+ txSlot* sourceView = sourceDispatch->next;
2128
+ txSlot* sourceBuffer = sourceView->next;
2129
+ txU2 shift = sourceDispatch->value.typedArray.dispatch->shift;
2130
+ txInteger sourceLength = fxCheckDataViewSize(the, sourceView, sourceBuffer, XS_IMMUTABLE) >> shift;
2131
+ txInteger sourceOffset = sourceView->value.dataView.offset;
2132
+ txSlot* sourceData = sourceBuffer->value.reference->next;
2133
+ txInteger limit = offset + (sourceLength * delta);
2134
+ if (/* (target < 0) || */ (length - sourceLength < target)) //@@ target can never be negative?
2135
+ mxRangeError("invalid offset");
2136
+ if (data == sourceData) {
2137
+ txSlot* resultBuffer;
2138
+ mxPush(mxArrayBufferConstructor);
2139
+ mxNew();
2140
+ mxPushInteger(sourceLength << shift);
2141
+ mxRunCount(1);
2142
+ resultBuffer = the->stack->value.reference->next;
2143
+ c_memcpy(resultBuffer->value.arrayBuffer.address, sourceData->value.arrayBuffer.address + sourceOffset, sourceLength << shift);
2144
+ sourceData = resultBuffer;
2145
+ sourceOffset = 0;
2146
+ }
2147
+ else
2148
+ mxPushUndefined();
2149
+ if (dispatch == sourceDispatch) {
2150
+ c_memcpy(data->value.arrayBuffer.address + offset, sourceData->value.arrayBuffer.address + sourceOffset, limit - offset);
2151
+ mxMeterSome(((txU4)(limit - offset)) * 2);
2152
+ }
2153
+ else {
2154
+ txInteger sourceDelta = 1 << shift;
2155
+ mxPushUndefined();
2156
+ while (offset < limit) {
2157
+ (*sourceDispatch->value.typedArray.dispatch->getter)(the, sourceData, sourceOffset, the->stack, EndianNative);
2158
+ (*dispatch->value.typedArray.dispatch->coerce)(the, the->stack);
2159
+ if (data->value.arrayBuffer.address == C_NULL)
2160
+ mxTypeError("detached buffer");
2161
+ (*dispatch->value.typedArray.dispatch->setter)(the, data, offset, the->stack, EndianNative);
2162
+ sourceOffset += sourceDelta;
2163
+ offset += delta;
2164
+ }
2165
+ mxPop();
2166
+ }
2167
+ mxPop();
2168
+ }
2169
+ else {
2170
+ txInteger count, index;
2171
+ if (data->value.arrayBuffer.address == C_NULL)
2172
+ mxTypeError("detached buffer");
2173
+ mxPushSlot(mxArgv(0));
2174
+ mxGetID(mxID(_length));
2175
+ count = fxToInteger(the, the->stack);
2176
+ mxPop();
2177
+ if (/* (target < 0) || */ (length - count < target)) //@@ target cannot be negative?
2178
+ mxRangeError("invalid offset");
2179
+ index = 0;
2180
+ while (index < count) {
2181
+ mxPushSlot(mxArgv(0));
2182
+ mxGetIndex(index);
2183
+ (*dispatch->value.typedArray.dispatch->coerce)(the, the->stack);
2184
+ if (data->value.arrayBuffer.address != C_NULL)
2185
+ (*dispatch->value.typedArray.dispatch->setter)(the, data, offset, the->stack, EndianNative);
2186
+ mxPop();
2187
+ offset += delta;
2188
+ index++;
2189
+ }
2190
+ }
2191
+ }
2192
+
2193
+ void fx_TypedArray_prototype_slice(txMachine* the)
2194
+ {
2195
+ mxTypedArrayDeclarations;
2196
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
2197
+ txInteger start = (txInteger)fxArgToIndex(the, 0, 0, length);
2198
+ txInteger end = (txInteger)fxArgToIndex(the, 1, length, length);
2199
+ txInteger count = (end > start) ? end - start : 0;
2200
+ txInteger index = 0;
2201
+ fxCreateTypedArraySpecies(the);
2202
+ mxPushNumber(count);
2203
+ mxRunCount(1);
2204
+ mxPullSlot(mxResult);
2205
+ {
2206
+ mxResultTypedArrayDeclarations;
2207
+ if (resultLength < count)
2208
+ mxTypeError("insufficient buffer");
2209
+ if (count) {
2210
+ length = fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
2211
+ mxPushUndefined();
2212
+ while ((start < length) && (start < end)) {
2213
+ (*dispatch->value.typedArray.dispatch->getter)(the, buffer->value.reference->next, view->value.dataView.offset + (start * delta), the->stack, EndianNative);
2214
+ (*resultDispatch->value.typedArray.dispatch->coerce)(the, the->stack);
2215
+ (*resultDispatch->value.typedArray.dispatch->setter)(the, resultBuffer->value.reference->next, resultView->value.dataView.offset + (index << resultDispatch->value.typedArray.dispatch->shift), the->stack, EndianNative);
2216
+ start++;
2217
+ index++;
2218
+ }
2219
+ while (start < end) {
2220
+ the->stack->kind = XS_UNDEFINED_KIND;
2221
+ (*resultDispatch->value.typedArray.dispatch->coerce)(the, the->stack);
2222
+ (*resultDispatch->value.typedArray.dispatch->setter)(the, resultBuffer->value.reference->next, resultView->value.dataView.offset + (index << resultDispatch->value.typedArray.dispatch->shift), the->stack, EndianNative);
2223
+ start++;
2224
+ index++;
2225
+ }
2226
+ mxPop();
2227
+ }
2228
+ }
2229
+ }
2230
+
2231
+ void fx_TypedArray_prototype_some(txMachine* the)
2232
+ {
2233
+ mxTypedArrayDeclarations;
2234
+ txSlot* function = fxArgToCallback(the, 0);
2235
+ txInteger index = 0;
2236
+ mxResult->kind = XS_BOOLEAN_KIND;
2237
+ mxResult->value.boolean = 0;
2238
+ while (index < length) {
2239
+ fxCallTypedArrayItem(the, function, dispatch, view, buffer->value.reference->next, index, C_NULL);
2240
+ mxResult->value.boolean = fxToBoolean(the, the->stack++);
2241
+ if (mxResult->value.boolean)
2242
+ break;
2243
+ index++;
2244
+ }
2245
+ }
2246
+
2247
+ void fx_TypedArray_prototype_sort(txMachine* the)
2248
+ {
2249
+ mxMutableTypedArrayDeclarations;
2250
+ txSlot* data = buffer->value.reference->next;
2251
+ txInteger delta = dispatch->value.typedArray.dispatch->size;
2252
+ txSlot* function = C_NULL;
2253
+ if (mxArgc > 0) {
2254
+ txSlot* slot = mxArgv(0);
2255
+ if (slot->kind != XS_UNDEFINED_KIND) {
2256
+ if (fxIsCallable(the, slot))
2257
+ function = slot;
2258
+ else
2259
+ mxTypeError("compare is no function");
2260
+ }
2261
+ }
2262
+ if (function)
2263
+ fxSortArrayItems(the, function, C_NULL, length);
2264
+ else
2265
+ c_qsort(data->value.arrayBuffer.address, length, delta, dispatch->value.typedArray.dispatch->compare);
2266
+ mxResult->kind = mxThis->kind;
2267
+ mxResult->value = mxThis->value;
2268
+ }
2269
+
2270
+ void fx_TypedArray_prototype_subarray(txMachine* the)
2271
+ {
2272
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
2273
+ txSlot* dispatch = instance->next;
2274
+ txSlot* view = dispatch->next;
2275
+ txSlot* buffer = view->next;
2276
+ txU2 shift = dispatch->value.typedArray.dispatch->shift;
2277
+ txInteger length = fxGetDataViewSize(the, view, buffer) >> shift;
2278
+ txInteger start = (txInteger)fxArgToIndex(the, 0, 0, length);
2279
+ txInteger stop = (txInteger)fxArgToIndex(the, 1, length, length);
2280
+ if (stop < start)
2281
+ stop = start;
2282
+ fxCreateTypedArraySpecies(the);
2283
+ mxPushSlot(buffer);
2284
+ mxPushInteger(view->value.dataView.offset + (start << shift));
2285
+ mxPushInteger(stop - start);
2286
+ mxRunCount(3);
2287
+ mxPullSlot(mxResult);
2288
+ fxCheckTypedArrayInstance(the, mxResult);
2289
+ }
2290
+
2291
+ void fx_TypedArray_prototype_toLocaleString(txMachine* the)
2292
+ {
2293
+ mxTypedArrayDeclarations;
2294
+ txInteger index = 0;
2295
+ txString string;
2296
+ txSlot* list = fxNewInstance(the);
2297
+ txSlot* slot = list;
2298
+ txBoolean comma = 0;
2299
+ txInteger size = 0;
2300
+ mxPushStringX(",");
2301
+ the->stack->kind += XS_KEY_KIND - XS_STRING_KIND;
2302
+ the->stack->value.key.sum = 1;
2303
+ while (index < length) {
2304
+ if (comma) {
2305
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
2306
+ size += slot->value.key.sum;
2307
+ }
2308
+ else
2309
+ comma = 1;
2310
+ mxPushSlot(mxThis);
2311
+ mxGetIndex(index);
2312
+ if ((the->stack->kind != XS_UNDEFINED_KIND) && (the->stack->kind != XS_NULL_KIND)) {
2313
+ mxDub();
2314
+ mxGetID(mxID(_toLocaleString));
2315
+ mxCall();
2316
+ mxRunCount(0);
2317
+ slot = fxNextSlotProperty(the, slot, the->stack, XS_NO_ID, XS_NO_FLAG);
2318
+ string = fxToString(the, slot);
2319
+ slot->kind += XS_KEY_KIND - XS_STRING_KIND;
2320
+ slot->value.key.sum = mxStringLength(string);
2321
+ size = fxAddChunkSizes(the, size, slot->value.key.sum);
2322
+ }
2323
+ mxPop();
2324
+ index++;
2325
+ }
2326
+ string = mxResult->value.string = fxNewChunk(the, fxAddChunkSizes(the, size, 1));
2327
+ slot = list->next;
2328
+ while (slot) {
2329
+ c_memcpy(string, slot->value.key.string, slot->value.key.sum);
2330
+ string += slot->value.key.sum;
2331
+ slot = slot->next;
2332
+ }
2333
+ *string = 0;
2334
+ mxResult->kind = XS_STRING_KIND;
2335
+ mxPop();
2336
+ }
2337
+
2338
+ void fx_TypedArray_prototype_toStringTag_get(txMachine* the)
2339
+ {
2340
+ if (mxThis->kind == XS_REFERENCE_KIND) {
2341
+ txSlot* instance = mxThis->value.reference;
2342
+ txSlot* slot = instance->next;
2343
+ if (slot && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_TYPED_ARRAY_KIND)) {
2344
+ txTypeDispatch *dispatch = instance->next->value.typedArray.dispatch;
2345
+ txSlot* key = fxGetKey(the, mxID(dispatch->constructorID));
2346
+ if (key->kind == XS_KEY_X_KIND)
2347
+ mxResult->kind = XS_STRING_X_KIND;
2348
+ else
2349
+ mxResult->kind = XS_STRING_KIND;
2350
+ mxResult->value.string = key->value.key.string;
2351
+ }
2352
+ }
2353
+ }
2354
+
2355
+ void fx_TypedArray_prototype_values(txMachine* the)
2356
+ {
2357
+ txSlot* instance = fxCheckTypedArrayInstance(the, mxThis);
2358
+ txSlot* dispatch = instance->next;
2359
+ txSlot* view = dispatch->next;
2360
+ txSlot* buffer = view->next;
2361
+ txSlot* property;
2362
+ fxCheckDataViewSize(the, view, buffer, XS_IMMUTABLE);
2363
+ mxPush(mxArrayIteratorPrototype);
2364
+ property = fxLastProperty(the, fxNewIteratorInstance(the, mxThis, mxID(_Array)));
2365
+ property = fxNextIntegerProperty(the, property, 0, XS_NO_ID, XS_INTERNAL_FLAG);
2366
+ mxPullSlot(mxResult);
2367
+ }
2368
+
2369
+ #if mxBigEndian
2370
+ #define mxEndianDouble_BtoN(a) (a)
2371
+ #define mxEndianFloat_BtoN(a) (a)
2372
+ #define mxEndianS64_BtoN(a) (a)
2373
+ #define mxEndianU64_BtoN(a) (a)
2374
+ #define mxEndianS32_BtoN(a) (a)
2375
+ #define mxEndianU32_BtoN(a) (a)
2376
+ #define mxEndianS16_BtoN(a) (a)
2377
+ #define mxEndianU16_BtoN(a) (a)
2378
+
2379
+ #define mxEndianDouble_NtoB(a) (a)
2380
+ #define mxEndianFloat_NtoB(a) (a)
2381
+ #define mxEndianS64_NtoB(a) (a)
2382
+ #define mxEndianU64_NtoB(a) (a)
2383
+ #define mxEndianS32_NtoB(a) (a)
2384
+ #define mxEndianU32_NtoB(a) (a)
2385
+ #define mxEndianS16_NtoB(a) (a)
2386
+ #define mxEndianU16_NtoB(a) (a)
2387
+ #else
2388
+ #define mxEndianDouble_LtoN(a) (a)
2389
+ #define mxEndianFloat_LtoN(a) (a)
2390
+ #define mxEndianS64_LtoN(a) (a)
2391
+ #define mxEndianU64_LtoN(a) (a)
2392
+ #define mxEndianS32_LtoN(a) (a)
2393
+ #define mxEndianU32_LtoN(a) (a)
2394
+ #define mxEndianS16_LtoN(a) (a)
2395
+ #define mxEndianU16_LtoN(a) (a)
2396
+
2397
+ #define mxEndianDouble_NtoL(a) (a)
2398
+ #define mxEndianFloat_NtoL(a) (a)
2399
+ #define mxEndianS64_NtoL(a) (a)
2400
+ #define mxEndianU64_NtoL(a) (a)
2401
+ #define mxEndianS32_NtoL(a) (a)
2402
+ #define mxEndianU32_NtoL(a) (a)
2403
+ #define mxEndianS16_NtoL(a) (a)
2404
+ #define mxEndianU16_NtoL(a) (a)
2405
+ #endif
2406
+
2407
+ #if mxLittleEndian
2408
+ #define mxEndianDouble_BtoN(a) (mxEndianDouble_Swap(a))
2409
+ #define mxEndianFloat_BtoN(a) (mxEndianFloat_Swap(a))
2410
+ #define mxEndianS64_BtoN(a) ((txS8) mxEndian64_Swap(a))
2411
+ #define mxEndianU64_BtoN(a) ((txU8) mxEndian64_Swap(a))
2412
+ #define mxEndianS32_BtoN(a) ((txS4) mxEndian32_Swap(a))
2413
+ #define mxEndianU32_BtoN(a) ((txU4) mxEndian32_Swap(a))
2414
+ #define mxEndianS16_BtoN(a) ((txS2) mxEndian16_Swap(a))
2415
+ #define mxEndianU16_BtoN(a) ((txU2) mxEndian16_Swap(a))
2416
+
2417
+ #define mxEndianDouble_NtoB(a) (mxEndianDouble_Swap(a))
2418
+ #define mxEndianFloat_NtoB(a) (mxEndianFloat_Swap(a))
2419
+ #define mxEndianS64_NtoB(a) ((txS8) mxEndian64_Swap(a))
2420
+ #define mxEndianU64_NtoB(a) ((txU8) mxEndian64_Swap(a))
2421
+ #define mxEndianS32_NtoB(a) ((txS4) mxEndian32_Swap(a))
2422
+ #define mxEndianU32_NtoB(a) ((txU4) mxEndian32_Swap(a))
2423
+ #define mxEndianS16_NtoB(a) ((txS2) mxEndian16_Swap(a))
2424
+ #define mxEndianU16_NtoB(a) ((txU2) mxEndian16_Swap(a))
2425
+ #else
2426
+ #define mxEndianDouble_LtoN(a) (mxEndianDouble_Swap(a))
2427
+ #define mxEndianFloat_LtoN(a) (mxEndianFloat_Swap(a))
2428
+ #define mxEndianS64_LtoN(a) ((txS8) mxEndian64_Swap(a))
2429
+ #define mxEndianU64_LtoN(a) ((txU8) mxEndian64_Swap(a))
2430
+ #define mxEndianS32_LtoN(a) ((txS4) mxEndian32_Swap(a))
2431
+ #define mxEndianU32_LtoN(a) ((txU4) mxEndian32_Swap(a))
2432
+ #define mxEndianS16_LtoN(a) ((txS2) mxEndian16_Swap(a))
2433
+ #define mxEndianU16_LtoN(a) ((txU2) mxEndian16_Swap(a))
2434
+
2435
+ #define mxEndianDouble_NtoL(a) (mxEndianDouble_Swap(a))
2436
+ #define mxEndianFloat_NtoL(a) (mxEndianFloat_Swap(a))
2437
+ #define mxEndianS64_NtoL(a) ((txS8) mxEndian64_Swap(a))
2438
+ #define mxEndianU64_NtoL(a) ((txU8) mxEndian64_Swap(a))
2439
+ #define mxEndianS32_NtoL(a) ((txS4) mxEndian32_Swap(a))
2440
+ #define mxEndianU32_NtoL(a) ((txU4) mxEndian32_Swap(a))
2441
+ #define mxEndianS16_NtoL(a) ((txS2) mxEndian16_Swap(a))
2442
+ #define mxEndianU16_NtoL(a) ((txU2) mxEndian16_Swap(a))
2443
+ #endif
2444
+
2445
+ #if defined(__GNUC__) || defined(__llvm__)
2446
+ #define mxEndian16_Swap(a) __builtin_bswap16(a)
2447
+ #else
2448
+ static txU2 mxEndian16_Swap(txU2 a)
2449
+ {
2450
+ txU2 b;
2451
+ txU1 *p1 = (txU1 *) &a, *p2 = (txU1 *) &b;
2452
+ int i;
2453
+ for (i = 0; i < 2; i++)
2454
+ p2[i] = p1[1 - i];
2455
+ return b;
2456
+ }
2457
+ #endif
2458
+
2459
+ #if defined(__GNUC__) || defined(__llvm__)
2460
+ #define mxEndian32_Swap(a) __builtin_bswap32(a)
2461
+ #else
2462
+ static txU4 mxEndian32_Swap(txU4 a)
2463
+ {
2464
+ txU4 b;
2465
+ txU1 *p1 = (txU1 *) &a, *p2 = (txU1 *) &b;
2466
+ int i;
2467
+ for (i = 0; i < 4; i++)
2468
+ p2[i] = p1[3 - i];
2469
+ return b;
2470
+ }
2471
+ #endif
2472
+
2473
+ #if defined(__GNUC__) || defined(__llvm__)
2474
+ #define mxEndian64_Swap(a) __builtin_bswap64(a)
2475
+ #else
2476
+ static txU8 mxEndian64_Swap(txU8 a)
2477
+ {
2478
+ txU4 b;
2479
+ txU1 *p1 = (txU1 *) &a, *p2 = (txU1 *) &b;
2480
+ int i;
2481
+ for (i = 0; i < 8; i++)
2482
+ p2[i] = p1[7 - i];
2483
+ return b;
2484
+ }
2485
+ #endif
2486
+
2487
+ static float mxEndianFloat_Swap(float a)
2488
+ {
2489
+ #if defined(__GNUC__) || defined(__llvm__)
2490
+ uint32_t result = __builtin_bswap32(*(uint32_t *)&a);
2491
+ return *(float *)&result;
2492
+ #else
2493
+ float b;
2494
+ txU1 *p1 = (txU1 *) &a, *p2 = (txU1 *) &b;
2495
+ int i;
2496
+ for (i = 0; i < 4; i++)
2497
+ p2[i] = p1[3 - i];
2498
+ return b;
2499
+ #endif
2500
+ }
2501
+
2502
+ static double mxEndianDouble_Swap(double a)
2503
+ {
2504
+ #if defined(__GNUC__) || defined(__llvm__)
2505
+ uint64_t result = __builtin_bswap64(*(uint64_t *)&a);
2506
+ return *(double *)&result;
2507
+ #else
2508
+ double b;
2509
+ txU1 *p1 = (txU1 *) &a, *p2 = (txU1 *) &b;
2510
+ int i;
2511
+ for (i = 0; i < 8; i++)
2512
+ p2[i] = p1[7 - i];
2513
+ return b;
2514
+ #endif
2515
+ }
2516
+
2517
+ #define toNative(size, endian) mxEndian##size##_##endian##toN
2518
+ #define fromNative(size, endian) mxEndian##size##_Nto##endian
2519
+ #define IMPORT(size) (endian == EndianBig ? toNative(size, B)(value) : endian == EndianLittle ? toNative(size, L)(value) : (value))
2520
+ #define EXPORT(size) (endian == EndianBig ? fromNative(size, B)(value) : endian == EndianLittle ? toNative(size, L)(value) : (value))
2521
+
2522
+ int fxBigInt64Compare(const void* p, const void* q)
2523
+ {
2524
+ txS8 a = *((txS8*)p);
2525
+ txS8 b = *((txS8*)q);
2526
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2527
+ }
2528
+
2529
+ void fxBigInt64Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2530
+ {
2531
+ txS8 value;
2532
+ #ifdef mxMisalignedSettersCrash
2533
+ value = c_read32(data->value.arrayBuffer.address + offset);
2534
+ #else
2535
+ value = *((txS8*)(data->value.arrayBuffer.address + offset));
2536
+ #endif
2537
+ value = IMPORT(S64);
2538
+ fxFromBigInt64(the, slot, value);
2539
+ mxMeterOne();
2540
+ }
2541
+
2542
+ void fxBigInt64Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2543
+ {
2544
+ txS8 value = (txS8)fxToBigInt64(the, slot);
2545
+ #ifdef mxMisalignedSettersCrash
2546
+ value = EXPORT(S64);
2547
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(txS8));
2548
+ #else
2549
+ *((txS8*)(data->value.arrayBuffer.address + offset)) = EXPORT(S64);
2550
+ #endif
2551
+ mxMeterOne();
2552
+ }
2553
+
2554
+ int fxBigUint64Compare(const void* p, const void* q)
2555
+ {
2556
+ txU8 a = *((txU8*)p);
2557
+ txU8 b = *((txU8*)q);
2558
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2559
+ }
2560
+
2561
+ void fxBigUint64Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2562
+ {
2563
+ txU8 value;
2564
+ #ifdef mxMisalignedSettersCrash
2565
+ value = c_read32(data->value.arrayBuffer.address + offset);
2566
+ #else
2567
+ value = *((txU8*)(data->value.arrayBuffer.address + offset));
2568
+ #endif
2569
+ value = IMPORT(U64);
2570
+ fxFromBigUint64(the, slot, value);
2571
+ mxMeterOne();
2572
+ }
2573
+
2574
+ void fxBigUint64Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2575
+ {
2576
+ txU8 value = (txU8)fxToBigUint64(the, slot);
2577
+ #ifdef mxMisalignedSettersCrash
2578
+ value = EXPORT(U64);
2579
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(txU8));
2580
+ #else
2581
+ *((txU8*)(data->value.arrayBuffer.address + offset)) = EXPORT(U64);
2582
+ #endif
2583
+ mxMeterOne();
2584
+ }
2585
+
2586
+ int fxFloat32Compare(const void* p, const void* q)
2587
+ {
2588
+ float a = *((float*)p);
2589
+ float b = *((float*)q);
2590
+ if (c_isnan(a)) {
2591
+ if (c_isnan(b))
2592
+ return 0;
2593
+ return 1;
2594
+ }
2595
+ if (c_isnan(b))
2596
+ return -1;
2597
+ if (a < b)
2598
+ return -1;
2599
+ if (a > b)
2600
+ return 1;
2601
+ if (a == 0) {
2602
+ if (c_signbit(a)) {
2603
+ if (c_signbit(b))
2604
+ return 0;
2605
+ return -1;
2606
+ }
2607
+ if (c_signbit(b))
2608
+ return 1;
2609
+ }
2610
+ return 0;
2611
+ }
2612
+
2613
+ void fxFloat32Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2614
+ {
2615
+ float value;
2616
+ slot->kind = XS_NUMBER_KIND;
2617
+ #ifdef mxMisalignedSettersCrash
2618
+ c_memcpy(&value, data->value.arrayBuffer.address + offset, sizeof(value));
2619
+ #else
2620
+ value = *((float*)(data->value.arrayBuffer.address + offset));
2621
+ #endif
2622
+ slot->value.number = IMPORT(Float);
2623
+ mxMeterOne();
2624
+ }
2625
+
2626
+ void fxFloat32Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2627
+ {
2628
+ float value = (float)slot->value.number;
2629
+ #ifdef mxMisalignedSettersCrash
2630
+ value = EXPORT(Float);
2631
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(float));
2632
+ #else
2633
+ *((float*)(data->value.arrayBuffer.address + offset)) = EXPORT(Float);
2634
+ #endif
2635
+ mxMeterOne();
2636
+ }
2637
+
2638
+ int fxFloat64Compare(const void* p, const void* q)
2639
+ {
2640
+ double a = *((double*)p);
2641
+ double b = *((double*)q);
2642
+ if (c_isnan(a)) {
2643
+ if (c_isnan(b))
2644
+ return 0;
2645
+ return 1;
2646
+ }
2647
+ if (c_isnan(b))
2648
+ return -1;
2649
+ if (a < b)
2650
+ return -1;
2651
+ if (a > b)
2652
+ return 1;
2653
+ if (a == 0) {
2654
+ if (c_signbit(a)) {
2655
+ if (c_signbit(b))
2656
+ return 0;
2657
+ return -1;
2658
+ }
2659
+ if (c_signbit(b))
2660
+ return 1;
2661
+ }
2662
+ return 0;
2663
+ }
2664
+
2665
+ void fxFloat64Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2666
+ {
2667
+ double value;
2668
+ slot->kind = XS_NUMBER_KIND;
2669
+ #ifdef mxMisalignedSettersCrash
2670
+ c_memcpy(&value, data->value.arrayBuffer.address + offset, sizeof(value));
2671
+ #else
2672
+ value = *((double*)(data->value.arrayBuffer.address + offset));
2673
+ #endif
2674
+ slot->value.number = IMPORT(Double);
2675
+ mxMeterOne();
2676
+ }
2677
+
2678
+ void fxFloat64Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2679
+ {
2680
+ double value = slot->value.number;
2681
+ #ifdef mxMisalignedSettersCrash
2682
+ value = EXPORT(Double);
2683
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(double));
2684
+ #else
2685
+ *((double*)(data->value.arrayBuffer.address + offset)) = EXPORT(Double);
2686
+ #endif
2687
+ mxMeterOne();
2688
+ }
2689
+
2690
+ void fxIntCoerce(txMachine* the, txSlot* slot)
2691
+ {
2692
+ fxToInteger(the, slot);
2693
+ }
2694
+
2695
+ void fxUintCoerce(txMachine* the, txSlot* slot)
2696
+ {
2697
+ fxToUnsigned(the, slot);
2698
+ }
2699
+
2700
+ int fxInt8Compare(const void* p, const void* q)
2701
+ {
2702
+ txS1 a = *((txS1*)p);
2703
+ txS1 b = *((txS1*)q);
2704
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2705
+ }
2706
+
2707
+ void fxInt8Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2708
+ {
2709
+ slot->kind = XS_INTEGER_KIND;
2710
+ slot->value.integer = *((txS1*)(data->value.arrayBuffer.address + offset));
2711
+ mxMeterOne();
2712
+ }
2713
+
2714
+ void fxInt8Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2715
+ {
2716
+ *((txS1*)(data->value.arrayBuffer.address + offset)) = (txS1)slot->value.integer;
2717
+ mxMeterOne();
2718
+ }
2719
+
2720
+ int fxInt16Compare(const void* p, const void* q)
2721
+ {
2722
+ txS2 a = *((txS2*)p);
2723
+ txS2 b = *((txS2*)q);
2724
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2725
+ }
2726
+
2727
+ void fxInt16Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2728
+ {
2729
+ txS2 value;
2730
+ slot->kind = XS_INTEGER_KIND;
2731
+ #ifdef mxMisalignedSettersCrash
2732
+ c_memcpy(&value, data->value.arrayBuffer.address + offset, sizeof(value));
2733
+ #else
2734
+ value = *((txS2*)(data->value.arrayBuffer.address + offset));
2735
+ #endif
2736
+ slot->value.integer = IMPORT(S16);
2737
+ mxMeterOne();
2738
+ }
2739
+
2740
+ void fxInt16Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2741
+ {
2742
+ txS2 value = (txS2)slot->value.integer;
2743
+ #ifdef mxMisalignedSettersCrash
2744
+ value = EXPORT(S16);
2745
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(txS2));
2746
+ #else
2747
+ *((txS2*)(data->value.arrayBuffer.address + offset)) = EXPORT(S16);
2748
+ #endif
2749
+ mxMeterOne();
2750
+ }
2751
+
2752
+ int fxInt32Compare(const void* p, const void* q)
2753
+ {
2754
+ txS4 a = *((txS4*)p);
2755
+ txS4 b = *((txS4*)q);
2756
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2757
+ }
2758
+
2759
+ void fxInt32Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2760
+ {
2761
+ txS4 value;
2762
+ slot->kind = XS_INTEGER_KIND;
2763
+ #ifdef mxMisalignedSettersCrash
2764
+ value = c_read32(data->value.arrayBuffer.address + offset);
2765
+ #else
2766
+ value = *((txS4*)(data->value.arrayBuffer.address + offset));
2767
+ #endif
2768
+ slot->value.integer = IMPORT(S32);
2769
+ mxMeterOne();
2770
+ }
2771
+
2772
+ void fxInt32Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2773
+ {
2774
+ txS4 value = (txS4)slot->value.integer;
2775
+ #ifdef mxMisalignedSettersCrash
2776
+ value = EXPORT(S32);
2777
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(txS4));
2778
+ #else
2779
+ *((txS4*)(data->value.arrayBuffer.address + offset)) = EXPORT(S32);
2780
+ #endif
2781
+ mxMeterOne();
2782
+ }
2783
+
2784
+ int fxUint8Compare(const void* p, const void* q)
2785
+ {
2786
+ txU1 a = c_read8((txU1*)p);
2787
+ txU1 b = c_read8((txU1*)q);
2788
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2789
+ }
2790
+
2791
+ void fxUint8Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2792
+ {
2793
+ slot->kind = XS_INTEGER_KIND;
2794
+ slot->value.integer = c_read8((txU1*)(data->value.arrayBuffer.address + offset));
2795
+ mxMeterOne();
2796
+ }
2797
+
2798
+ void fxUint8Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2799
+ {
2800
+ txUnsigned tmp = (slot->kind == XS_INTEGER_KIND) ? (txUnsigned)slot->value.integer : (txUnsigned)slot->value.number;
2801
+ *((txU1*)(data->value.arrayBuffer.address + offset)) = (txU1)tmp;
2802
+ mxMeterOne();
2803
+ }
2804
+
2805
+ int fxUint16Compare(const void* p, const void* q)
2806
+ {
2807
+ txU2 a = *((txU2*)p);
2808
+ txU2 b = *((txU2*)q);
2809
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2810
+ }
2811
+
2812
+ void fxUint16Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2813
+ {
2814
+ txU2 value;
2815
+ slot->kind = XS_INTEGER_KIND;
2816
+ #ifdef mxMisalignedSettersCrash
2817
+ c_memcpy(&value, data->value.arrayBuffer.address + offset, sizeof(value));
2818
+ #else
2819
+ value = *((txU2*)(data->value.arrayBuffer.address + offset));
2820
+ #endif
2821
+ slot->value.integer = IMPORT(U16);
2822
+ mxMeterOne();
2823
+ }
2824
+
2825
+ void fxUint16Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2826
+ {
2827
+ txUnsigned tmp = (slot->kind == XS_INTEGER_KIND) ? (txUnsigned)slot->value.integer : (txUnsigned)slot->value.number;
2828
+ txU2 value = (txU2)tmp;
2829
+ #ifdef mxMisalignedSettersCrash
2830
+ value = EXPORT(U16);
2831
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(txU2));
2832
+ #else
2833
+ *((txU2*)(data->value.arrayBuffer.address + offset)) = EXPORT(U16);
2834
+ #endif
2835
+ mxMeterOne();
2836
+ }
2837
+
2838
+ int fxUint32Compare(const void* p, const void* q)
2839
+ {
2840
+ txU4 a = *((txU4*)p);
2841
+ txU4 b = *((txU4*)q);
2842
+ return (a < b) ? -1 : (a > b) ? 1 : 0;
2843
+ }
2844
+
2845
+ void fxUint32Getter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2846
+ {
2847
+ #ifdef mxMisalignedSettersCrash
2848
+ txUnsigned value = c_read32(data->value.arrayBuffer.address + offset);
2849
+ #else
2850
+ txUnsigned value = *((txU4*)(data->value.arrayBuffer.address + offset));
2851
+ #endif
2852
+ value = IMPORT(U32);
2853
+ if (((txInteger)value) >= 0) {
2854
+ slot->kind = XS_INTEGER_KIND;
2855
+ slot->value.integer = value;
2856
+ }
2857
+ else {
2858
+ slot->kind = XS_NUMBER_KIND;
2859
+ slot->value.number = value;
2860
+ }
2861
+ mxMeterOne();
2862
+ }
2863
+
2864
+ void fxUint32Setter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2865
+ {
2866
+ txU4 value = (slot->kind == XS_INTEGER_KIND) ? (txU4)slot->value.integer : (txU4)slot->value.number;
2867
+ #ifdef mxMisalignedSettersCrash
2868
+ value = EXPORT(U32);
2869
+ c_memcpy(data->value.arrayBuffer.address + offset, &value, sizeof(txU4));
2870
+ #else
2871
+ *((txU4*)(data->value.arrayBuffer.address + offset)) = EXPORT(U32);
2872
+ #endif
2873
+ mxMeterOne();
2874
+ }
2875
+
2876
+ void fxUint8ClampedSetter(txMachine* the, txSlot* data, txInteger offset, txSlot* slot, int endian)
2877
+ {
2878
+ txNumber value = fxToNumber(the, slot);
2879
+ if (value <= 0)
2880
+ value = 0;
2881
+ else if (value >= 255)
2882
+ value = 255;
2883
+ else if (c_isnan(value))
2884
+ value = 0;
2885
+ else
2886
+ value = c_nearbyint(value);
2887
+ *((txU1*)(data->value.arrayBuffer.address + offset)) = (txU1)value;
2888
+ mxMeterOne();
2889
+ }
2890
+