@agoric/xsnap 0.14.3-dev-b047af2.0 → 0.14.3-dev-3eb4230.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/api.js +1 -1
  2. package/package.json +16 -23
  3. package/src/build.js +4 -61
  4. package/moddable/modules/data/base64/base64.js +0 -28
  5. package/moddable/modules/data/base64/manifest.json +0 -11
  6. package/moddable/modules/data/base64/modBase64.c +0 -188
  7. package/moddable/modules/data/binaryMessage/BinaryMessage.js +0 -106
  8. package/moddable/modules/data/crc/crc.c +0 -205
  9. package/moddable/modules/data/crc/crc.js +0 -36
  10. package/moddable/modules/data/crc/manifest.json +0 -8
  11. package/moddable/modules/data/hex/hex.js +0 -28
  12. package/moddable/modules/data/hex/manifest.json +0 -11
  13. package/moddable/modules/data/hex/modHex.c +0 -139
  14. package/moddable/modules/data/logical/logical.js +0 -32
  15. package/moddable/modules/data/logical/modLogical.c +0 -98
  16. package/moddable/modules/data/qrcode/manifest.json +0 -9
  17. package/moddable/modules/data/qrcode/qrcode.c +0 -93
  18. package/moddable/modules/data/qrcode/qrcode.js +0 -23
  19. package/moddable/modules/data/qrcode/qrcodegen.c +0 -1025
  20. package/moddable/modules/data/qrcode/qrcodegen.h +0 -267
  21. package/moddable/modules/data/text/decoder/manifest.json +0 -8
  22. package/moddable/modules/data/text/decoder/textdecoder.c +0 -480
  23. package/moddable/modules/data/text/decoder/textdecoder.js +0 -27
  24. package/moddable/modules/data/text/encoder/manifest.json +0 -8
  25. package/moddable/modules/data/text/encoder/textencoder.c +0 -232
  26. package/moddable/modules/data/text/encoder/textencoder.js +0 -24
  27. package/moddable/modules/data/tinyint/tinyint.c +0 -150
  28. package/moddable/modules/data/tinyint/tinyint.js +0 -53
  29. package/moddable/modules/data/url/manifest.json +0 -17
  30. package/moddable/modules/data/url/url.c +0 -1959
  31. package/moddable/modules/data/url/url.js +0 -210
  32. package/moddable/modules/data/wavreader/manifest.json +0 -8
  33. package/moddable/modules/data/wavreader/wavreader.js +0 -128
  34. package/moddable/modules/data/zlib/deflate.c +0 -161
  35. package/moddable/modules/data/zlib/deflate.js +0 -63
  36. package/moddable/modules/data/zlib/inflate.c +0 -145
  37. package/moddable/modules/data/zlib/inflate.js +0 -66
  38. package/moddable/modules/data/zlib/manifest_deflate.json +0 -9
  39. package/moddable/modules/data/zlib/manifest_inflate.json +0 -9
  40. package/moddable/modules/data/zlib/miniz.c +0 -4924
  41. package/moddable/xs/includes/xs.d.ts +0 -73
  42. package/moddable/xs/includes/xs.h +0 -1533
  43. package/moddable/xs/includes/xsmc.h +0 -206
  44. package/moddable/xs/makefiles/lin/makefile +0 -33
  45. package/moddable/xs/makefiles/lin/xsc.mk +0 -118
  46. package/moddable/xs/makefiles/lin/xsid.mk +0 -90
  47. package/moddable/xs/makefiles/lin/xsl.mk +0 -168
  48. package/moddable/xs/makefiles/lin/xst.mk +0 -201
  49. package/moddable/xs/makefiles/mac/makefile +0 -33
  50. package/moddable/xs/makefiles/mac/xsc.mk +0 -130
  51. package/moddable/xs/makefiles/mac/xsid.mk +0 -102
  52. package/moddable/xs/makefiles/mac/xsl.mk +0 -177
  53. package/moddable/xs/makefiles/mac/xst.mk +0 -203
  54. package/moddable/xs/makefiles/mac/xst_no_asan.txt +0 -52
  55. package/moddable/xs/makefiles/win/build.bat +0 -26
  56. package/moddable/xs/makefiles/win/xsc.mak +0 -142
  57. package/moddable/xs/makefiles/win/xsid.mak +0 -113
  58. package/moddable/xs/makefiles/win/xsl.mak +0 -186
  59. package/moddable/xs/makefiles/win/xst.mak +0 -195
  60. package/moddable/xs/platforms/lin_xs.h +0 -99
  61. package/moddable/xs/platforms/mac_xs.h +0 -97
  62. package/moddable/xs/platforms/wasm_xs.h +0 -79
  63. package/moddable/xs/platforms/win_xs.h +0 -104
  64. package/moddable/xs/platforms/xsHost.h +0 -63
  65. package/moddable/xs/platforms/xsPlatform.h +0 -618
  66. package/moddable/xs/sources/xsAPI.c +0 -2555
  67. package/moddable/xs/sources/xsAll.c +0 -294
  68. package/moddable/xs/sources/xsAll.h +0 -2741
  69. package/moddable/xs/sources/xsArguments.c +0 -222
  70. package/moddable/xs/sources/xsArray.c +0 -2657
  71. package/moddable/xs/sources/xsAtomics.c +0 -844
  72. package/moddable/xs/sources/xsBigInt.c +0 -1859
  73. package/moddable/xs/sources/xsBoolean.c +0 -109
  74. package/moddable/xs/sources/xsCode.c +0 -4493
  75. package/moddable/xs/sources/xsCommon.c +0 -1710
  76. package/moddable/xs/sources/xsCommon.h +0 -1142
  77. package/moddable/xs/sources/xsDataView.c +0 -2890
  78. package/moddable/xs/sources/xsDate.c +0 -1541
  79. package/moddable/xs/sources/xsDebug.c +0 -2710
  80. package/moddable/xs/sources/xsDefaults.c +0 -134
  81. package/moddable/xs/sources/xsError.c +0 -353
  82. package/moddable/xs/sources/xsFunction.c +0 -776
  83. package/moddable/xs/sources/xsGenerator.c +0 -865
  84. package/moddable/xs/sources/xsGlobal.c +0 -839
  85. package/moddable/xs/sources/xsJSON.c +0 -1091
  86. package/moddable/xs/sources/xsLexical.c +0 -1969
  87. package/moddable/xs/sources/xsLockdown.c +0 -933
  88. package/moddable/xs/sources/xsMapSet.c +0 -1649
  89. package/moddable/xs/sources/xsMarshall.c +0 -1020
  90. package/moddable/xs/sources/xsMath.c +0 -624
  91. package/moddable/xs/sources/xsMemory.c +0 -1941
  92. package/moddable/xs/sources/xsModule.c +0 -3101
  93. package/moddable/xs/sources/xsNumber.c +0 -560
  94. package/moddable/xs/sources/xsObject.c +0 -1102
  95. package/moddable/xs/sources/xsPlatforms.c +0 -480
  96. package/moddable/xs/sources/xsProfile.c +0 -577
  97. package/moddable/xs/sources/xsPromise.c +0 -1199
  98. package/moddable/xs/sources/xsProperty.c +0 -636
  99. package/moddable/xs/sources/xsProxy.c +0 -1014
  100. package/moddable/xs/sources/xsRegExp.c +0 -1168
  101. package/moddable/xs/sources/xsRun.c +0 -4889
  102. package/moddable/xs/sources/xsScope.c +0 -1293
  103. package/moddable/xs/sources/xsScript.c +0 -288
  104. package/moddable/xs/sources/xsScript.h +0 -1186
  105. package/moddable/xs/sources/xsSnapshot.c +0 -2161
  106. package/moddable/xs/sources/xsSnapshot.h +0 -51
  107. package/moddable/xs/sources/xsSourceMap.c +0 -218
  108. package/moddable/xs/sources/xsString.c +0 -3332
  109. package/moddable/xs/sources/xsSymbol.c +0 -503
  110. package/moddable/xs/sources/xsSyntaxical.c +0 -4193
  111. package/moddable/xs/sources/xsTree.c +0 -1893
  112. package/moddable/xs/sources/xsType.c +0 -1488
  113. package/moddable/xs/sources/xsdtoa.c +0 -6672
  114. package/moddable/xs/sources/xsmc.c +0 -340
  115. package/moddable/xs/sources/xsre.c +0 -7578
  116. package/xsnap-native/xsnap/makefiles/lin/makefile +0 -10
  117. package/xsnap-native/xsnap/makefiles/lin/xsnap-worker.mk +0 -153
  118. package/xsnap-native/xsnap/makefiles/lin/xsnap.mk +0 -144
  119. package/xsnap-native/xsnap/makefiles/mac/makefile +0 -10
  120. package/xsnap-native/xsnap/makefiles/mac/xsnap-worker.mk +0 -162
  121. package/xsnap-native/xsnap/makefiles/mac/xsnap.mk +0 -153
  122. package/xsnap-native/xsnap/sources/xsnap-worker.c +0 -996
  123. package/xsnap-native/xsnap/sources/xsnap.c +0 -716
  124. package/xsnap-native/xsnap/sources/xsnap.h +0 -142
  125. package/xsnap-native/xsnap/sources/xsnapPlatform.c +0 -1496
  126. package/xsnap-native/xsnap/sources/xsnapPlatform.h +0 -105
@@ -1,1649 +0,0 @@
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
- #ifndef mxTableMinLength
41
- #define mxTableMinLength (1)
42
- #endif
43
- #ifndef mxTableMaxLength
44
- #define mxTableMaxLength (1024 * 1024)
45
- #endif
46
- #define mxTableThreshold(LENGTH) (((LENGTH) >> 1) + ((LENGTH) >> 2))
47
-
48
- static txSlot* fxCheckMapInstance(txMachine* the, txSlot* slot, txBoolean mutable);
49
- static txSlot* fxCheckMapKey(txMachine* the);
50
- static txSlot* fxNewMapIteratorInstance(txMachine* the, txSlot* iterable, txInteger kind);
51
-
52
- static txSlot* fxCheckSetInstance(txMachine* the, txSlot* slot, txBoolean mutable);
53
- static txSlot* fxCheckSetValue(txMachine* the);
54
- static txSlot* fxNewSetIteratorInstance(txMachine* the, txSlot* iterable, txInteger kind);
55
-
56
- static void fxClearEntries(txMachine* the, txSlot* table, txSlot* list, txBoolean paired);
57
- static txBoolean fxDeleteEntry(txMachine* the, txSlot* table, txSlot* list, txSlot* slot, txBoolean paired);
58
- static txSlot* fxGetEntry(txMachine* the, txSlot* table, txSlot* slot);
59
- static void fxPurgeEntries(txMachine* the, txSlot* list);
60
- static void fxResizeEntries(txMachine* the, txSlot* table, txSlot* list);
61
- static void fxSetEntry(txMachine* the, txSlot* table, txSlot* list, txSlot* slot, txSlot* pair);
62
- static txBoolean fxTestEntry(txMachine* the, txSlot* a, txSlot* b);
63
-
64
- static txSlot* fxCheckWeakMapInstance(txMachine* the, txSlot* slot, txBoolean mutable);
65
- static txSlot* fxCheckWeakMapKey(txMachine* the, txBoolean mutable);
66
-
67
- static txSlot* fxCheckWeakSetInstance(txMachine* the, txSlot* slot, txBoolean mutable);
68
- static txSlot* fxCheckWeakSetValue(txMachine* the, txBoolean mutable);
69
-
70
- static txBoolean fxDeleteWeakEntry(txMachine* the, txSlot* link, txSlot* slot);
71
- static txSlot* fxGetWeakEntry(txMachine* the, txSlot* link, txSlot* slot);
72
- static void fxSetWeakEntry(txMachine* the, txSlot* link, txSlot* slot, txSlot* pair);
73
-
74
- static void fxKeepDuringJobs(txMachine* the, txSlot* target);
75
- static txSlot* fxNewWeakRefInstance(txMachine* the);
76
-
77
- static void fx_FinalizationRegistryCleanup(txMachine* the, txSlot* registry, txSlot* callback);
78
-
79
- void fxBuildMapSet(txMachine* the)
80
- {
81
- txSlot* slot;
82
- txSlot* property;
83
-
84
- /* MAP */
85
- mxPush(mxObjectPrototype);
86
- slot = fxLastProperty(the, fxNewObjectInstance(the));
87
- slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Map_prototype_size), C_NULL, mxID(_size), XS_DONT_ENUM_FLAG);
88
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_clear), 0, mxID(_clear), XS_DONT_ENUM_FLAG);
89
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_delete), 1, mxID(_delete), XS_DONT_ENUM_FLAG);
90
- property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_entries), 0, mxID(_entries), XS_DONT_ENUM_FLAG);
91
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_forEach), 1, mxID(_forEach), XS_DONT_ENUM_FLAG);
92
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_get), 1, mxID(_get), XS_DONT_ENUM_FLAG);
93
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_has), 1, mxID(_has), XS_DONT_ENUM_FLAG);
94
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_keys), 0, mxID(_keys), XS_DONT_ENUM_FLAG);
95
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_set), 2, mxID(_set), XS_DONT_ENUM_FLAG);
96
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Map_prototype_values), 0, mxID(_values), XS_DONT_ENUM_FLAG);
97
- slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
98
- slot = fxNextStringXProperty(the, slot, "Map", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
99
- mxMapPrototype = *the->stack;
100
- slot = fxBuildHostConstructor(the, mxCallback(fx_Map), 0, mxID(_Map));
101
- mxMapConstructor = *the->stack;
102
- slot = fxLastProperty(the, slot);
103
- slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG);
104
- mxPop();
105
-
106
- mxPush(mxIteratorPrototype);
107
- slot = fxLastProperty(the, fxNewObjectInstance(the));
108
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_MapIterator_prototype_next), 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG);
109
- slot = fxNextStringXProperty(the, slot, "Map Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
110
- mxPull(mxMapIteratorPrototype);
111
-
112
- /* SET */
113
- mxPush(mxObjectPrototype);
114
- slot = fxLastProperty(the, fxNewObjectInstance(the));
115
- slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_Set_prototype_size), C_NULL, mxID(_size), XS_DONT_ENUM_FLAG);
116
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_add), 1, mxID(_add), XS_DONT_ENUM_FLAG);
117
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_clear), 0, mxID(_clear), XS_DONT_ENUM_FLAG);
118
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_delete), 1, mxID(_delete), XS_DONT_ENUM_FLAG);
119
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_entries), 0, mxID(_entries), XS_DONT_ENUM_FLAG);
120
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_forEach), 1, mxID(_forEach), XS_DONT_ENUM_FLAG);
121
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_has), 1, mxID(_has), XS_DONT_ENUM_FLAG);
122
- property = slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_Set_prototype_values), 0, mxID(_values), XS_DONT_ENUM_FLAG);
123
- slot = fxNextSlotProperty(the, slot, property, mxID(_keys), XS_DONT_ENUM_FLAG);
124
- slot = fxNextSlotProperty(the, slot, property, mxID(_Symbol_iterator), XS_DONT_ENUM_FLAG);
125
- slot = fxNextStringXProperty(the, slot, "Set", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
126
- mxSetPrototype = *the->stack;
127
- slot = fxBuildHostConstructor(the, mxCallback(fx_Set), 0, mxID(_Set));
128
- mxSetConstructor = *the->stack;
129
- slot = fxLastProperty(the, slot);
130
- slot = fxNextHostAccessorProperty(the, slot, mxCallback(fx_species_get), C_NULL, mxID(_Symbol_species), XS_DONT_ENUM_FLAG);
131
- mxPop();
132
-
133
- mxPush(mxIteratorPrototype);
134
- slot = fxLastProperty(the, fxNewObjectInstance(the));
135
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_SetIterator_prototype_next), 0, mxID(_next), XS_DONT_DELETE_FLAG | XS_DONT_ENUM_FLAG);
136
- slot = fxNextStringXProperty(the, slot, "Set Iterator", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
137
- mxPull(mxSetIteratorPrototype);
138
-
139
- /* WEAK MAP */
140
- mxPush(mxObjectPrototype);
141
- slot = fxLastProperty(the, fxNewObjectInstance(the));
142
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakMap_prototype_delete), 1, mxID(_delete), XS_DONT_ENUM_FLAG);
143
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakMap_prototype_get), 1, mxID(_get), XS_DONT_ENUM_FLAG);
144
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakMap_prototype_has), 1, mxID(_has), XS_DONT_ENUM_FLAG);
145
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakMap_prototype_set), 2, mxID(_set), XS_DONT_ENUM_FLAG);
146
- slot = fxNextStringXProperty(the, slot, "WeakMap", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
147
- mxWeakMapPrototype = *the->stack;
148
- slot = fxBuildHostConstructor(the, mxCallback(fx_WeakMap), 0, mxID(_WeakMap));
149
- mxWeakMapConstructor = *the->stack;
150
- mxPop();
151
-
152
- /* WEAK SET */
153
- mxPush(mxObjectPrototype);
154
- slot = fxLastProperty(the, fxNewObjectInstance(the));
155
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakSet_prototype_add), 1, mxID(_add), XS_DONT_ENUM_FLAG);
156
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakSet_prototype_delete), 1, mxID(_delete), XS_DONT_ENUM_FLAG);
157
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakSet_prototype_has), 1, mxID(_has), XS_DONT_ENUM_FLAG);
158
- slot = fxNextStringXProperty(the, slot, "WeakSet", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
159
- mxWeakSetPrototype = *the->stack;
160
- slot = fxBuildHostConstructor(the, mxCallback(fx_WeakSet), 0, mxID(_WeakSet));
161
- mxWeakSetConstructor = *the->stack;
162
- mxPop();
163
-
164
- /* WEAK REF */
165
- mxPush(mxObjectPrototype);
166
- slot = fxLastProperty(the, fxNewObjectInstance(the));
167
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_WeakRef_prototype_deref), 0, mxID(_deref), XS_DONT_ENUM_FLAG);
168
- slot = fxNextStringXProperty(the, slot, "WeakRef", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
169
- mxWeakRefPrototype = *the->stack;
170
- slot = fxBuildHostConstructor(the, mxCallback(fx_WeakRef), 1, mxID(_WeakRef));
171
- mxWeakRefConstructor = *the->stack;
172
- mxPop();
173
-
174
- /* FINALIZATION REGISTRY */
175
- mxPush(mxObjectPrototype);
176
- slot = fxLastProperty(the, fxNewObjectInstance(the));
177
- // slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_FinalizationRegistry_prototype_cleanupSome), 0, mxID(_cleanupSome), XS_DONT_ENUM_FLAG);
178
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_FinalizationRegistry_prototype_register), 2, mxID(_register), XS_DONT_ENUM_FLAG);
179
- slot = fxNextHostFunctionProperty(the, slot, mxCallback(fx_FinalizationRegistry_prototype_unregister), 1, mxID(_unregister), XS_DONT_ENUM_FLAG);
180
- slot = fxNextStringXProperty(the, slot, "FinalizationRegistry", mxID(_Symbol_toStringTag), XS_DONT_ENUM_FLAG | XS_DONT_SET_FLAG);
181
- mxFinalizationRegistryPrototype = *the->stack;
182
- slot = fxBuildHostConstructor(the, mxCallback(fx_FinalizationRegistry), 1, mxID(_FinalizationRegistry));
183
- mxFinalizationRegistryConstructor = *the->stack;
184
- mxPop();
185
- }
186
-
187
- txSlot* fxCheckMapInstance(txMachine* the, txSlot* slot, txBoolean mutable)
188
- {
189
- if (slot->kind == XS_REFERENCE_KIND) {
190
- txSlot* instance = slot->value.reference;
191
- if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_MAP_KIND) && (instance != mxMapPrototype.value.reference)) {
192
- if (mutable && (slot->flag & XS_DONT_SET_FLAG))
193
- mxTypeError("Map instance is read-only");
194
- return instance;
195
- }
196
- }
197
- mxTypeError("this is no Map instance");
198
- return C_NULL;
199
- }
200
-
201
- txSlot* fxCheckMapKey(txMachine* the)
202
- {
203
- if (mxArgc > 0) {
204
- txSlot* slot = mxArgv(0);
205
- return slot;
206
- }
207
- mxTypeError("no key");
208
- return C_NULL;
209
- }
210
-
211
- txSlot* fxNewMapInstance(txMachine* the)
212
- {
213
- txSlot* map;
214
- txSlot* table;
215
- txSlot* list;
216
- txSlot* size;
217
- txSlot** address;
218
- map = fxNewSlot(the);
219
- map->kind = XS_INSTANCE_KIND;
220
- map->value.instance.garbage = C_NULL;
221
- map->value.instance.prototype = the->stack->value.reference;
222
- the->stack->kind = XS_REFERENCE_KIND;
223
- the->stack->value.reference = map;
224
- table = map->next = fxNewSlot(the);
225
- list = table->next = fxNewSlot(the);
226
- size = list->next = fxNewSlot(the);
227
- address = (txSlot**)fxNewChunk(the, mxTableMinLength * sizeof(txSlot*));
228
- c_memset(address, 0, mxTableMinLength * sizeof(txSlot*));
229
- /* TABLE */
230
- table->flag = XS_INTERNAL_FLAG;
231
- table->kind = XS_MAP_KIND;
232
- table->value.table.address = address;
233
- table->value.table.length = mxTableMinLength;
234
- /* LIST */
235
- list->flag = XS_INTERNAL_FLAG;
236
- list->kind = XS_LIST_KIND;
237
- list->value.list.first = C_NULL;
238
- list->value.list.last = C_NULL;
239
- /* SIZE */
240
- size->flag = XS_INTERNAL_FLAG;
241
- size->kind = XS_INTEGER_KIND;
242
- size->value.integer = 0;
243
- return map;
244
- }
245
-
246
- void fx_Map(txMachine* the)
247
- {
248
- txSlot *function, *iterable, *iterator, *next, *value;
249
- if (mxIsUndefined(mxTarget))
250
- mxTypeError("call: Map");
251
- mxPushSlot(mxTarget);
252
- fxGetPrototypeFromConstructor(the, &mxMapPrototype);
253
- fxNewMapInstance(the);
254
- mxPullSlot(mxResult);
255
- if (mxArgc < 1)
256
- return;
257
- iterable = mxArgv(0);
258
- if ((iterable->kind == XS_UNDEFINED_KIND) || (iterable->kind == XS_NULL_KIND))
259
- return;
260
- mxPushSlot(mxResult);
261
- mxGetID(mxID(_set));
262
- function = the->stack;
263
- if (!fxIsCallable(the, function))
264
- mxTypeError("set is no function");
265
- mxTemporary(iterator);
266
- mxTemporary(next);
267
- fxGetIterator(the, iterable, iterator, next, 0);
268
- mxTemporary(value);
269
- while (fxIteratorNext(the, iterator, next, value)) {
270
- mxTry(the) {
271
- if (value->kind != XS_REFERENCE_KIND)
272
- mxTypeError("item is no object");
273
- mxPushSlot(mxResult);
274
- mxPushSlot(function);
275
- mxCall();
276
- mxPushSlot(value);
277
- mxGetIndex(0);
278
- mxPushSlot(value);
279
- mxGetIndex(1);
280
- mxRunCount(2);
281
- mxPop();
282
- }
283
- mxCatch(the) {
284
- fxIteratorReturn(the, iterator);
285
- fxJump(the);
286
- }
287
- }
288
- }
289
-
290
- void fx_Map_prototype_clear(txMachine* the)
291
- {
292
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_MUTABLE);
293
- txSlot* table = instance->next;
294
- txSlot* list = table->next;
295
- fxClearEntries(the, table, list, 1);
296
- }
297
-
298
- void fx_Map_prototype_delete(txMachine* the)
299
- {
300
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_MUTABLE);
301
- txSlot* table = instance->next;
302
- txSlot* list = table->next;
303
- txSlot* key = fxCheckMapKey(the);
304
- mxResult->value.boolean = fxDeleteEntry(the, table, list, key, 1);
305
- mxResult->kind = XS_BOOLEAN_KIND;
306
- }
307
-
308
- void fx_Map_prototype_entries(txMachine* the)
309
- {
310
- fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
311
- fxNewMapIteratorInstance(the, mxThis, 2);
312
- }
313
-
314
- void fx_Map_prototype_forEach(txMachine* the)
315
- {
316
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
317
- txSlot* table = instance->next;
318
- txSlot* list = table->next;
319
- txSlot* function = fxArgToCallback(the, 0);
320
- txSlot* key;
321
- txSlot* value;
322
- mxPushList();
323
- key = the->stack->value.list.first = list->value.list.first;
324
- while (key) {
325
- value = key->next;
326
- if (!(key->flag & XS_DONT_ENUM_FLAG)) {
327
- /* THIS */
328
- if (mxArgc > 1)
329
- mxPushSlot(mxArgv(1));
330
- else
331
- mxPushUndefined();
332
- /* FUNCTION */
333
- mxPushSlot(function);
334
- mxCall();
335
- /* ARGUMENTS */
336
- mxPushSlot(value);
337
- mxPushSlot(key);
338
- mxPushSlot(mxThis);
339
- mxRunCount(3);
340
- mxPop();
341
- }
342
- key = the->stack->value.list.first = value->next;
343
- }
344
- mxPop();
345
- }
346
-
347
- void fx_Map_prototype_get(txMachine* the)
348
- {
349
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
350
- txSlot* table = instance->next;
351
- txSlot* key = fxCheckMapKey(the);
352
- txSlot* result = fxGetEntry(the, table, key);
353
- if (result) {
354
- txSlot* value = result->next;
355
- mxResult->kind = value->kind;
356
- mxResult->value = value->value;
357
- }
358
- }
359
-
360
- void fx_Map_prototype_has(txMachine* the)
361
- {
362
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
363
- txSlot* table = instance->next;
364
- txSlot* key = fxCheckMapKey(the);
365
- txSlot* result = fxGetEntry(the, table, key);
366
- mxResult->kind = XS_BOOLEAN_KIND;
367
- mxResult->value.boolean = (result) ? 1 : 0;
368
- }
369
-
370
- void fx_Map_prototype_keys(txMachine* the)
371
- {
372
- fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
373
- fxNewMapIteratorInstance(the, mxThis, 0);
374
- }
375
-
376
- void fx_Map_prototype_set(txMachine* the)
377
- {
378
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_MUTABLE);
379
- txSlot* table = instance->next;
380
- txSlot* list = table->next;
381
- txSlot* key = fxCheckMapKey(the);
382
- fxSetEntry(the, table, list, key, (mxArgc > 1) ? mxArgv(1) : &mxUndefined);
383
- *mxResult = *mxThis;
384
- }
385
-
386
- void fx_Map_prototype_size(txMachine* the)
387
- {
388
- txSlot* instance = fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
389
- txSlot* table = instance->next;
390
- txSlot* list = table->next;
391
- mxResult->kind = XS_INTEGER_KIND;
392
- mxResult->value.integer = list->next->value.integer;
393
- }
394
-
395
- void fx_Map_prototype_values(txMachine* the)
396
- {
397
- fxCheckMapInstance(the, mxThis, XS_IMMUTABLE);
398
- fxNewMapIteratorInstance(the, mxThis, 1);
399
- }
400
-
401
- txSlot* fxNewMapIteratorInstance(txMachine* the, txSlot* iterable, txInteger kind)
402
- {
403
- txSlot* instance;
404
- txSlot* property;
405
- mxPush(mxMapIteratorPrototype);
406
- instance = fxNewIteratorInstance(the, iterable, mxID(_Map));
407
- property = fxLastProperty(the, instance);
408
- property->kind = XS_LIST_KIND;
409
- property->value.list.first = C_NULL;
410
- property->value.list.last = C_NULL;
411
- property = fxNextIntegerProperty(the, property, kind, XS_NO_ID, XS_INTERNAL_FLAG);
412
- mxPullSlot(mxResult);
413
- return instance;
414
- }
415
-
416
- void fx_MapIterator_prototype_next(txMachine* the)
417
- {
418
- txSlot* iterator = fxCheckIteratorInstance(the, mxThis, mxID(_Map));
419
- txSlot* result = iterator->next;
420
- txSlot* iterable = result->next;
421
- mxResult->kind = result->kind;
422
- mxResult->value = result->value;
423
- result = fxCheckIteratorResult(the, result);
424
- if (result->next->value.boolean == 0) {
425
- txSlot* list = iterable->next;
426
- txInteger kind = list->next->value.integer;
427
- txSlot* key = list->value.list.first;
428
- if (key)
429
- key = key->next->next;
430
- else
431
- key = iterable->value.reference->next->next->value.list.first;
432
- while (key && (key->flag & XS_DONT_ENUM_FLAG))
433
- key = key->next->next;
434
- if (key) {
435
- txSlot* value = key->next;
436
- if (kind == 2) {
437
- mxPushSlot(key);
438
- mxPushSlot(value);
439
- fxConstructArrayEntry(the, result);
440
- }
441
- else if (kind == 1) {
442
- result->kind = value->kind;
443
- result->value = value->value;
444
- }
445
- else {
446
- result->kind = key->kind;
447
- result->value = key->value;
448
- }
449
- list->value.list.first = key;
450
- }
451
- else {
452
- result->kind = XS_UNDEFINED_KIND;
453
- result->next->value.boolean = 1;
454
- list->value.list.first = C_NULL;
455
- }
456
- }
457
- }
458
-
459
- txSlot* fxCheckSetInstance(txMachine* the, txSlot* slot, txBoolean mutable)
460
- {
461
- if (slot->kind == XS_REFERENCE_KIND) {
462
- txSlot* instance = slot->value.reference;
463
- if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_SET_KIND) && (instance != mxSetPrototype.value.reference)) {
464
- if (mutable && (slot->flag & XS_DONT_SET_FLAG))
465
- mxTypeError("Set instance is read-only");
466
- return instance;
467
- }
468
- }
469
- mxTypeError("this is no Set instance");
470
- return C_NULL;
471
- }
472
-
473
- txSlot* fxCheckSetValue(txMachine* the)
474
- {
475
- if (mxArgc > 0) {
476
- txSlot* slot = mxArgv(0);
477
- return slot;
478
- }
479
- mxTypeError("no value");
480
- return C_NULL;
481
- }
482
-
483
- txSlot* fxNewSetInstance(txMachine* the)
484
- {
485
- txSlot* set;
486
- txSlot* table;
487
- txSlot* list;
488
- txSlot* size;
489
- txSlot** address;
490
- set = fxNewSlot(the);
491
- set->kind = XS_INSTANCE_KIND;
492
- set->value.instance.garbage = C_NULL;
493
- set->value.instance.prototype = the->stack->value.reference;
494
- the->stack->kind = XS_REFERENCE_KIND;
495
- the->stack->value.reference = set;
496
- table = set->next = fxNewSlot(the);
497
- list = table->next = fxNewSlot(the);
498
- size = list->next = fxNewSlot(the);
499
- address = (txSlot**)fxNewChunk(the, mxTableMinLength * sizeof(txSlot*));
500
- c_memset(address, 0, mxTableMinLength * sizeof(txSlot*));
501
- /* TABLE */
502
- table->flag = XS_INTERNAL_FLAG;
503
- table->kind = XS_SET_KIND;
504
- table->value.table.address = address;
505
- table->value.table.length = mxTableMinLength;
506
- /* LIST */
507
- list->flag = XS_INTERNAL_FLAG;
508
- list->kind = XS_LIST_KIND;
509
- list->value.list.first = C_NULL;
510
- list->value.list.last = C_NULL;
511
- /* SIZE */
512
- size->flag = XS_INTERNAL_FLAG;
513
- size->kind = XS_INTEGER_KIND;
514
- size->value.integer = 0;
515
- return set;
516
- }
517
-
518
- void fx_Set(txMachine* the)
519
- {
520
- txSlot *function, *iterable, *iterator, *next, *value;
521
- if (mxIsUndefined(mxTarget))
522
- mxTypeError("call: Set");
523
- mxPushSlot(mxTarget);
524
- fxGetPrototypeFromConstructor(the, &mxSetPrototype);
525
- fxNewSetInstance(the);
526
- mxPullSlot(mxResult);
527
- if (mxArgc < 1)
528
- return;
529
- iterable = mxArgv(0);
530
- if ((iterable->kind == XS_UNDEFINED_KIND) || (iterable->kind == XS_NULL_KIND))
531
- return;
532
- mxPushSlot(mxResult);
533
- mxGetID(mxID(_add));
534
- function = the->stack;
535
- if (!fxIsCallable(the, function))
536
- mxTypeError("add is no function");
537
- mxTemporary(iterator);
538
- mxTemporary(next);
539
- fxGetIterator(the, iterable, iterator, next, 0);
540
- mxTemporary(value);
541
- while (fxIteratorNext(the, iterator, next, value)) {
542
- mxTry(the) {
543
- mxPushSlot(mxResult);
544
- mxPushSlot(function);
545
- mxCall();
546
- mxPushSlot(value);
547
- mxRunCount(1);
548
- mxPop();
549
- }
550
- mxCatch(the) {
551
- fxIteratorReturn(the, iterator);
552
- fxJump(the);
553
- }
554
- }
555
- }
556
-
557
- void fx_Set_prototype_add(txMachine* the)
558
- {
559
- txSlot* instance = fxCheckSetInstance(the, mxThis, XS_MUTABLE);
560
- txSlot* table = instance->next;
561
- txSlot* list = table->next;
562
- txSlot* value = fxCheckSetValue(the);
563
- fxSetEntry(the, table, list, value, C_NULL);
564
- *mxResult = *mxThis;
565
- }
566
-
567
- void fx_Set_prototype_clear(txMachine* the)
568
- {
569
- txSlot* instance = fxCheckSetInstance(the, mxThis, XS_MUTABLE);
570
- txSlot* table = instance->next;
571
- txSlot* list = table->next;
572
- fxClearEntries(the, table, list, 0);
573
- }
574
-
575
- void fx_Set_prototype_delete(txMachine* the)
576
- {
577
- txSlot* instance = fxCheckSetInstance(the, mxThis, XS_MUTABLE);
578
- txSlot* table = instance->next;
579
- txSlot* list = table->next;
580
- txSlot* value = fxCheckSetValue(the);
581
- mxResult->value.boolean = fxDeleteEntry(the, table, list, value, 0);
582
- mxResult->kind = XS_BOOLEAN_KIND;
583
- }
584
-
585
- void fx_Set_prototype_entries(txMachine* the)
586
- {
587
- fxCheckSetInstance(the, mxThis, XS_IMMUTABLE);
588
- fxNewSetIteratorInstance(the, mxThis, 2);
589
- }
590
-
591
- void fx_Set_prototype_forEach(txMachine* the)
592
- {
593
- txSlot* instance = fxCheckSetInstance(the, mxThis, XS_IMMUTABLE);
594
- txSlot* table = instance->next;
595
- txSlot* list = table->next;
596
- txSlot* function = fxArgToCallback(the, 0);
597
- txSlot* value;
598
- mxPushList();
599
- value = the->stack->value.list.first = list->value.list.first;
600
- while (value) {
601
- if (!(value->flag & XS_DONT_ENUM_FLAG)) {
602
- /* THIS */
603
- if (mxArgc > 1)
604
- mxPushSlot(mxArgv(1));
605
- else
606
- mxPushUndefined();
607
- /* FUNCTION */
608
- mxPushSlot(function);
609
- mxCall();
610
- /* ARGUMENTS */
611
- mxPushSlot(value);
612
- mxPushSlot(value);
613
- mxPushSlot(mxThis);
614
- mxRunCount(3);
615
- mxPop();
616
- }
617
- value = the->stack->value.list.first = value->next;
618
- }
619
- mxPop();
620
- }
621
-
622
- void fx_Set_prototype_has(txMachine* the)
623
- {
624
- txSlot* instance = fxCheckSetInstance(the, mxThis, XS_IMMUTABLE);
625
- txSlot* table = instance->next;
626
- txSlot* value = fxCheckSetValue(the);
627
- txSlot* result = fxGetEntry(the, table, value);
628
- mxResult->kind = XS_BOOLEAN_KIND;
629
- mxResult->value.boolean = (result) ? 1 : 0;
630
- }
631
-
632
- void fx_Set_prototype_size(txMachine* the)
633
- {
634
- txSlot* instance = fxCheckSetInstance(the, mxThis, XS_IMMUTABLE);
635
- txSlot* table = instance->next;
636
- txSlot* list = table->next;
637
- mxResult->kind = XS_INTEGER_KIND;
638
- mxResult->value.integer = list->next->value.integer;
639
- }
640
-
641
- void fx_Set_prototype_values(txMachine* the)
642
- {
643
- fxCheckSetInstance(the, mxThis, XS_IMMUTABLE);
644
- fxNewSetIteratorInstance(the, mxThis, 1);
645
- }
646
-
647
- txSlot* fxNewSetIteratorInstance(txMachine* the, txSlot* iterable, txInteger kind)
648
- {
649
- txSlot* instance;
650
- txSlot* property;
651
- mxPush(mxSetIteratorPrototype);
652
- instance = fxNewIteratorInstance(the, iterable, mxID(_Set));
653
- property = fxLastProperty(the, instance);
654
- property->kind = XS_LIST_KIND;
655
- property->value.list.first = C_NULL;
656
- property->value.list.last = C_NULL;
657
- property = fxNextIntegerProperty(the, property, kind, XS_NO_ID, XS_INTERNAL_FLAG);
658
- mxPullSlot(mxResult);
659
- return instance;
660
- }
661
-
662
- void fx_SetIterator_prototype_next(txMachine* the)
663
- {
664
- txSlot* iterator = fxCheckIteratorInstance(the, mxThis, mxID(_Set));
665
- txSlot* result = iterator->next;
666
- txSlot* iterable = result->next;
667
- mxResult->kind = result->kind;
668
- mxResult->value = result->value;
669
- result = fxCheckIteratorResult(the, result);
670
- if (result->next->value.boolean == 0) {
671
- txSlot* list = iterable->next;
672
- txInteger kind = list->next->value.integer;
673
- txSlot* value = list->value.list.first;
674
- if (value)
675
- value = value->next;
676
- else
677
- value = iterable->value.reference->next->next->value.list.first;
678
- while (value && (value->flag & XS_DONT_ENUM_FLAG))
679
- value = value->next;
680
- if (value) {
681
- if (kind == 2) {
682
- mxPushSlot(value);
683
- mxPushSlot(value);
684
- fxConstructArrayEntry(the, result);
685
- }
686
- else {
687
- result->kind = value->kind;
688
- result->value = value->value;
689
- }
690
- list->value.list.first = value;
691
- }
692
- else {
693
- result->kind = XS_UNDEFINED_KIND;
694
- result->next->value.boolean = 1;
695
- list->value.list.first = C_NULL;
696
- }
697
- }
698
- }
699
-
700
- void fxClearEntries(txMachine* the, txSlot* table, txSlot* list, txBoolean paired)
701
- {
702
- txSlot* slot = list->value.list.first;
703
- while (slot) {
704
- slot->flag = XS_DONT_ENUM_FLAG;
705
- slot->kind = XS_UNDEFINED_KIND;
706
- slot = slot->next;
707
- }
708
- c_memset(table->value.table.address, 0, table->value.table.length * sizeof(txSlot*));
709
- list->next->value.integer = 0;
710
- fxResizeEntries(the, table, list);
711
- fxPurgeEntries(the, list);
712
- }
713
-
714
- txBoolean fxDeleteEntry(txMachine* the, txSlot* table, txSlot* list, txSlot* key, txBoolean paired)
715
- {
716
- txSlot* info = list->next;
717
- txU4 sum = fxSumEntry(the, key);
718
- txU4 index = sum & (table->value.table.length - 1);
719
- txSlot** address = &(table->value.table.address[index]);
720
- txSlot* entry;
721
- txSlot* first;
722
- txSlot* last;
723
- while ((entry = *address)) {
724
- if (entry->value.entry.sum == sum) {
725
- first = entry->value.entry.slot;
726
- if (fxTestEntry(the, first, key)) {
727
- *address = entry->next;
728
- entry->next = C_NULL;
729
- first->flag = XS_DONT_ENUM_FLAG;
730
- first->kind = XS_UNDEFINED_KIND;
731
- if (paired) {
732
- last = first->next;
733
- last->flag = XS_DONT_ENUM_FLAG;
734
- last->kind = XS_UNDEFINED_KIND;
735
- }
736
- info->value.integer--;
737
- fxResizeEntries(the, table, list);
738
- fxPurgeEntries(the, list);
739
- return 1;
740
- }
741
- }
742
- address = &entry->next;
743
- }
744
- return 0;
745
- }
746
-
747
- txSlot* fxGetEntry(txMachine* the, txSlot* table, txSlot* slot)
748
- {
749
- txU4 sum = fxSumEntry(the, slot);
750
- txU4 index = sum & (table->value.table.length - 1);
751
- txSlot* entry = table->value.table.address[index];
752
- txSlot* result;
753
- while (entry) {
754
- if (entry->value.entry.sum == sum) {
755
- result = entry->value.entry.slot;
756
- if (fxTestEntry(the, result, slot))
757
- return result;
758
- }
759
- entry = entry->next;
760
- }
761
- return C_NULL;
762
- }
763
-
764
- void fxPurgeEntries(txMachine* the, txSlot* list)
765
- {
766
- txSlot* former = C_NULL;
767
- txSlot** address = &(list->value.list.first);
768
- txSlot* slot;
769
- while ((slot = *address)) {
770
- if (slot->flag & XS_DONT_ENUM_FLAG) {
771
- *address = slot->next;
772
- }
773
- else {
774
- former = slot;
775
- address = &slot->next;
776
- }
777
- }
778
- list->value.list.last = former;
779
- }
780
-
781
- void fxResizeEntries(txMachine* the, txSlot* table, txSlot* list)
782
- {
783
- txSize size = list->next->value.integer;
784
- txSize formerLength = table->value.table.length;
785
- txSize currentLength = formerLength;
786
- txSize high = mxTableThreshold(formerLength);
787
- txSize low = mxTableThreshold(formerLength) >> 1;
788
- if (high < size) {
789
- currentLength = formerLength << 1;
790
- if (currentLength > mxTableMaxLength)
791
- currentLength = mxTableMaxLength;
792
- }
793
- else if (low >= size) {
794
- currentLength = formerLength >> 1;
795
- if (currentLength < mxTableMinLength)
796
- currentLength = mxTableMinLength;
797
- }
798
- if (formerLength != currentLength) {
799
- txSlot** currentAddress = (txSlot**)fxNewChunk(the, currentLength * sizeof(txSlot*));
800
- if (currentAddress) {
801
- txSlot** formerAddress = table->value.table.address;
802
-
803
- txSize currentMask = currentLength - 1;
804
- c_memset(currentAddress, 0, currentLength * sizeof(txSlot*));
805
- while (formerLength) {
806
- txSlot* entry;
807
- while ((entry = *formerAddress)) {
808
- txU4 index = entry->value.entry.sum & currentMask;
809
- *formerAddress = entry->next;
810
- entry->next = currentAddress[index];
811
- currentAddress[index] = entry;
812
- }
813
- formerLength--;
814
- formerAddress++;
815
- }
816
- table->value.table.address = currentAddress;
817
- table->value.table.length = currentLength;
818
- }
819
- }
820
- // {
821
- // txSize holes = 0;
822
- // txSize collisions = 0;
823
- // txSize i = 0;
824
- // while (i < table->value.table.length) {
825
- // txSize j = 0;
826
- // txSlot* entry = table->value.table.address[i];
827
- // while (entry) {
828
- // j++;
829
- // entry = entry->next;
830
- // }
831
- // if (j == 0)
832
- // holes++;
833
- // else if (collisions < j)
834
- // collisions = j;
835
- // i++;
836
- // }
837
- // fprintf(stderr, "# size %d capacity %d holes %d collisions <%d\n", size, table->value.table.length, holes, collisions);
838
- // }
839
- }
840
-
841
- void fxSetEntry(txMachine* the, txSlot* table, txSlot* list, txSlot* key, txSlot* pair)
842
- {
843
- txU4 sum = fxSumEntry(the, key);
844
- txU4 index = sum & (table->value.table.length - 1);
845
- txSlot** address = &(table->value.table.address[index]);
846
- txSlot* entry = *address;
847
- txSlot* first;
848
- txSlot* last;
849
- while (entry) {
850
- if (entry->value.entry.sum == sum) {
851
- first = entry->value.entry.slot;
852
- if (fxTestEntry(the, first, key)) {
853
- if (pair) {
854
- last = first->next;
855
- last->kind = pair->kind;
856
- last->value = pair->value;
857
- }
858
- return;
859
- }
860
- }
861
- entry = entry->next;
862
- }
863
- first = fxNewSlot(the);
864
- first->kind = key->kind;
865
- first->value = key->value;
866
- mxPushClosure(first);
867
- if (pair) {
868
- first->next = last = fxNewSlot(the);
869
- last->kind = pair->kind;
870
- last->value = pair->value;
871
- mxPushClosure(last);
872
- }
873
- entry = fxNewSlot(the);
874
- address = &(table->value.table.address[index]);
875
- entry->next = *address;
876
- entry->kind = XS_ENTRY_KIND;
877
- entry->value.entry.slot = first;
878
- entry->value.entry.sum = sum;
879
- *address = entry;
880
- if (list->value.list.last)
881
- list->value.list.last->next = first;
882
- else
883
- list->value.list.first = first;
884
- if (pair)
885
- list->value.list.last = last;
886
- else
887
- list->value.list.last = first;
888
- if (pair)
889
- mxPop();
890
- mxPop();
891
- list->next->value.integer++;
892
- fxResizeEntries(the, table, list);
893
- }
894
-
895
- txU4 fxSumEntry(txMachine* the, txSlot* slot)
896
- {
897
- txU1 kind = slot->kind;
898
- txU8 sum;
899
-
900
- if ((XS_STRING_KIND == kind) || (XS_STRING_X_KIND == kind)) {
901
- // Dan Bernstein: http://www.cse.yorku.ca/~oz/hash.html
902
- txU1 *string = (txU1*)slot->value.string;
903
- sum = 5381;
904
- while ((kind = c_read8(string++))) {
905
- sum = ((sum << 5) + sum) + kind;
906
- }
907
- }
908
- else {
909
- if (XS_REFERENCE_KIND == kind) {
910
- txSlot* base = C_NULL;
911
- sum = slot->value.reference - base;
912
- }
913
- else if (XS_INTEGER_KIND == kind) {
914
- fxToNumber(the, slot);
915
- sum = *((txU8*)&slot->value.number);
916
- }
917
- else if (XS_NUMBER_KIND == kind) {
918
- if (slot->value.number == 0)
919
- slot->value.number = 0;
920
- else if (c_isnan(slot->value.number))
921
- slot->value.number = C_NAN;
922
- sum = *((txU8*)&slot->value.number);
923
- }
924
- else if ((XS_BIGINT_KIND == kind) || (XS_BIGINT_X_KIND == kind)) {
925
- sum = fxToBigUint64(the, slot);
926
- }
927
- else if (XS_SYMBOL_KIND == kind) {
928
- sum = slot->value.symbol;
929
- }
930
- else if (XS_BOOLEAN_KIND == kind) {
931
- sum = slot->value.boolean;
932
- }
933
- else {
934
- sum = 0;
935
- }
936
- // Thomas Wang: http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
937
- sum = (~sum) + (sum << 18); // sum = (sum << 18) - sum - 1;
938
- sum = sum ^ (sum >> 31);
939
- sum = sum * 21; // sum = (sum + (sum << 2)) + (sum << 4);
940
- sum = sum ^ (sum >> 11);
941
- sum = sum + (sum << 6);
942
- sum = sum ^ (sum >> 22);
943
- }
944
- sum &= 0xFFFFFFFF;
945
- return (txU4)sum;
946
- }
947
-
948
- txBoolean fxTestEntry(txMachine* the, txSlot* a, txSlot* b)
949
- {
950
- txBoolean result = 0;
951
- if (a->kind == b->kind) {
952
- if ((XS_UNDEFINED_KIND == a->kind) || (XS_NULL_KIND == a->kind))
953
- result = 1;
954
- else if (XS_BOOLEAN_KIND == a->kind)
955
- result = a->value.boolean == b->value.boolean;
956
- else if (XS_INTEGER_KIND == a->kind)
957
- result = a->value.integer == b->value.integer;
958
- else if (XS_NUMBER_KIND == a->kind)
959
- result = ((c_isnan(a->value.number) && c_isnan(b->value.number)) || (a->value.number == b->value.number));
960
- else if ((XS_STRING_KIND == a->kind) || (XS_STRING_X_KIND == a->kind))
961
- result = c_strcmp(a->value.string, b->value.string) == 0;
962
- else if (XS_SYMBOL_KIND == a->kind)
963
- result = a->value.symbol == b->value.symbol;
964
- else if ((XS_BIGINT_KIND == a->kind) || (XS_BIGINT_X_KIND == a->kind))
965
- result = gxTypeBigInt.compare(the, 0, 1, 0, a, b);
966
- else if (XS_REFERENCE_KIND == a->kind)
967
- result = a->value.reference == b->value.reference;
968
- }
969
- else if ((XS_INTEGER_KIND == a->kind) && (XS_NUMBER_KIND == b->kind))
970
- result = (!c_isnan(b->value.number)) && ((txNumber)(a->value.integer) == b->value.number);
971
- else if ((XS_NUMBER_KIND == a->kind) && (XS_INTEGER_KIND == b->kind))
972
- result = (!c_isnan(a->value.number)) && (a->value.number == (txNumber)(b->value.integer));
973
- else if ((XS_STRING_KIND == a->kind) && (XS_STRING_X_KIND == b->kind))
974
- result = c_strcmp(a->value.string, b->value.string) == 0;
975
- else if ((XS_STRING_X_KIND == a->kind) && (XS_STRING_KIND == b->kind))
976
- result = c_strcmp(a->value.string, b->value.string) == 0;
977
- else if ((XS_BIGINT_KIND == a->kind) && (XS_BIGINT_X_KIND == b->kind))
978
- result = gxTypeBigInt.compare(the, 0, 1, 0, a, b);
979
- else if ((XS_BIGINT_X_KIND == a->kind) && (XS_BIGINT_KIND == b->kind))
980
- result = gxTypeBigInt.compare(the, 0, 1, 0, a, b);
981
- return result;
982
- }
983
-
984
- txSlot* fxCheckWeakMapInstance(txMachine* the, txSlot* slot, txBoolean mutable)
985
- {
986
- if (slot->kind == XS_REFERENCE_KIND) {
987
- txSlot* instance = slot->value.reference;
988
- if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_WEAK_MAP_KIND) && (instance != mxWeakMapPrototype.value.reference)) {
989
- if (mutable && (slot->flag & XS_DONT_SET_FLAG))
990
- mxTypeError("WeakMap instance is read-only");
991
- return instance;
992
- }
993
- }
994
- mxTypeError("this is no WeakMap instance");
995
- return C_NULL;
996
- }
997
-
998
- txSlot* fxCheckWeakMapKey(txMachine* the, txBoolean mutable)
999
- {
1000
- if (mxArgc > 0) {
1001
- txSlot* slot = mxArgv(0);
1002
- if (slot->kind == XS_REFERENCE_KIND) {
1003
- if (mutable && (slot->value.reference->flag & XS_MARK_FLAG))
1004
- mxTypeError("WeakMap key is read-only");
1005
- return slot;
1006
- }
1007
- }
1008
- return C_NULL;
1009
- }
1010
-
1011
- txSlot* fxNewWeakMapInstance(txMachine* the)
1012
- {
1013
- txSlot* map;
1014
- txSlot* list;
1015
- map = fxNewSlot(the);
1016
- map->kind = XS_INSTANCE_KIND;
1017
- map->value.instance.garbage = C_NULL;
1018
- map->value.instance.prototype = the->stack->value.reference;
1019
- the->stack->kind = XS_REFERENCE_KIND;
1020
- the->stack->value.reference = map;
1021
- /* LIST */
1022
- list = map->next = fxNewSlot(the);
1023
- list->flag = XS_INTERNAL_FLAG;
1024
- list->kind = XS_WEAK_MAP_KIND;
1025
- list->value.weakList.first = C_NULL;
1026
- list->value.weakList.link = the->firstWeakListLink;
1027
- the->firstWeakListLink = list;
1028
- return map;
1029
- }
1030
-
1031
- void fx_WeakMap(txMachine* the)
1032
- {
1033
- txSlot *function, *iterable, *iterator, *next, *value;
1034
- if (mxIsUndefined(mxTarget))
1035
- mxTypeError("call: WeakMap");
1036
- mxPushSlot(mxTarget);
1037
- fxGetPrototypeFromConstructor(the, &mxWeakMapPrototype);
1038
- fxNewWeakMapInstance(the);
1039
- mxPullSlot(mxResult);
1040
- if (mxArgc < 1)
1041
- return;
1042
- iterable = mxArgv(0);
1043
- if ((iterable->kind == XS_UNDEFINED_KIND) || (iterable->kind == XS_NULL_KIND))
1044
- return;
1045
- mxPushSlot(mxResult);
1046
- mxGetID(mxID(_set));
1047
- function = the->stack;
1048
- if (!fxIsCallable(the, function))
1049
- mxTypeError("set is no function");
1050
- mxTemporary(iterator);
1051
- mxTemporary(next);
1052
- fxGetIterator(the, iterable, iterator, next, 0);
1053
- mxTemporary(value);
1054
- while (fxIteratorNext(the, iterator, next, value)) {
1055
- mxTry(the) {
1056
- mxPushSlot(mxResult);
1057
- mxPushSlot(function);
1058
- mxCall();
1059
- if (value->kind != XS_REFERENCE_KIND)
1060
- mxTypeError("item is no object");
1061
- mxPushSlot(value);
1062
- mxGetIndex(0);
1063
- mxPushSlot(value);
1064
- mxGetIndex(1);
1065
- mxRunCount(2);
1066
- mxPop();
1067
- }
1068
- mxCatch(the) {
1069
- fxIteratorReturn(the, iterator);
1070
- fxJump(the);
1071
- }
1072
- }
1073
- }
1074
-
1075
- void fx_WeakMap_prototype_delete(txMachine* the)
1076
- {
1077
- txSlot* instance = fxCheckWeakMapInstance(the, mxThis, XS_MUTABLE);
1078
- txSlot* key = fxCheckWeakMapKey(the, XS_MUTABLE);
1079
- mxResult->value.boolean = (key) ? fxDeleteWeakEntry(the, instance->next, key->value.reference) : 0;
1080
- mxResult->kind = XS_BOOLEAN_KIND;
1081
- }
1082
-
1083
- void fx_WeakMap_prototype_get(txMachine* the)
1084
- {
1085
- txSlot* instance = fxCheckWeakMapInstance(the, mxThis, XS_IMMUTABLE);
1086
- txSlot* key = fxCheckWeakMapKey(the, XS_IMMUTABLE);
1087
- txSlot* result = (key) ? fxGetWeakEntry(the, instance->next, key->value.reference) : C_NULL;
1088
- if (result) {
1089
- txSlot* value = result->value.weakEntry.value;
1090
- mxResult->kind = value->kind;
1091
- mxResult->value = value->value;
1092
- }
1093
- }
1094
-
1095
- void fx_WeakMap_prototype_has(txMachine* the)
1096
- {
1097
- txSlot* instance = fxCheckWeakMapInstance(the, mxThis, XS_IMMUTABLE);
1098
- txSlot* key = fxCheckWeakMapKey(the, XS_IMMUTABLE);
1099
- txSlot* result = (key) ? fxGetWeakEntry(the, instance->next, key->value.reference) : C_NULL;
1100
- mxResult->kind = XS_BOOLEAN_KIND;
1101
- mxResult->value.boolean = (result) ? 1 : 0;
1102
- }
1103
-
1104
- void fx_WeakMap_prototype_set(txMachine* the)
1105
- {
1106
- txSlot* instance = fxCheckWeakMapInstance(the, mxThis, XS_MUTABLE);
1107
- txSlot* key = fxCheckWeakMapKey(the, XS_MUTABLE);
1108
- if (!key)
1109
- mxTypeError("key is no object");
1110
- fxSetWeakEntry(the, instance->next, key->value.reference, (mxArgc > 1) ? mxArgv(1) : &mxUndefined);
1111
- *mxResult = *mxThis;
1112
- }
1113
-
1114
- txSlot* fxCheckWeakSetInstance(txMachine* the, txSlot* slot, txBoolean mutable)
1115
- {
1116
- if (slot->kind == XS_REFERENCE_KIND) {
1117
- txSlot* instance = slot->value.reference;
1118
- if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_WEAK_SET_KIND) && (instance != mxWeakSetPrototype.value.reference)) {
1119
- if (mutable && (slot->flag & XS_DONT_SET_FLAG))
1120
- mxTypeError("WeakSet instance is read-only");
1121
- return instance;
1122
- }
1123
- }
1124
- mxTypeError("this is no WeakSet instance");
1125
- return C_NULL;
1126
- }
1127
-
1128
- txSlot* fxCheckWeakSetValue(txMachine* the, txBoolean mutable)
1129
- {
1130
- if (mxArgc > 0) {
1131
- txSlot* slot = mxArgv(0);
1132
- if (slot->kind == XS_REFERENCE_KIND) {
1133
- if (mutable && (slot->value.reference->flag & XS_MARK_FLAG))
1134
- mxTypeError("WeakSet value is read-only");
1135
- return slot;
1136
- }
1137
- }
1138
- return C_NULL;
1139
- }
1140
-
1141
- txSlot* fxNewWeakSetInstance(txMachine* the)
1142
- {
1143
- txSlot* set;
1144
- txSlot* list;
1145
- set = fxNewSlot(the);
1146
- set->kind = XS_INSTANCE_KIND;
1147
- set->value.instance.garbage = C_NULL;
1148
- set->value.instance.prototype = the->stack->value.reference;
1149
- the->stack->kind = XS_REFERENCE_KIND;
1150
- the->stack->value.reference = set;
1151
- /* LIST */
1152
- list = set->next = fxNewSlot(the);
1153
- list->flag = XS_INTERNAL_FLAG;
1154
- list->kind = XS_WEAK_SET_KIND;
1155
- list->value.weakList.first = C_NULL;
1156
- list->value.weakList.link = the->firstWeakListLink;
1157
- the->firstWeakListLink = list;
1158
- return set;
1159
- }
1160
-
1161
- void fx_WeakSet(txMachine* the)
1162
- {
1163
- txSlot *function, *iterable, *iterator, *next, *value;
1164
- if (mxIsUndefined(mxTarget))
1165
- mxTypeError("call: WeakSet");
1166
- mxPushSlot(mxTarget);
1167
- fxGetPrototypeFromConstructor(the, &mxWeakSetPrototype);
1168
- fxNewWeakSetInstance(the);
1169
- mxPullSlot(mxResult);
1170
- if (mxArgc < 1)
1171
- return;
1172
- iterable = mxArgv(0);
1173
- if ((iterable->kind == XS_UNDEFINED_KIND) || (iterable->kind == XS_NULL_KIND))
1174
- return;
1175
- mxPushSlot(mxResult);
1176
- mxGetID(mxID(_add));
1177
- function = the->stack;
1178
- if (!fxIsCallable(the, function))
1179
- mxTypeError("add is no function");
1180
- mxTemporary(iterator);
1181
- mxTemporary(next);
1182
- fxGetIterator(the, iterable, iterator, next, 0);
1183
- mxTemporary(value);
1184
- while (fxIteratorNext(the, iterator, next, value)) {
1185
- mxTry(the) {
1186
- mxPushSlot(mxResult);
1187
- mxPushSlot(function);
1188
- mxCall();
1189
- mxPushSlot(value);
1190
- mxRunCount(1);
1191
- mxPop();
1192
- }
1193
- mxCatch(the) {
1194
- fxIteratorReturn(the, iterator);
1195
- fxJump(the);
1196
- }
1197
- }
1198
- }
1199
-
1200
- void fx_WeakSet_prototype_add(txMachine* the)
1201
- {
1202
- txSlot* instance = fxCheckWeakSetInstance(the, mxThis, XS_MUTABLE);
1203
- txSlot* value = fxCheckWeakSetValue(the, XS_MUTABLE);
1204
- if (!value)
1205
- mxTypeError("value is no object");
1206
- fxSetWeakEntry(the, instance->next, value->value.reference, &mxUndefined);
1207
- *mxResult = *mxThis;
1208
- }
1209
-
1210
- void fx_WeakSet_prototype_has(txMachine* the)
1211
- {
1212
- txSlot* instance = fxCheckWeakSetInstance(the, mxThis, XS_IMMUTABLE);
1213
- txSlot* value = fxCheckWeakSetValue(the, XS_IMMUTABLE);
1214
- txSlot* result = (value) ? fxGetWeakEntry(the, instance->next, value->value.reference) : C_NULL;
1215
- mxResult->kind = XS_BOOLEAN_KIND;
1216
- mxResult->value.boolean = (result) ? 1 : 0;
1217
- }
1218
-
1219
- void fx_WeakSet_prototype_delete(txMachine* the)
1220
- {
1221
- txSlot* instance = fxCheckWeakSetInstance(the, mxThis, XS_MUTABLE);
1222
- txSlot* value = fxCheckWeakSetValue(the, XS_MUTABLE);
1223
- mxResult->value.boolean = (value) ? fxDeleteWeakEntry(the, instance->next, value->value.reference) : 0;
1224
- mxResult->kind = XS_BOOLEAN_KIND;
1225
- }
1226
-
1227
- txBoolean fxDeleteWeakEntry(txMachine* the, txSlot* list, txSlot* key)
1228
- {
1229
- txSlot* slot = (key->flag & XS_EXOTIC_FLAG) ? key->next : key;
1230
- txSlot** address = &slot->next;
1231
- while ((slot = *address)) {
1232
- if (!(slot->flag & XS_INTERNAL_FLAG))
1233
- break;
1234
- if ((slot->kind == XS_WEAK_ENTRY_KIND) && (slot->value.weakEntry.check == list)) {
1235
- slot->value.weakEntry.value->kind = XS_UNINITIALIZED_KIND;
1236
- *address = slot->next;
1237
- return 1;
1238
- }
1239
- address = &slot->next;
1240
- }
1241
- return 0;
1242
- }
1243
-
1244
- txSlot* fxGetWeakEntry(txMachine* the, txSlot* list, txSlot* key)
1245
- {
1246
- txSlot* slot = (key->flag & XS_EXOTIC_FLAG) ? key->next : key;
1247
- slot = slot->next;
1248
- while (slot) {
1249
- if (!(slot->flag & XS_INTERNAL_FLAG))
1250
- break;
1251
- if ((slot->kind == XS_WEAK_ENTRY_KIND) && (slot->value.weakEntry.check == list))
1252
- return slot;
1253
- slot = slot->next;
1254
- }
1255
- return C_NULL;
1256
- }
1257
-
1258
- void fxSetWeakEntry(txMachine* the, txSlot* list, txSlot* key, txSlot* value)
1259
- {
1260
- txSlot* slot = (key->flag & XS_EXOTIC_FLAG) ? key->next : key;
1261
- txSlot** address = &slot->next;
1262
- txSlot* keyEntry;
1263
- txSlot* listEntry;
1264
- txSlot* closure;
1265
- while ((slot = *address)) {
1266
- if (!(slot->flag & XS_INTERNAL_FLAG))
1267
- break;
1268
- if ((slot->kind == XS_WEAK_ENTRY_KIND) && (slot->value.weakEntry.check == list)) {
1269
- slot = slot->value.weakEntry.value;
1270
- slot->kind = value->kind;
1271
- slot->value = value->value;
1272
- return;
1273
- }
1274
- address = &slot->next;
1275
- }
1276
-
1277
- keyEntry = fxNewSlot(the);
1278
- mxPushClosure(keyEntry);
1279
- listEntry = fxNewSlot(the);
1280
- mxPushClosure(listEntry);
1281
- closure = fxNewSlot(the);
1282
- closure->kind = value->kind;
1283
- closure->value = value->value;
1284
-
1285
- slot = (key->flag & XS_EXOTIC_FLAG) ? key->next : key;
1286
- address = &slot->next;
1287
- while ((slot = *address)) {
1288
- if (!(slot->flag & XS_INTERNAL_FLAG))
1289
- break;
1290
- address = &slot->next;
1291
- }
1292
-
1293
- keyEntry->next = *address;
1294
- keyEntry->flag = XS_INTERNAL_FLAG;
1295
- keyEntry->kind = XS_WEAK_ENTRY_KIND;
1296
- keyEntry->value.weakEntry.check = list;
1297
- keyEntry->value.weakEntry.value = closure;
1298
- *address = keyEntry;
1299
-
1300
- listEntry->next = list->value.weakList.first;
1301
- listEntry->flag = XS_INTERNAL_FLAG;
1302
- listEntry->kind = XS_WEAK_ENTRY_KIND;
1303
- listEntry->value.weakEntry.check = key;
1304
- listEntry->value.weakEntry.value = closure;
1305
- list->value.weakList.first = listEntry;
1306
-
1307
- mxPop();
1308
- mxPop();
1309
- }
1310
-
1311
- void fxKeepDuringJobs(txMachine* the, txSlot* target)
1312
- {
1313
- txSlot* instance = mxDuringJobs.value.reference;
1314
- txSlot** address = &(instance->next);
1315
- txSlot* slot;
1316
- while ((slot = *address)) {
1317
- if (slot->value.reference == target)
1318
- return;
1319
- address = &(slot->next);
1320
- }
1321
- *address = slot = fxNewSlot(the);
1322
- slot->value.reference = target;
1323
- slot->kind = XS_REFERENCE_KIND;
1324
- }
1325
-
1326
- txSlot* fxCheckWeakRefInstance(txMachine* the, txSlot* slot)
1327
- {
1328
- if (slot->kind == XS_REFERENCE_KIND) {
1329
- txSlot* instance = slot->value.reference;
1330
- if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_WEAK_REF_KIND))
1331
- return instance;
1332
- }
1333
- mxTypeError("this is no WeakRef instance");
1334
- return C_NULL;
1335
- }
1336
-
1337
- txSlot* fxNewWeakRefInstance(txMachine* the)
1338
- {
1339
- txSlot* slot;
1340
- txSlot* instance = fxNewSlot(the);
1341
- instance->kind = XS_INSTANCE_KIND;
1342
- instance->value.instance.garbage = C_NULL;
1343
- instance->value.instance.prototype = the->stack->value.reference;
1344
- the->stack->kind = XS_REFERENCE_KIND;
1345
- the->stack->value.reference = instance;
1346
- slot = instance->next = fxNewSlot(the);
1347
- slot->flag = XS_INTERNAL_FLAG;
1348
- slot->kind = XS_WEAK_REF_KIND;
1349
- slot->value.weakRef.target = C_NULL;
1350
- slot->value.weakRef.link = C_NULL;
1351
- return instance;
1352
- }
1353
-
1354
- void fx_WeakRef(txMachine* the)
1355
- {
1356
- txSlot* target;
1357
- txSlot* instance;
1358
- if (mxIsUndefined(mxTarget))
1359
- mxTypeError("call: WeakRef");
1360
- if (mxArgc < 1)
1361
- mxTypeError("new WeakRef: no target");
1362
- target = mxArgv(0);
1363
- if (!mxIsReference(target))
1364
- mxTypeError("new WeakRef: target is no object");
1365
- target = target->value.reference;
1366
- mxPushSlot(mxTarget);
1367
- fxGetPrototypeFromConstructor(the, &mxWeakRefPrototype);
1368
- instance = fxNewWeakRefInstance(the);
1369
- mxPullSlot(mxResult);
1370
- fxKeepDuringJobs(the, target);
1371
- instance->next->value.weakRef.target = target;
1372
- }
1373
-
1374
- void fx_WeakRef_prototype_deref(txMachine* the)
1375
- {
1376
- txSlot* instance = fxCheckWeakRefInstance(the, mxThis);
1377
- txSlot* target = instance->next->value.weakRef.target;
1378
- if (target) {
1379
- mxResult->value.reference = target;
1380
- mxResult->kind = XS_REFERENCE_KIND;
1381
- fxKeepDuringJobs(the, target);
1382
- }
1383
- }
1384
-
1385
- txSlot* fxCheckFinalizationRegistryInstance(txMachine* the, txSlot* slot)
1386
- {
1387
- if (slot->kind == XS_REFERENCE_KIND) {
1388
- txSlot* instance = slot->value.reference;
1389
- if (((slot = instance->next)) && (slot->flag & XS_INTERNAL_FLAG) && (slot->kind == XS_CLOSURE_KIND) && (slot->value.closure->kind == XS_FINALIZATION_REGISTRY_KIND)) {
1390
- if (slot->flag & XS_MARK_FLAG)
1391
- mxTypeError("FinalizationRegistry instance is read-only");
1392
- return instance;
1393
- }
1394
- }
1395
- mxTypeError("this is no FinalizationRegistry instance");
1396
- return C_NULL;
1397
- }
1398
-
1399
- void fx_FinalizationRegistry(txMachine* the)
1400
- {
1401
- txSlot* callback;
1402
- txSlot* instance;
1403
- txSlot* property;
1404
- txSlot* registry;
1405
- txSlot* slot;
1406
- if (mxIsUndefined(mxTarget))
1407
- mxTypeError("call: FinalizationRegistry");
1408
- if (mxArgc < 1)
1409
- mxTypeError("no callback");
1410
- callback = mxArgv(0);
1411
- if (!fxIsCallable(the, callback))
1412
- mxTypeError("callback is no function");
1413
- mxPushSlot(mxTarget);
1414
- fxGetPrototypeFromConstructor(the, &mxFinalizationRegistryPrototype);
1415
- instance = fxNewSlot(the);
1416
- instance->kind = XS_INSTANCE_KIND;
1417
- instance->value.instance.garbage = C_NULL;
1418
- instance->value.instance.prototype = the->stack->value.reference;
1419
- the->stack->kind = XS_REFERENCE_KIND;
1420
- the->stack->value.reference = instance;
1421
- mxPullSlot(mxResult);
1422
- property = instance->next = fxNewSlot(the);
1423
- property->flag = XS_INTERNAL_FLAG;
1424
- property->kind = XS_CLOSURE_KIND;
1425
- property->value.closure = C_NULL;
1426
- registry = fxNewSlot(the);
1427
- registry->kind = XS_FINALIZATION_REGISTRY_KIND;
1428
- registry->value.finalizationRegistry.callback = C_NULL;
1429
- registry->value.finalizationRegistry.flags = XS_NO_FLAG;
1430
- property->value.closure = registry;
1431
- slot = fxNewSlot(the);
1432
- slot->kind = callback->kind;
1433
- slot->value = callback->value;
1434
- registry->value.finalizationRegistry.callback = slot;
1435
- }
1436
-
1437
-
1438
- #if 0
1439
- // removed from FinalizationRegistry specification
1440
- void fx_FinalizationRegistry_prototype_cleanupSome(txMachine* the)
1441
- {
1442
- txSlot* instance;
1443
- txSlot* registry;
1444
- txSlot* callback = C_NULL;
1445
- txSlot** address;
1446
- txSlot* slot;
1447
- if (!mxIsReference(mxThis))
1448
- mxTypeError("this is no object");
1449
- instance = fxCheckFinalizationRegistryInstance(the, mxThis);
1450
- registry = instance->next->value.closure;
1451
- if (mxArgc > 0) {
1452
- callback = mxArgv(0);
1453
- if (mxIsUndefined(callback))
1454
- callback = C_NULL;
1455
- else if (!fxIsCallable(the, callback))
1456
- mxTypeError("callback is no function");
1457
- }
1458
- fx_FinalizationRegistryCleanup(the, registry, callback);
1459
- callback = registry->value.finalizationRegistry.callback;
1460
- if (callback->next == C_NULL) {
1461
- address = &(mxFinalizationRegistries.value.reference->next);
1462
- while ((slot = *address)) {
1463
- if (slot->value.closure == registry) {
1464
- *address = slot->next;
1465
- return;
1466
- }
1467
- address = &(slot->next);
1468
- }
1469
- }
1470
- }
1471
- #endif
1472
-
1473
- void fx_FinalizationRegistry_prototype_register(txMachine* the)
1474
- {
1475
- txSlot* instance;
1476
- txSlot* registry;
1477
- txSlot* target;
1478
- txSlot* token = C_NULL;
1479
- txSlot* callback;
1480
- txSlot** address;
1481
- txSlot* slot;
1482
- if (!mxIsReference(mxThis))
1483
- mxTypeError("this is no object");
1484
- instance = fxCheckFinalizationRegistryInstance(the, mxThis);
1485
- registry = instance->next->value.closure;
1486
- if (mxArgc < 1)
1487
- mxTypeError("no target");
1488
- target = mxArgv(0);
1489
- if (!mxIsReference(target))
1490
- mxTypeError("target is no object");
1491
- if (mxArgc > 1) {
1492
- if (fxIsSameValue(the, target, mxArgv(1), 1))
1493
- mxTypeError("target and holdings are the same");
1494
- }
1495
- target = target->value.reference;
1496
- if (mxArgc > 2) {
1497
- token = mxArgv(2);
1498
- if (mxIsUndefined(token))
1499
- token = C_NULL;
1500
- else if (mxIsReference(token))
1501
- token = token->value.reference;
1502
- else
1503
- mxTypeError("token is no object");
1504
- }
1505
- callback = registry->value.finalizationRegistry.callback;
1506
- address = &(callback->next);
1507
- while ((slot = *address))
1508
- address = &(slot->next);
1509
- slot = *address = fxNewSlot(the);
1510
- if (mxArgc > 1) {
1511
- slot->kind = mxArgv(1)->kind;
1512
- slot->value = mxArgv(1)->value;
1513
- }
1514
- slot = slot->next = fxNewSlot(the);
1515
- slot->kind = XS_FINALIZATION_CELL_KIND;
1516
- slot->value.finalizationCell.target = target;
1517
- slot->value.finalizationCell.token = token;
1518
-
1519
- address = &(mxFinalizationRegistries.value.reference->next);
1520
- while ((slot = *address)) {
1521
- if (slot->value.closure == registry)
1522
- return;
1523
- address = &(slot->next);
1524
- }
1525
- slot = *address = fxNewSlot(the);
1526
- slot->kind = XS_CLOSURE_KIND;
1527
- slot->value.closure = registry;
1528
- }
1529
-
1530
- void fx_FinalizationRegistry_prototype_unregister(txMachine* the)
1531
- {
1532
- txSlot* instance;
1533
- txSlot* token;
1534
- txSlot* registry;
1535
- txSlot* callback;
1536
- txSlot** address;
1537
- txSlot* slot;
1538
- if (!mxIsReference(mxThis))
1539
- mxTypeError("this is no object");
1540
- instance = fxCheckFinalizationRegistryInstance(the, mxThis);
1541
- if (mxArgc < 1)
1542
- mxTypeError("no token");
1543
- token = mxArgv(0);
1544
- if (!mxIsReference(token))
1545
- mxTypeError("token is no object");
1546
- token = token->value.reference;
1547
- mxResult->kind = XS_BOOLEAN_KIND;
1548
- mxResult->value.boolean = 0;
1549
- registry = instance->next->value.closure;
1550
- callback = registry->value.finalizationRegistry.callback;
1551
- address = &(callback->next);
1552
- while ((slot = *address)) {
1553
- slot = slot->next;
1554
- if (slot->value.finalizationCell.token && fxIsSameInstance(the, slot->value.finalizationCell.token, token)) {
1555
- *address = slot->next;
1556
- mxResult->value.boolean = 1;
1557
- }
1558
- else
1559
- address = &(slot->next);
1560
- }
1561
- if (callback->next == C_NULL) {
1562
- address = &(mxFinalizationRegistries.value.reference->next);
1563
- while ((slot = *address)) {
1564
- if (slot->value.closure == registry) {
1565
- *address = slot->next;
1566
- return;
1567
- }
1568
- address = &(slot->next);
1569
- }
1570
- }
1571
- }
1572
-
1573
- void fx_FinalizationRegistryCleanup(txMachine* the, txSlot* registry, txSlot* callback)
1574
- {
1575
- txSlot* slot;
1576
- txUnsigned flags;
1577
- txSlot** address;
1578
- txSlot* value;
1579
-
1580
- if (!(registry->value.finalizationRegistry.flags & XS_FINALIZATION_REGISTRY_CHANGED))
1581
- return;
1582
-
1583
- slot = registry->value.finalizationRegistry.callback->next;
1584
- flags = 0;
1585
- while (slot) {
1586
- slot = slot->next;
1587
- if (slot->value.finalizationCell.target == C_NULL) {
1588
- flags = 1;
1589
- break;
1590
- }
1591
- slot = slot->next;
1592
- }
1593
- if (!flags)
1594
- return;
1595
- if (!callback)
1596
- callback = registry->value.finalizationRegistry.callback;
1597
- flags = registry->value.finalizationRegistry.flags;
1598
- {
1599
- mxTry(the) {
1600
- address = &(registry->value.finalizationRegistry.callback->next);
1601
- while ((value = *address)) {
1602
- slot = value->next;
1603
- if (slot->value.finalizationCell.target == C_NULL) {
1604
- *address = slot->next;
1605
- mxPushUndefined();
1606
- mxPushSlot(callback);
1607
- mxCall();
1608
- mxPushSlot(value);
1609
- mxRunCount(1);
1610
- mxPop();
1611
- }
1612
- else
1613
- address = &(slot->next);
1614
- }
1615
- registry->value.finalizationRegistry.flags = flags;
1616
- }
1617
- mxCatch(the) {
1618
- registry->value.finalizationRegistry.flags = flags;
1619
- fxJump(the);
1620
- }
1621
- }
1622
-
1623
- slot = registry->value.finalizationRegistry.callback->next;
1624
- while (slot) {
1625
- slot = slot->next;
1626
- if (slot->value.finalizationCell.target == C_NULL)
1627
- break;
1628
- slot = slot->next;
1629
- }
1630
- if (!slot)
1631
- registry->value.finalizationRegistry.flags &= ~XS_FINALIZATION_REGISTRY_CHANGED;
1632
- }
1633
-
1634
- void fxCleanupFinalizationRegistries(txMachine* the)
1635
- {
1636
- txSlot** address = &(mxFinalizationRegistries.value.reference->next);
1637
- txSlot* closure;
1638
- while ((closure = *address)) {
1639
- txSlot* registry = closure->value.closure;
1640
- if (registry->value.finalizationRegistry.flags & XS_FINALIZATION_REGISTRY_CHANGED) {
1641
- fx_FinalizationRegistryCleanup(the, registry, C_NULL);
1642
- address = &(mxFinalizationRegistries.value.reference->next);
1643
- }
1644
- else
1645
- address = &(closure->next);
1646
- }
1647
- }
1648
-
1649
-