@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.
- package/README.md +3 -3
- package/api.js +4 -2
- package/build.env +1 -1
- package/moddable/modules/data/base64/base64.js +28 -0
- package/moddable/modules/data/base64/manifest.json +11 -0
- package/moddable/modules/data/base64/modBase64.c +188 -0
- package/moddable/modules/data/binaryMessage/BinaryMessage.js +106 -0
- package/moddable/modules/data/crc/crc.c +205 -0
- package/moddable/modules/data/crc/crc.js +36 -0
- package/moddable/modules/data/crc/manifest.json +8 -0
- package/moddable/modules/data/hex/hex.js +28 -0
- package/moddable/modules/data/hex/manifest.json +11 -0
- package/moddable/modules/data/hex/modHex.c +139 -0
- package/moddable/modules/data/logical/logical.js +32 -0
- package/moddable/modules/data/logical/modLogical.c +98 -0
- package/moddable/modules/data/qrcode/manifest.json +9 -0
- package/moddable/modules/data/qrcode/qrcode.c +93 -0
- package/moddable/modules/data/qrcode/qrcode.js +23 -0
- package/moddable/modules/data/qrcode/qrcodegen.c +1025 -0
- package/moddable/modules/data/qrcode/qrcodegen.h +267 -0
- package/moddable/modules/data/text/decoder/manifest.json +8 -0
- package/moddable/modules/data/text/decoder/textdecoder.c +480 -0
- package/moddable/modules/data/text/decoder/textdecoder.js +27 -0
- package/moddable/modules/data/text/encoder/manifest.json +8 -0
- package/moddable/modules/data/text/encoder/textencoder.c +232 -0
- package/moddable/modules/data/text/encoder/textencoder.js +24 -0
- package/moddable/modules/data/tinyint/tinyint.c +150 -0
- package/moddable/modules/data/tinyint/tinyint.js +53 -0
- package/moddable/modules/data/url/manifest.json +17 -0
- package/moddable/modules/data/url/url.c +1959 -0
- package/moddable/modules/data/url/url.js +210 -0
- package/moddable/modules/data/wavreader/manifest.json +8 -0
- package/moddable/modules/data/wavreader/wavreader.js +128 -0
- package/moddable/modules/data/zlib/deflate.c +161 -0
- package/moddable/modules/data/zlib/deflate.js +63 -0
- package/moddable/modules/data/zlib/inflate.c +145 -0
- package/moddable/modules/data/zlib/inflate.js +66 -0
- package/moddable/modules/data/zlib/manifest_deflate.json +9 -0
- package/moddable/modules/data/zlib/manifest_inflate.json +9 -0
- package/moddable/modules/data/zlib/miniz.c +4924 -0
- package/moddable/xs/includes/xs.d.ts +73 -0
- package/moddable/xs/includes/xs.h +1533 -0
- package/moddable/xs/includes/xsmc.h +206 -0
- package/moddable/xs/makefiles/lin/makefile +33 -0
- package/moddable/xs/makefiles/lin/xsc.mk +118 -0
- package/moddable/xs/makefiles/lin/xsid.mk +90 -0
- package/moddable/xs/makefiles/lin/xsl.mk +168 -0
- package/moddable/xs/makefiles/lin/xst.mk +201 -0
- package/moddable/xs/makefiles/mac/makefile +33 -0
- package/moddable/xs/makefiles/mac/xsc.mk +130 -0
- package/moddable/xs/makefiles/mac/xsid.mk +102 -0
- package/moddable/xs/makefiles/mac/xsl.mk +177 -0
- package/moddable/xs/makefiles/mac/xst.mk +203 -0
- package/moddable/xs/makefiles/mac/xst_no_asan.txt +52 -0
- package/moddable/xs/makefiles/win/build.bat +26 -0
- package/moddable/xs/makefiles/win/xsc.mak +142 -0
- package/moddable/xs/makefiles/win/xsid.mak +113 -0
- package/moddable/xs/makefiles/win/xsl.mak +186 -0
- package/moddable/xs/makefiles/win/xst.mak +195 -0
- package/moddable/xs/platforms/lin_xs.h +99 -0
- package/moddable/xs/platforms/mac_xs.h +97 -0
- package/moddable/xs/platforms/wasm_xs.h +79 -0
- package/moddable/xs/platforms/win_xs.h +104 -0
- package/moddable/xs/platforms/xsHost.h +63 -0
- package/moddable/xs/platforms/xsPlatform.h +618 -0
- package/moddable/xs/sources/xsAPI.c +2555 -0
- package/moddable/xs/sources/xsAll.c +294 -0
- package/moddable/xs/sources/xsAll.h +2741 -0
- package/moddable/xs/sources/xsArguments.c +222 -0
- package/moddable/xs/sources/xsArray.c +2657 -0
- package/moddable/xs/sources/xsAtomics.c +844 -0
- package/moddable/xs/sources/xsBigInt.c +1859 -0
- package/moddable/xs/sources/xsBoolean.c +109 -0
- package/moddable/xs/sources/xsCode.c +4493 -0
- package/moddable/xs/sources/xsCommon.c +1710 -0
- package/moddable/xs/sources/xsCommon.h +1142 -0
- package/moddable/xs/sources/xsDataView.c +2890 -0
- package/moddable/xs/sources/xsDate.c +1541 -0
- package/moddable/xs/sources/xsDebug.c +2710 -0
- package/moddable/xs/sources/xsDefaults.c +134 -0
- package/moddable/xs/sources/xsError.c +353 -0
- package/moddable/xs/sources/xsFunction.c +776 -0
- package/moddable/xs/sources/xsGenerator.c +865 -0
- package/moddable/xs/sources/xsGlobal.c +839 -0
- package/moddable/xs/sources/xsJSON.c +1091 -0
- package/moddable/xs/sources/xsLexical.c +1969 -0
- package/moddable/xs/sources/xsLockdown.c +933 -0
- package/moddable/xs/sources/xsMapSet.c +1649 -0
- package/moddable/xs/sources/xsMarshall.c +1020 -0
- package/moddable/xs/sources/xsMath.c +624 -0
- package/moddable/xs/sources/xsMemory.c +1941 -0
- package/moddable/xs/sources/xsModule.c +3101 -0
- package/moddable/xs/sources/xsNumber.c +560 -0
- package/moddable/xs/sources/xsObject.c +1102 -0
- package/moddable/xs/sources/xsPlatforms.c +480 -0
- package/moddable/xs/sources/xsProfile.c +577 -0
- package/moddable/xs/sources/xsPromise.c +1199 -0
- package/moddable/xs/sources/xsProperty.c +636 -0
- package/moddable/xs/sources/xsProxy.c +1014 -0
- package/moddable/xs/sources/xsRegExp.c +1168 -0
- package/moddable/xs/sources/xsRun.c +4889 -0
- package/moddable/xs/sources/xsScope.c +1293 -0
- package/moddable/xs/sources/xsScript.c +288 -0
- package/moddable/xs/sources/xsScript.h +1186 -0
- package/moddable/xs/sources/xsSnapshot.c +2161 -0
- package/moddable/xs/sources/xsSnapshot.h +51 -0
- package/moddable/xs/sources/xsSourceMap.c +218 -0
- package/moddable/xs/sources/xsString.c +3332 -0
- package/moddable/xs/sources/xsSymbol.c +503 -0
- package/moddable/xs/sources/xsSyntaxical.c +4193 -0
- package/moddable/xs/sources/xsTree.c +1893 -0
- package/moddable/xs/sources/xsType.c +1488 -0
- package/moddable/xs/sources/xsdtoa.c +6672 -0
- package/moddable/xs/sources/xsmc.c +340 -0
- package/moddable/xs/sources/xsre.c +7578 -0
- package/package.json +37 -20
- package/scripts/get_xsnap_version.sh +14 -0
- package/scripts/test-package.sh +21 -0
- package/src/avaAssertXS.js +6 -2
- package/src/avaHandler.cjs +2 -5
- package/src/avaXS.js +7 -8
- package/src/build.js +161 -28
- package/src/replay.js +0 -3
- package/src/xsnap.js +105 -91
- package/src/xsrepl.js +2 -3
- package/xsnap-native/xsnap/makefiles/lin/makefile +10 -0
- package/xsnap-native/xsnap/makefiles/lin/xsnap-worker.mk +156 -0
- package/xsnap-native/xsnap/makefiles/lin/xsnap.mk +144 -0
- package/xsnap-native/xsnap/makefiles/mac/makefile +10 -0
- package/xsnap-native/xsnap/makefiles/mac/xsnap-worker.mk +165 -0
- package/xsnap-native/xsnap/makefiles/mac/xsnap.mk +153 -0
- package/xsnap-native/xsnap/sources/xsnap-worker.c +1008 -0
- package/xsnap-native/xsnap/sources/xsnap.c +717 -0
- package/xsnap-native/xsnap/sources/xsnap.h +142 -0
- package/xsnap-native/xsnap/sources/xsnapPlatform.c +1501 -0
- package/xsnap-native/xsnap/sources/xsnapPlatform.h +105 -0
- 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
|
+
|