diff --git a/pages/coverage-reports/pages/1732654154983480898/base.css b/pages/coverage-reports/pages/1732654154983480898/base.css new file mode 100644 index 00000000..f418035b --- /dev/null +++ b/pages/coverage-reports/pages/1732654154983480898/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/pages/coverage-reports/pages/1732654154983480898/block-navigation.js b/pages/coverage-reports/pages/1732654154983480898/block-navigation.js new file mode 100644 index 00000000..cc121302 --- /dev/null +++ b/pages/coverage-reports/pages/1732654154983480898/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selecter that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/pages/coverage-reports/pages/1732654154983480898/favicon.png b/pages/coverage-reports/pages/1732654154983480898/favicon.png new file mode 100644 index 00000000..66918178 Binary files /dev/null and b/pages/coverage-reports/pages/1732654154983480898/favicon.png differ diff --git a/pages/coverage-reports/pages/1732654154983480898/index.html b/pages/coverage-reports/pages/1732654154983480898/index.html new file mode 100644 index 00000000..64615127 --- /dev/null +++ b/pages/coverage-reports/pages/1732654154983480898/index.html @@ -0,0 +1,206 @@ + + + + +
++ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
near-membrane-base/dist | +
+
+ |
+ 97.95% | +143/146 | +64.18% | +43/67 | +92.31% | +24/26 | +98.47% | +129/131 | +
near-membrane-base/src | +
+
+ |
+ 88.36% | +129/146 | +47.69% | +31/65 | +80.77% | +21/26 | +87.22% | +116/133 | +
near-membrane-dom/dist | +
+
+ |
+ 97.17% | +103/106 | +86.49% | +32/37 | +100% | +7/7 | +97.14% | +102/105 | +
near-membrane-node/src | +
+
+ |
+ 95.65% | +22/23 | +94.74% | +18/19 | +50% | +1/2 | +95.65% | +22/23 | +
near-membrane-shared-dom/dist | +
+
+ |
+ 100% | +21/21 | +77.78% | +7/9 | +100% | +2/2 | +100% | +21/21 | +
near-membrane-shared/dist | +
+
+ |
+ 96.71% | +294/304 | +72.64% | +77/106 | +92% | +23/25 | +96.69% | +292/302 | +
near-membrane-shared/src | +
+
+ |
+ 46.71% | +142/304 | +5.66% | +6/106 | +24% | +6/25 | +47.18% | +142/301 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
index.mjs.js | +
+
+ |
+ 97.95% | +143/146 | +64.18% | +43/67 | +92.31% | +24/26 | +98.47% | +129/131 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 | + + + + + + + + + + + + + + + + + + + + + + + + + +42x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +42x + + + +61x +1x + +60x + + +263x +5x + +258x + +42x + + +252x +2x + + + + + + + + + + + +250x + + + +250x +250x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +250x + +250x +250x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +250x +250x + + + + + + + + + + + + + + + + + + + + +250x + + + + + + + + + + + + + + + + + + + + + + + + +250x +250x +250x +250x +250x + +3640x +6591x +302x +6591x +250x +250x + + +206x +206x +206x +206x +50106x + +206x + +250x + + +454x +454x +454x +454x +240350x + +454x + +250x + + +309x +309x +293x +52x +52x + +241x + + +16x + + + +454x +454x +454x +454x + + +1x +1x + +454x + + + +3640x +3640x +3640x + +3640x +6591x +6591x +6591x +6591x +6591x + + + +206x +206x +206x + + +206x +206x +206x +206x +7158x +7158x + + + + +7158x + + +7158x +7158x +7158x +7158x +7158x +7158x +7158x + +206x + + + +229x +229x +229x +229x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +458x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +458x + + + + + + + + +458x +56x + +458x + + + +42x + +458x +458x + + +458x + + + +458x + + +458x + + +196x +196x +196x + +196x +7385x + + + +7385x +7219x +7219x + + + + +7219x + + + + + +196x + + +262x +262x +262x +262x +262x + +262x +283321x + + + +283321x +271733x + + +262x + + + +228x + +228x +3192x +3192x +3192x + +3178x +2497x + +681x + + + + + + | import { toSafeWeakMap, WeakMapCtor, TypeErrorCtor, SymbolFor, ErrorCtor, ObjectAssign, noop, ArrayCtor, ReflectApply, ArrayProtoPush, ReflectOwnKeys, toSafeArray, ObjectHasOwn, ArrayProtoIncludes } from '@locker/near-membrane-shared'; + +/** + * This file contains an exportable (portable) function `init()` used to initialize + * one side of a membrane on any realm. The only prerequisite is the ability to + * evaluate the sourceText of the `init()` function there. Once evaluated, the + * function will return a set of values that can be used to wire up the side of + * the membrane with another existing `init()` function from another realm, in + * which case they will exchange callable functions that are required to connect + * the two realms via the membrane. + * + * About the mechanics of the membrane, there are few important considerations: + * + * 1. Pointers are the way to pass reference to object and functions. + * 2. A dedicated symbol (LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) is needed + * to represent the absence of a value. + * 3. The realm that owns the object or function is responsible for projecting + * the proxy onto the other side (via callablePushTarget), which returns a + * Pointer that can be used by the realm to pass the reference to the same + * proxy over and over again. + * 4. The realm that owns the proxy (after the other side projects it into it) + * will hold a Pointer alongside the proxy to signal what original object or + * function should the foreign operation operates, it is always the first + * argument of the foreign callable for proxies, and the other side can use + * it via `selectedTarget!`. + */ +const proxyTargetToLazyPropertyDescriptorStateMap = toSafeWeakMap(new WeakMapCtor()); +// istanbul ignore next +function createMembraneMarshall(globalObject) { + var _ref, _ref2, _ReflectApply, _globalThisRef$BigInt, _globalThisRef$BigUin; + /* eslint-disable prefer-object-spread */ + const ArrayCtor = Array; + const ArrayBufferCtor = ArrayBuffer; + const ErrorCtor = Error; + const NumberCtor = Number; + const ObjectCtor = Object; + const ProxyCtor = Proxy; + const ReflectRef = Reflect; + const RegExpCtor = RegExp; + const StringCtor = String; + const SymbolCtor = Symbol; + const TypeErrorCtor = TypeError; + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + const WeakMapCtor = WeakMap; + const WeakSetCtor = WeakSet; + const { + for: SymbolFor, + toStringTag: SymbolToStringTag + } = SymbolCtor; + const { + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + apply: ReflectApply, + construct: ReflectConstruct, + defineProperty: ReflectDefineProperty, + deleteProperty: ReflectDeleteProperty, + get: ReflectGet, + getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor, + getPrototypeOf: ReflectGetPrototypeOf, + has: ReflectHas, + isExtensible: ReflectIsExtensible, + ownKeys: ReflectOwnKeys, + preventExtensions: ReflectPreventExtensions, + set: ReflectSet, + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + setPrototypeOf: ReflectSetPrototypeOf + } = ReflectRef; + const { + assign: ObjectAssign, + defineProperties: ObjectDefineProperties, + freeze: ObjectFreeze, + getOwnPropertyDescriptor: ObjectGetOwnPropertyDescriptor, + getOwnPropertyDescriptors: ObjectGetOwnPropertyDescriptors, + isFrozen: ObjectIsFrozen, + isSealed: ObjectIsSealed, + keys: ObjectKeys, + prototype: ObjectProto, + seal: ObjectSeal + } = ObjectCtor; + const { + hasOwnProperty: ObjectProtoHasOwnProperty, + propertyIsEnumerable: ObjectProtoPropertyIsEnumerable, + toString: ObjectProtoToString + } = ObjectProto; + const { + hasOwn: OriginalObjectHasOwn + } = ObjectCtor; + const { + __defineGetter__: ObjectProtoDefineGetter, + __defineSetter__: ObjectProtoDefineSetter, + __lookupGetter__: ObjectProtoLookupGetter, + __lookupSetter__: ObjectProtoLookupSetter + } = ObjectProto; + const ObjectHasOwn = typeof OriginalObjectHasOwn === 'function' ? OriginalObjectHasOwn : (object, key) => ReflectApply(ObjectProtoHasOwnProperty, object, [key]); + const globalThisRef = (_ref = (_ref2 = globalObject != null ? globalObject : + // Support for globalThis was added in Chrome 71. + // https://caniuse.com/mdn-javascript_builtins_globalthisfor + typeof globalThis !== 'undefined' ? globalThis : undefined) != null ? _ref2 : + // However, environments like Android emulators are running Chrome 69. + // eslint-disable-next-line no-restricted-globals + typeof self !== 'undefined' ? self : undefined) != null ? _ref : ( + // See https://mathiasbynens.be/notes/globalthis for more details. + ReflectDefineProperty(ObjectProto, 'globalThis', { + __proto__: null, + configurable: true, + get() { + ReflectDeleteProperty(ObjectProto, 'globalThis'); + // Safari 12 on iOS 12.1 has a `this` of `undefined` so we + // fallback to `self`. + // eslint-disable-next-line no-restricted-globals + return this != null ? this : self; + } + }), globalThis); + const IS_IN_SHADOW_REALM = typeof globalObject !== 'object' || globalObject === null; + const IS_NOT_IN_SHADOW_REALM = !IS_IN_SHADOW_REALM; + const LOCKER_DEBUG_MODE_SYMBOL = IS_NOT_IN_SHADOW_REALM ? SymbolFor('@@lockerDebugMode') : undefined; + const LOCKER_IDENTIFIER_MARKER = '$LWS'; + const LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL = IS_NOT_IN_SHADOW_REALM ? SymbolFor('@@lockerNearMembraneSerializedValue') : undefined; + const LOCKER_NEAR_MEMBRANE_SYMBOL = IS_NOT_IN_SHADOW_REALM ? SymbolFor('@@lockerNearMembrane') : undefined; + const LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL = SymbolFor('@@lockerNearMembraneUndefinedValue'); + // The default stack trace limit in Chrome is 10. + // Set to 20 to account for stack trace filtering. + const LOCKER_STACK_TRACE_LIMIT = 20; + // This package is bundled by third-parties that have their own build time + // replacement logic. Instead of customizing each build system to be aware + // of this package we implement a two phase debug mode by performing small + // runtime checks to determine phase one, our code is unminified, and + // phase two, the user opted-in to custom devtools formatters. Phase one + // is used for light weight initialization time debug while phase two is + // reserved for post initialization runtime. + // eslint-disable-next-line @typescript-eslint/naming-convention + const LOCKER_UNMINIFIED_FLAG = `${function LOCKER_UNMINIFIED_FLAG() { + return LOCKER_UNMINIFIED_FLAG.name; + }()}`.includes('LOCKER_UNMINIFIED_FLAG'); + // Indicate whether debug support is available. + const LOCKER_DEBUGGABLE_FLAG = LOCKER_UNMINIFIED_FLAG && IS_NOT_IN_SHADOW_REALM; + const ERR_ILLEGAL_PROPERTY_ACCESS = 'Illegal property access.'; + // BigInt is not supported in Safari 13.1. + // https://caniuse.com/bigint + const FLAGS_REG_EXP = IS_IN_SHADOW_REALM ? /\w*$/ : undefined; + // Minification safe references to the private `BoundaryProxyHandler` + // 'apply' and 'construct' trap variant's property names. + let MINIFICATION_SAFE_TRAP_PROPERTY_NAMES; + const SUPPORTS_BIG_INT = typeof BigInt === 'function'; + const { + isArray: isArrayOrThrowForRevoked + } = ArrayCtor; + const { + includes: ArrayProtoIncludes, + indexOf: ArrayProtoIndexOf, + slice: ArrayProtoSlice + } = ArrayCtor.prototype; + const { + isView: ArrayBufferIsView + } = ArrayBufferCtor; + const BigIntProtoValueOf = SUPPORTS_BIG_INT ? BigInt.prototype.valueOf : undefined; + const { + valueOf: BooleanProtoValueOf + } = Boolean.prototype; + const { + toString: ErrorProtoToString + } = ErrorCtor.prototype; + const { + bind: FunctionProtoBind, + toString: FunctionProtoToString + } = Function.prototype; + const { + stringify: JSONStringify + } = JSON; + const { + isInteger: NumberIsInteger + } = NumberCtor; + const { + valueOf: NumberProtoValueOf + } = NumberCtor.prototype; + const { + revocable: ProxyRevocable + } = ProxyCtor; + const { + prototype: RegExpProto + } = RegExpCtor; + const { + exec: RegExpProtoExec, + test: RegExpProtoTest, + toString: RegExProtoToString + } = RegExpProto; + // Edge 15 does not support RegExp.prototype.flags. + // https://caniuse.com/mdn-javascript_builtins_regexp_flags + const RegExpProtoFlagsGetter = IS_IN_SHADOW_REALM ? (_ReflectApply = ReflectApply(ObjectProtoLookupGetter, RegExpProto, ['flags'])) != null ? _ReflectApply : function flags() { + const string = ReflectApply(RegExProtoToString, this, []); + return ReflectApply(RegExpProtoExec, FLAGS_REG_EXP, [string])[0]; + } : undefined; + const RegExpProtoSourceGetter = ReflectApply(ObjectProtoLookupGetter, RegExpProto, ['source']); + const { + replace: StringProtoReplace, + slice: StringProtoSlice, + valueOf: StringProtoValueOf + } = StringCtor.prototype; + const { + toString: SymbolProtoToString, + valueOf: SymbolProtoValueOf + } = SymbolCtor.prototype; + const BigInt64ArrayProto = (_globalThisRef$BigInt = globalThisRef.BigInt64Array) == null ? void 0 : _globalThisRef$BigInt.prototype; + const BigUint64ArrayProto = (_globalThisRef$BigUin = globalThisRef.BigUint64Array) == null ? void 0 : _globalThisRef$BigUin.prototype; + const { + prototype: Float32ArrayProto + } = Float32Array; + const { + prototype: Float64ArrayProto + } = Float64Array; + const { + prototype: Int8ArrayProto + } = Int8Array; + const { + prototype: Int16ArrayProto + } = Int16Array; + const { + prototype: Int32ArrayProto + } = Int32Array; + const { + prototype: Uint8ArrayProto + } = Uint8Array; + const { + prototype: Uint16ArrayProto + } = Uint16Array; + const { + prototype: Uint32ArrayProto + } = Uint32Array; + // eslint-disable-next-line no-proto + const TypedArrayProto = Uint8ArrayProto.__proto__; + const TypedArrayProtoLengthGetter = ReflectApply(ObjectProtoLookupGetter, TypedArrayProto, ['length']); + const { + prototype: WeakMapProto + } = WeakMapCtor; + const { + delete: WeakMapProtoDelete, + has: WeakMapProtoHas, + set: WeakMapProtoSet, + [SymbolToStringTag]: WeakMapProtoSymbolToStringTag + } = WeakMapProto; + const { + prototype: WeakSetProto + } = WeakSetCtor; + const { + add: WeakSetProtoAdd, + has: WeakSetProtoHas, + delete: WeakSetProtoDelete, + [SymbolToStringTag]: WeakSetProtoSymbolToStringTag + } = WeakSetProto; + const consoleObject = IS_NOT_IN_SHADOW_REALM && typeof console === 'object' && console !== null ? console : undefined; + const consoleInfo = consoleObject == null ? void 0 : consoleObject.info; + const localEval = IS_IN_SHADOW_REALM ? eval : undefined; + // Install flags to ensure things are installed once per realm. + let installedErrorPrepareStackTraceFlag = false; + let installedPropertyDescriptorMethodWrappersFlag = false; + function alwaysFalse() { + return false; + } + const installErrorPrepareStackTrace = LOCKER_UNMINIFIED_FLAG ? () => { + if (installedErrorPrepareStackTraceFlag) { + return; + } + installedErrorPrepareStackTraceFlag = true; + // Feature detect the V8 stack trace API. + // https://v8.dev/docs/stack-trace-api + const CallSite = (() => { + try { + var _callSites$; + ErrorCtor.prepareStackTrace = (_error, callSites) => callSites; + const callSites = new ErrorCtor().stack; + ReflectDeleteProperty(ErrorCtor, 'prepareStackTrace'); + return isArrayOrThrowForRevoked(callSites) && callSites.length > 0 ? (_callSites$ = callSites[0]) == null ? void 0 : _callSites$.constructor : undefined; + // eslint-disable-next-line no-empty + } catch (_unused) {} + return undefined; + })(); + if (typeof CallSite !== 'function') { + return; + } + const { + getEvalOrigin: CallSiteProtoGetEvalOrigin, + getFunctionName: CallSiteProtoGetFunctionName, + toString: CallSiteProtoToString + } = CallSite.prototype; + // A regexp to detect call sites containing LOCKER_IDENTIFIER_MARKER. + const lockerFunctionNameMarkerRegExp = new RegExpCtor(`${ + // Escape regexp special characters in LOCKER_IDENTIFIER_MARKER. + ReflectApply(StringProtoReplace, LOCKER_IDENTIFIER_MARKER, [/[\\^$.*+?()[\]{}|]/g, '\\$&']) + // Function name references in call sites also contain + // the name of the class they belong to, + // e.g. myClassName.myFunctionName. + }(?=\\.|$)`); + const formatStackTrace = function formatStackTrace(error, callSites) { + // Based on V8's default stack trace formatting: + // https://chromium.googlesource.com/v8/v8.git/+/refs/heads/main/src/execution/messages.cc#371 + let stackTrace = ''; + try { + stackTrace = ReflectApply(ErrorProtoToString, error, []); + } catch (_unused2) { + stackTrace = '<error>'; + } + let consecutive = false; + for (let i = 0, { + length + } = callSites; i < length; i += 1) { + const callSite = callSites[i]; + const funcName = ReflectApply(CallSiteProtoGetFunctionName, callSite, []); + let isMarked = false; + if (typeof funcName === 'string' && funcName !== 'eval' && ReflectApply(RegExpProtoTest, lockerFunctionNameMarkerRegExp, [funcName])) { + isMarked = true; + } + if (!isMarked) { + const evalOrigin = ReflectApply(CallSiteProtoGetEvalOrigin, callSite, []); + if (typeof evalOrigin === 'string' && ReflectApply(RegExpProtoTest, lockerFunctionNameMarkerRegExp, [evalOrigin])) { + isMarked = true; + } + } + // Only write a single LWS entry per consecutive LWS stacks. + if (isMarked) { + if (!consecutive) { + consecutive = true; + stackTrace += '\n at LWS'; + } + continue; + } else { + consecutive = false; + } + try { + stackTrace += `\n at ${ReflectApply(CallSiteProtoToString, callSite, [])}`; + // eslint-disable-next-line no-empty + } catch (_unused3) {} + } + return stackTrace; + }; + try { + // Error.prepareStackTrace cannot be a bound or proxy wrapped + // function, so to obscure its source we wrap the call to + // formatStackTrace(). + ErrorCtor.prepareStackTrace = function prepareStackTrace(error, callSites) { + return formatStackTrace(error, callSites); + }; + // eslint-disable-next-line no-empty + } catch (_unused4) {} + try { + const { + stackTraceLimit + } = ErrorCtor; + if (typeof stackTraceLimit !== 'number' || stackTraceLimit < LOCKER_STACK_TRACE_LIMIT) { + ErrorCtor.stackTraceLimit = LOCKER_STACK_TRACE_LIMIT; + } + // eslint-disable-next-line no-empty + } catch (_unused5) {} + } : noop; + function noop() { + // No-operation. + } + const serializeBigIntObject = IS_IN_SHADOW_REALM ? bigIntObject => + // Section 21.2.3 Properties of the BigInt Prototype Object + // https://tc39.es/ecma262/#thisbigintvalue + // Step 2: If Type(value) is Object and value has a [[BigIntData]] internal slot, then + // a. Assert: Type(value.[[BigIntData]]) is BigInt. + ReflectApply(BigIntProtoValueOf, bigIntObject, []) : noop; + const serializeBooleanObject = IS_IN_SHADOW_REALM ? booleanObject => + // Section 20.3.3 Properties of the Boolean Prototype Object + // https://tc39.es/ecma262/#thisbooleanvalue + // Step 2: If Type(value) is Object and value has a [[BooleanData]] internal slot, then + // a. Let b be value.[[BooleanData]]. + // b. Assert: Type(b) is Boolean. + ReflectApply(BooleanProtoValueOf, booleanObject, []) : noop; + const serializeNumberObject = IS_IN_SHADOW_REALM ? numberObject => + // 21.1.3 Properties of the Number Prototype Object + // https://tc39.es/ecma262/#thisnumbervalue + // Step 2: If Type(value) is Object and value has a [[NumberData]] internal slot, then + // a. Let n be value.[[NumberData]]. + // b. Assert: Type(n) is Number. + ReflectApply(NumberProtoValueOf, numberObject, []) : noop; + const serializeRegExp = IS_IN_SHADOW_REALM ? value => { + // 22.2.5.12 get RegExp.prototype.source + // https://tc39.es/ecma262/#sec-get-regexp.prototype.source + // Step 3: If R does not have an [[OriginalSource]] internal slot, then + // a. If SameValue(R, %RegExp.prototype%) is true, return "(?:)". + // b. Otherwise, throw a TypeError exception. + if (value !== RegExpProto) { + const source = ReflectApply(RegExpProtoSourceGetter, value, []); + return JSONStringify({ + __proto__: null, + flags: ReflectApply(RegExpProtoFlagsGetter, value, []), + source + }); + } + return undefined; + } : noop; + const serializeStringObject = IS_IN_SHADOW_REALM ? stringObject => + // 22.1.3 Properties of the String Prototype Object + // https://tc39.es/ecma262/#thisstringvalue + // Step 2: If Type(value) is Object and value has a [[StringData]] internal slot, then + // a. Let s be value.[[StringData]]. + // b. Assert: Type(s) is String. + ReflectApply(StringProtoValueOf, stringObject, []) : noop; + const serializeSymbolObject = IS_IN_SHADOW_REALM ? symbolObject => + // 20.4.3 Properties of the Symbol Prototype Object + // https://tc39.es/ecma262/#thissymbolvalue + // Step 2: If Type(value) is Object and value has a [[SymbolData]] internal slot, then + // a. Let s be value.[[SymbolData]]. + // b. Assert: Type(s) is Symbol. + ReflectApply(SymbolProtoValueOf, symbolObject, []) : noop; + const serializeTargetByBrand = IS_IN_SHADOW_REALM ? target => { + const brand = ReflectApply(ObjectProtoToString, target, []); + switch (brand) { + // The brand checks below represent boxed primitives of + // `ESGlobalKeys` in packages/near-membrane-base/src/intrinsics.ts + // which are not remapped or reflective. + case '[object Boolean]': + return serializeBooleanObject(target); + case '[object Number]': + return serializeNumberObject(target); + case '[object RegExp]': + return serializeRegExp(target); + case '[object String]': + return serializeStringObject(target); + case '[object Object]': + try { + // Symbol.prototype[@@toStringTag] is defined by default so + // must have been removed. + // https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag + return serializeSymbolObject(target); + // eslint-disable-next-line no-empty + } catch (_unused6) {} + if (SUPPORTS_BIG_INT) { + // BigInt.prototype[@@toStringTag] is defined by default so + // must have been removed. + // https://tc39.es/ecma262/#sec-bigint.prototype-@@tostringtag + try { + return serializeBigIntObject(target); + // eslint-disable-next-line no-empty + } catch (_unused7) {} + } + // eslint-disable-next-line no-fallthrough + default: + return undefined; + } + } : noop; + const serializeTargetByTrialAndError = IS_IN_SHADOW_REALM ? target => { + // The serialization attempts below represent boxed primitives of + // `ESGlobalKeys` in packages/near-membrane-base/src/intrinsics.ts + // which are not remapped or reflective. + try { + // Symbol.prototype[@@toStringTag] is defined by default so + // attempted before others. + // https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag + return serializeSymbolObject(target); + // eslint-disable-next-line no-empty + } catch (_unused8) {} + if (SUPPORTS_BIG_INT) { + // BigInt.prototype[@@toStringTag] is defined by default so + // attempted before others. + // https://tc39.es/ecma262/#sec-bigint.prototype-@@tostringtag + try { + return serializeBigIntObject(target); + // eslint-disable-next-line no-empty + } catch (_unused9) {} + } + try { + return serializeBooleanObject(target); + // eslint-disable-next-line no-empty + } catch (_unused10) {} + try { + return serializeNumberObject(target); + // eslint-disable-next-line no-empty + } catch (_unused11) {} + try { + return serializeRegExp(target); + // eslint-disable-next-line no-empty + } catch (_unused12) {} + try { + return serializeStringObject(target); + // eslint-disable-next-line no-empty + } catch (_unused13) {} + return undefined; + } : noop; + function toSafeTemplateStringValue(value) { + if (typeof value === 'string') { + return value; + } + try { + if (typeof value === 'object' && value !== null) { + const result = ReflectApply(ObjectProtoToString, value, []); + return result === '[object Symbol]' ? ReflectApply(SymbolProtoToString, value, []) : result; + } + if (typeof value === 'function') { + return ReflectApply(FunctionProtoToString, value, []); + } + // Attempt to coerce `value` to a string with the String() constructor. + // Section 22.1.1.1 String ( value ) + // https://tc39.es/ecma262/#sec-string-constructor-string-value + return StringCtor(value); + // eslint-disable-next-line no-empty + } catch (_unused14) {} + return '[Object Unknown]'; + } + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + function toSafeWeakMap(weakMap) { + ReflectSetPrototypeOf(weakMap, null); + weakMap.delete = WeakMapProtoDelete; + weakMap.has = WeakMapProtoHas; + weakMap.set = WeakMapProtoSet; + weakMap[SymbolToStringTag] = WeakMapProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakMap, WeakMapProto); + return weakMap; + } + function toSafeWeakSet(weakSet) { + ReflectSetPrototypeOf(weakSet, null); + weakSet.add = WeakSetProtoAdd; + weakSet.delete = WeakSetProtoDelete; + weakSet.has = WeakSetProtoHas; + weakSet[SymbolToStringTag] = WeakSetProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakSet, WeakSetProto); + return weakSet; + } + return function createHooksCallback(color, foreignCallableHooksCallback, options) { + if (IS_IN_SHADOW_REALM) { + options = undefined; + } + const { + distortionCallback, + liveTargetCallback, + revokedProxyCallback + // eslint-disable-next-line prefer-object-spread + } = ObjectAssign({ + __proto__: null + }, options); + const applyTrapNameRegistry = { + // Populated in the returned connector function below. + __proto__: null, + 0: undefined, + 1: undefined, + 2: undefined, + 3: undefined, + 4: undefined, + n: undefined + }; + const constructTrapNameRegistry = { + // Populated in the returned connector function below. + __proto__: null, + 0: undefined, + 1: undefined, + 2: undefined, + 3: undefined, + 4: undefined, + n: undefined + }; + const lazyPropertyDescriptorStateCache = toSafeWeakMap(new WeakMapCtor()); + const proxyPointerCache = toSafeWeakMap(new WeakMapCtor()); + let foreignCallablePushErrorTarget; + let foreignCallablePushTarget; + let foreignCallableApply; + let foreignCallableConstruct; + let foreignCallableDefineProperty; + let foreignCallableDeleteProperty; + let foreignCallableGet; + let foreignCallableGetOwnPropertyDescriptor; + let foreignCallableGetPrototypeOf; + let foreignCallableHas; + let foreignCallableIsExtensible; + let foreignCallableOwnKeys; + let foreignCallablePreventExtensions; + let foreignCallableSet; + let foreignCallableSetPrototypeOf; + let foreignCallableDebugInfo; + let foreignCallableGetPropertyValue; + let foreignCallableGetLazyPropertyDescriptorStateByTarget; + let foreignCallableGetTargetIntegrityTraits; + let foreignCallableGetToStringTagOfTarget; + let foreignCallableInstallErrorPrepareStackTrace; + let foreignCallableIsTargetLive; + let foreignCallableIsTargetRevoked; + let foreignCallableSerializeTarget; + let foreignCallableSetLazyPropertyDescriptorStateByTarget; + let foreignCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors; + let foreignCallableBatchGetPrototypeOfWhenHasNoOwnProperty; + let foreignCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor; + let fastForeignTargetPointers; + let foreignPointerBigInt64ArrayProto; + let foreignPointerBigUint64ArrayProto; + let foreignPointerFloat32ArrayProto; + let foreignPointerFloat64ArrayProto; + let foreignPointerInt8ArrayProto; + let foreignPointerInt16ArrayProto; + let foreignPointerInt32ArrayProto; + let foreignPointerObjectProto; + let foreignPointerTypedArrayProto; + let foreignPointerUint8ArrayProto; + let foreignPointerUint16ArrayProto; + let foreignPointerUint32ArrayProto; + let selectedTarget; + let lastProxyTrapCalled = 0 /* ProxyHandlerTraps.None */; + let handshakePropertyFlag = false; + let useFastForeignTargetPath = IS_IN_SHADOW_REALM; + let useFastForeignTargetPathForTypedArrays = IS_IN_SHADOW_REALM; + const activateLazyOwnPropertyDefinition = IS_IN_SHADOW_REALM ? (target, key, state) => { + state[key] = false; + const foreignTargetPointer = getTransferablePointer(target); + let safeDesc; + try { + foreignCallableGetOwnPropertyDescriptor(foreignTargetPointer, key, (_key, configurable, enumerable, writable, valuePointer, getterPointer, setterPointer) => { + safeDesc = createDescriptorFromMeta(configurable, enumerable, writable, valuePointer, getterPointer, setterPointer); + }); + } catch (error) { + var _selectedTarget; + const errorToThrow = (_selectedTarget = selectedTarget) != null ? _selectedTarget : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (safeDesc) { + ReflectDefineProperty(target, key, safeDesc); + } else { + ReflectDeleteProperty(target, key); + } + } : noop; + let checkDebugMode = LOCKER_DEBUGGABLE_FLAG ? () => { + try { + if (ObjectHasOwn(globalThisRef, LOCKER_DEBUG_MODE_SYMBOL)) { + checkDebugMode = () => true; + installErrorPrepareStackTrace(); + foreignCallableInstallErrorPrepareStackTrace(); + } + } catch (_unused15) { + checkDebugMode = alwaysFalse; + } + return false; + } : alwaysFalse; + const clearFastForeignTargetPointers = IS_IN_SHADOW_REALM ? () => { + fastForeignTargetPointers = toSafeWeakSet(new WeakSetCtor()); + } : noop; + function copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget(foreignTargetPointer, shadowTarget) { + let protoPointerOrNull; + try { + protoPointerOrNull = foreignCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors(foreignTargetPointer, (...descriptorTuples) => { + const descriptors = {}; + for (let i = 0, { + length + } = descriptorTuples; i < length; i += 7) { + const key = descriptorTuples[i]; + descriptors[key] = createDescriptorFromMeta(descriptorTuples[i + 1], + // configurable + descriptorTuples[i + 2], + // enumerable + descriptorTuples[i + 3], + // writable + descriptorTuples[i + 4], + // valuePointer + descriptorTuples[i + 5], + // getterPointer + descriptorTuples[i + 6] // setterPointer + ); + } + // Use `ObjectDefineProperties()` instead of individual + // `ReflectDefineProperty()` calls for better performance. + ObjectDefineProperties(shadowTarget, descriptors); + }); + } catch (error) { + var _selectedTarget2; + const errorToThrow = (_selectedTarget2 = selectedTarget) != null ? _selectedTarget2 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let proto; + if (typeof protoPointerOrNull === 'function') { + protoPointerOrNull(); + proto = selectedTarget; + selectedTarget = undefined; + } else { + proto = null; + } + ReflectSetPrototypeOf(shadowTarget, proto); + } + function createApplyOrConstructTrapForZeroOrMoreArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap ? applyTrapNameRegistry : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrap(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + if (length !== 0) { + var _arityToApplyOrConstr; + return this[(_arityToApplyOrConstr = arityToApplyOrConstructTrapNameRegistry[length]) != null ? _arityToApplyOrConstr : arityToApplyOrConstructTrapNameRegistry.n](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableApplyOrConstruct(foreignTargetPointer, + // Inline getTransferableValue(). + typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget); + } catch (error) { + var _selectedTarget3; + const errorToThrow = (_selectedTarget3 = selectedTarget) != null ? _selectedTarget3 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createApplyOrConstructTrapForOneOrMoreArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap ? applyTrapNameRegistry : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrapForOneOrMoreArgs(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + if (length !== 1) { + var _arityToApplyOrConstr2; + return this[(_arityToApplyOrConstr2 = arityToApplyOrConstructTrapNameRegistry[length]) != null ? _arityToApplyOrConstr2 : arityToApplyOrConstructTrapNameRegistry.n](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive; + try { + const { + 0: arg0 + } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct(foreignTargetPointer, + // Inline getTransferableValue(). + typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget, + // Inline getTransferableValue(). + typeof arg0 === 'object' && arg0 !== null || typeof arg0 === 'function' ? getTransferablePointer(arg0) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' ? undefined : arg0); + } catch (error) { + var _selectedTarget4; + const errorToThrow = (_selectedTarget4 = selectedTarget) != null ? _selectedTarget4 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createApplyOrConstructTrapForTwoOrMoreArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap ? applyTrapNameRegistry : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + if (length !== 2) { + var _arityToApplyOrConstr3; + return this[(_arityToApplyOrConstr3 = arityToApplyOrConstructTrapNameRegistry[length]) != null ? _arityToApplyOrConstr3 : arityToApplyOrConstructTrapNameRegistry.n](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive; + try { + const { + 0: arg0, + 1: arg1 + } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct(foreignTargetPointer, + // Inline getTransferableValue(). + typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget, + // Inline getTransferableValue(). + typeof arg0 === 'object' && arg0 !== null || typeof arg0 === 'function' ? getTransferablePointer(arg0) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' ? undefined : arg0, + // Inline getTransferableValue(). + typeof arg1 === 'object' && arg1 !== null || typeof arg1 === 'function' ? getTransferablePointer(arg1) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' ? undefined : arg1); + } catch (error) { + var _selectedTarget5; + const errorToThrow = (_selectedTarget5 = selectedTarget) != null ? _selectedTarget5 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createApplyOrConstructTrapForThreeOrMoreArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap ? applyTrapNameRegistry : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + if (length !== 3) { + var _arityToApplyOrConstr4; + return this[(_arityToApplyOrConstr4 = arityToApplyOrConstructTrapNameRegistry[length]) != null ? _arityToApplyOrConstr4 : arityToApplyOrConstructTrapNameRegistry.n](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive; + try { + const { + 0: arg0, + 1: arg1, + 2: arg2 + } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct(foreignTargetPointer, + // Inline getTransferableValue(). + typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget, + // Inline getTransferableValue(). + typeof arg0 === 'object' && arg0 !== null || typeof arg0 === 'function' ? getTransferablePointer(arg0) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' ? undefined : arg0, + // Inline getTransferableValue(). + typeof arg1 === 'object' && arg1 !== null || typeof arg1 === 'function' ? getTransferablePointer(arg1) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' ? undefined : arg1, + // Inline getTransferableValue(). + typeof arg2 === 'object' && arg2 !== null || typeof arg2 === 'function' ? getTransferablePointer(arg2) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg2 === 'undefined' ? undefined : arg2); + } catch (error) { + var _selectedTarget6; + const errorToThrow = (_selectedTarget6 = selectedTarget) != null ? _selectedTarget6 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createApplyOrConstructTrapForFourOrMoreArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap ? applyTrapNameRegistry : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + if (length !== 4) { + var _arityToApplyOrConstr5; + return this[(_arityToApplyOrConstr5 = arityToApplyOrConstructTrapNameRegistry[length]) != null ? _arityToApplyOrConstr5 : arityToApplyOrConstructTrapNameRegistry.n](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive; + try { + const { + 0: arg0, + 1: arg1, + 2: arg2, + 3: arg3 + } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct(foreignTargetPointer, + // Inline getTransferableValue(). + typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget, + // Inline getTransferableValue(). + typeof arg0 === 'object' && arg0 !== null || typeof arg0 === 'function' ? getTransferablePointer(arg0) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' ? undefined : arg0, + // Inline getTransferableValue(). + typeof arg1 === 'object' && arg1 !== null || typeof arg1 === 'function' ? getTransferablePointer(arg1) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' ? undefined : arg1, + // Inline getTransferableValue(). + typeof arg2 === 'object' && arg2 !== null || typeof arg2 === 'function' ? getTransferablePointer(arg2) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg2 === 'undefined' ? undefined : arg2, + // Inline getTransferableValue(). + typeof arg3 === 'object' && arg3 !== null || typeof arg3 === 'function' ? getTransferablePointer(arg3) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg3 === 'undefined' ? undefined : arg3); + } catch (error) { + var _selectedTarget7; + const errorToThrow = (_selectedTarget7 = selectedTarget) != null ? _selectedTarget7 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createApplyOrConstructTrapForFiveOrMoreArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap ? applyTrapNameRegistry : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + if (length !== 5) { + var _arityToApplyOrConstr6; + return this[(_arityToApplyOrConstr6 = arityToApplyOrConstructTrapNameRegistry[length]) != null ? _arityToApplyOrConstr6 : arityToApplyOrConstructTrapNameRegistry.n](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive; + try { + const { + 0: arg0, + 1: arg1, + 2: arg2, + 3: arg3, + 4: arg4 + } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct(foreignTargetPointer, + // Inline getTransferableValue(). + typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget, + // Inline getTransferableValue(). + typeof arg0 === 'object' && arg0 !== null || typeof arg0 === 'function' ? getTransferablePointer(arg0) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' ? undefined : arg0, + // Inline getTransferableValue(). + typeof arg1 === 'object' && arg1 !== null || typeof arg1 === 'function' ? getTransferablePointer(arg1) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' ? undefined : arg1, + // Inline getTransferableValue(). + typeof arg2 === 'object' && arg2 !== null || typeof arg2 === 'function' ? getTransferablePointer(arg2) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg2 === 'undefined' ? undefined : arg2, + // Inline getTransferableValue(). + typeof arg3 === 'object' && arg3 !== null || typeof arg3 === 'function' ? getTransferablePointer(arg3) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg3 === 'undefined' ? undefined : arg3, + // Inline getTransferableValue(). + typeof arg4 === 'object' && arg4 !== null || typeof arg4 === 'function' ? getTransferablePointer(arg4) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg4 === 'undefined' ? undefined : arg4); + } catch (error) { + var _selectedTarget8; + const errorToThrow = (_selectedTarget8 = selectedTarget) != null ? _selectedTarget8 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createApplyOrConstructTrapForAnyNumberOfArgs(proxyTrapEnum) { + const isApplyTrap = proxyTrapEnum & 1 /* ProxyHandlerTraps.Apply */; + const foreignCallableApplyOrConstruct = isApplyTrap ? foreignCallableApply : foreignCallableConstruct; + return function applyOrConstructTrapForAnyNumberOfArgs(_shadowTarget, thisArgOrArgs, argsOrNewTarget) { + lastProxyTrapCalled = proxyTrapEnum; + // @ts-ignore: Prevent private property access error. + const { + foreignTargetPointer + } = this; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { + length + } = args; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let combinedOffset = 2; + const combinedArgs = new ArrayCtor(length + combinedOffset); + combinedArgs[0] = foreignTargetPointer; + let pointerOrPrimitive; + try { + combinedArgs[1] = typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null || typeof thisArgOrNewTarget === 'function' ? getTransferablePointer(thisArgOrNewTarget) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' ? undefined : thisArgOrNewTarget; + for (let i = 0; i < length; i += 1) { + const arg = args[i]; + // Inlining `getTransferableValue()`. + combinedArgs[combinedOffset++] = typeof arg === 'object' && arg !== null || typeof arg === 'function' ? getTransferablePointer(arg) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg === 'undefined' ? undefined : arg; + } + pointerOrPrimitive = ReflectApply(foreignCallableApplyOrConstruct, undefined, combinedArgs); + } catch (error) { + var _selectedTarget9; + const errorToThrow = (_selectedTarget9 = selectedTarget) != null ? _selectedTarget9 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + function createDescriptorFromMeta(configurable, enumerable, writable, valuePointerOrPrimitive, getterPointerOrPrimitive, setterPointerOrPrimitive) { + const safeDesc = { + __proto__: null + }; + if (configurable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.configurable = configurable; + } + if (enumerable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.enumerable = enumerable; + } + if (writable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.writable = writable; + } + if (getterPointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof getterPointerOrPrimitive === 'function') { + getterPointerOrPrimitive(); + safeDesc.get = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.get = undefined; + } + } + if (setterPointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof setterPointerOrPrimitive === 'function') { + setterPointerOrPrimitive(); + safeDesc.set = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.set = undefined; + } + } + if (valuePointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof valuePointerOrPrimitive === 'function') { + valuePointerOrPrimitive(); + safeDesc.value = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.value = valuePointerOrPrimitive; + } + } + return safeDesc; + } + function createPointer(originalTarget) { + const pointer = () => { + // assert: selectedTarget is undefined + selectedTarget = originalTarget; + }; + return pointer; + } + const disableFastForeignTargetPointers = IS_IN_SHADOW_REALM ? () => { + useFastForeignTargetPath = false; + useFastForeignTargetPathForTypedArrays = false; + clearFastForeignTargetPointers(); + } : noop; + const getLazyPropertyDescriptorStateByTarget = IS_IN_SHADOW_REALM ? target => { + let state = lazyPropertyDescriptorStateCache.get(target); + if (state === undefined) { + const statePointerOrUndefined = foreignCallableGetLazyPropertyDescriptorStateByTarget(getTransferablePointer(target)); + if (typeof statePointerOrUndefined === 'function') { + statePointerOrUndefined(); + state = selectedTarget; + selectedTarget = undefined; + if (state) { + lazyPropertyDescriptorStateCache.set(target, state); + } + } + } + return state; + } : noop; + const isForeignPointerOfObjectProto = IS_IN_SHADOW_REALM ? + // eslint-disable-next-line no-return-assign + foreignTargetPointer => foreignTargetPointer === (foreignPointerObjectProto === undefined ? foreignPointerObjectProto = getTransferablePointer(ObjectProto) : foreignPointerObjectProto) : alwaysFalse; + const isForeignPointerOfTypedArrayProto = IS_IN_SHADOW_REALM ? + // eslint-disable-next-line no-return-assign + foreignTargetPointer => foreignTargetPointer === (foreignPointerFloat32ArrayProto === undefined ? foreignPointerFloat32ArrayProto = getTransferablePointer(Float32ArrayProto) : foreignPointerFloat32ArrayProto) || foreignTargetPointer === (foreignPointerFloat64ArrayProto === undefined ? foreignPointerFloat64ArrayProto = getTransferablePointer(Float64ArrayProto) : foreignPointerFloat64ArrayProto) || foreignTargetPointer === (foreignPointerInt8ArrayProto === undefined ? foreignPointerInt8ArrayProto = getTransferablePointer(Int8ArrayProto) : foreignPointerInt8ArrayProto) || foreignTargetPointer === (foreignPointerInt16ArrayProto === undefined ? foreignPointerInt16ArrayProto = getTransferablePointer(Int16ArrayProto) : foreignPointerInt16ArrayProto) || foreignTargetPointer === (foreignPointerInt32ArrayProto === undefined ? foreignPointerInt32ArrayProto = getTransferablePointer(Int32ArrayProto) : foreignPointerInt32ArrayProto) || foreignTargetPointer === (foreignPointerUint8ArrayProto === undefined ? foreignPointerUint8ArrayProto = getTransferablePointer(Uint8ArrayProto) : foreignPointerUint8ArrayProto) || foreignTargetPointer === (foreignPointerUint16ArrayProto === undefined ? foreignPointerUint16ArrayProto = getTransferablePointer(Uint16ArrayProto) : foreignPointerUint16ArrayProto) || foreignTargetPointer === (foreignPointerUint32ArrayProto === undefined ? foreignPointerUint32ArrayProto = getTransferablePointer(Uint32ArrayProto) : foreignPointerUint32ArrayProto) || foreignTargetPointer === (foreignPointerTypedArrayProto === undefined ? foreignPointerTypedArrayProto = getTransferablePointer(TypedArrayProto) : foreignPointerTypedArrayProto) || foreignTargetPointer === (foreignPointerBigInt64ArrayProto === undefined ? foreignPointerBigInt64ArrayProto = BigInt64ArrayProto ? getTransferablePointer(BigInt64ArrayProto) : noop : foreignPointerBigInt64ArrayProto) || foreignTargetPointer === (foreignPointerBigUint64ArrayProto === undefined ? foreignPointerBigUint64ArrayProto = BigUint64ArrayProto ? getTransferablePointer(BigUint64ArrayProto) : noop : foreignPointerBigUint64ArrayProto) : alwaysFalse; + function getTransferablePointer(originalTarget, foreignCallablePusher = foreignCallablePushTarget) { + let proxyPointer = proxyPointerCache.get(originalTarget); + if (proxyPointer) { + return proxyPointer; + } + let targetFunctionArity = 0; + let targetFunctionName = ''; + let targetTypedArrayLength = 0; + if (revokedProxyCallback && revokedProxyCallback(originalTarget)) { + proxyPointer = foreignCallablePusher(createPointer(originalTarget), 64 /* TargetTraits.Revoked */, targetFunctionArity, targetFunctionName, targetTypedArrayLength); + proxyPointerCache.set(originalTarget, proxyPointer); + return proxyPointer; + } + let distortionTarget; + let targetTraits = 16 /* TargetTraits.IsObject */; + if (distortionCallback) { + distortionTarget = distortionCallback(originalTarget); + // If a distortion entry is found, it must be a valid proxy target. + if (distortionTarget !== originalTarget && typeof distortionTarget !== typeof originalTarget) { + throw new TypeErrorCtor(`Invalid distortion ${toSafeTemplateStringValue(originalTarget)}.`); + } + } else { + distortionTarget = originalTarget; + } + let isPossiblyRevoked = true; + if (typeof distortionTarget === 'function') { + isPossiblyRevoked = false; + targetFunctionArity = 0; + targetTraits = 4 /* TargetTraits.IsFunction */; + try { + // Detect arrow functions. + if (!('prototype' in distortionTarget)) { + targetTraits |= 8 /* TargetTraits.IsArrowFunction */; + } + + const safeLengthDesc = ReflectGetOwnPropertyDescriptor(originalTarget, 'length'); + if (safeLengthDesc) { + ReflectSetPrototypeOf(safeLengthDesc, null); + const { + value: safeLengthDescValue + } = safeLengthDesc; + if (typeof safeLengthDescValue === 'number') { + targetFunctionArity = safeLengthDescValue; + } + } + const safeNameDesc = false ? ReflectGetOwnPropertyDescriptor(originalTarget, 'name') : undefined; + if (safeNameDesc) ; + } catch (_unused16) { + isPossiblyRevoked = true; + } + } else if (ArrayBufferIsView(distortionTarget)) { + isPossiblyRevoked = false; + targetTraits = 2 /* TargetTraits.IsArrayBufferView */; + try { + targetTypedArrayLength = ReflectApply(TypedArrayProtoLengthGetter, distortionTarget, []); + targetTraits |= 32 /* TargetTraits.IsTypedArray */; + // eslint-disable-next-line no-empty + } catch (_unused17) { + // Could be a DataView object or a revoked proxy. + isPossiblyRevoked = true; + } + } + if (isPossiblyRevoked) { + try { + if (isArrayOrThrowForRevoked(distortionTarget)) { + targetTraits = 1 /* TargetTraits.IsArray */; + } + } catch (_unused18) { + targetTraits = 64 /* TargetTraits.Revoked */; + } + } + + proxyPointer = foreignCallablePusher(createPointer(distortionTarget), targetTraits, targetFunctionArity, targetFunctionName, targetTypedArrayLength); + proxyPointerCache.set(originalTarget, proxyPointer); + return proxyPointer; + } + const installPropertyDescriptorMethodWrappers = IS_IN_SHADOW_REALM ? unforgeableGlobalThisKeys => { + if (installedPropertyDescriptorMethodWrappersFlag) { + return; + } + installedPropertyDescriptorMethodWrappersFlag = true; + // We wrap property descriptor methods to activate lazy + // descriptors and/or workaround browser bugs. The following + // methods are wrapped: + // Object.getOwnPropertyDescriptors() + // Object.getOwnPropertyDescriptor() + // Reflect.defineProperty() + // Reflect.getOwnPropertyDescriptor() + // Object.prototype.__defineGetter__() + // Object.prototype.__defineSetter__() + // Object.prototype.__lookupGetter__() + // Object.prototype.__lookupSetter__() + // + // Chromium based browsers have a bug that nulls the result + // of `window` getters in detached iframes when the property + // descriptor of `window.window` is retrieved. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1305302 + // + // Methods may be poisoned when they interact with the `window` + // object and retrieve property descriptors, like 'window', + // that contain the `window` object itself. The following + // built-in methods are susceptible to this issue: + // console.log(window); + // Object.getOwnPropertyDescriptors(window); + // Object.getOwnPropertyDescriptor(window, 'window'); + // Reflect.getOwnPropertyDescriptor(window, 'window'); + // window.__lookupGetter__('window'); + // window.__lookupSetter__('window'); + // + // We side step issues with `console` by mapping it to the + // primary realm's `console`. Since we're already wrapping + // property descriptor methods to activate lazy descriptors + // we use the wrapper to workaround the `window` getter + // nulling bug. + const shouldFixChromeBug = isArrayOrThrowForRevoked(unforgeableGlobalThisKeys) && unforgeableGlobalThisKeys.length > 0; + // Lazily populated by `getUnforgeableGlobalThisGetter()`; + const keyToGlobalThisGetterRegistry = shouldFixChromeBug ? { + __proto__: null + } : undefined; + const getFixedDescriptor = shouldFixChromeBug ? (target, key) => ReflectApply(ArrayProtoIncludes, unforgeableGlobalThisKeys, [key]) ? { + configurable: false, + enumerable: ReflectApply(ObjectProtoPropertyIsEnumerable, target, [key]), + // eslint-disable-next-line @typescript-eslint/no-use-before-define + get: getUnforgeableGlobalThisGetter(key), + set: undefined + } : ReflectGetOwnPropertyDescriptor(target, key) : undefined; + const getUnforgeableGlobalThisGetter = shouldFixChromeBug ? key => { + let globalThisGetter = keyToGlobalThisGetterRegistry[key]; + if (globalThisGetter === undefined) { + // We can't access the original getter to mask + // with `proxyMaskFunction()`, so instead we wrap + // `unboundGlobalThisGetter` in bound function + // to obscure the getter source as "[native code]". + globalThisGetter = ReflectApply(FunctionProtoBind, + // eslint-disable-next-line @typescript-eslint/no-use-before-define + unboundGlobalThisGetter, []); + // Preserve identity continuity of getters. + keyToGlobalThisGetterRegistry[key] = globalThisGetter; + } + return globalThisGetter; + } : undefined; + const lookupFixedGetter = shouldFixChromeBug ? (target, key) => ReflectApply(ArrayProtoIncludes, unforgeableGlobalThisKeys, [key]) ? getUnforgeableGlobalThisGetter(key) : ReflectApply(ObjectProtoLookupGetter, target, [key]) : undefined; + const lookupFixedSetter = shouldFixChromeBug ? (target, key) => ReflectApply(ArrayProtoIncludes, unforgeableGlobalThisKeys, [key]) ? undefined : ReflectApply(ObjectProtoLookupSetter, target, [key]) : undefined; + const unboundGlobalThisGetter = shouldFixChromeBug ? () => globalThisRef : undefined; + const wrapDefineAccessOrProperty = originalFunc => { + const { + length: originalFuncLength + } = originalFunc; + // `__defineGetter__()` and `__defineSetter__()` have + // function lengths of 2 while `Reflect.defineProperty()` + // has a function length of 3. + const useThisArgAsTarget = originalFuncLength === 2; + return new ProxyCtor(originalFunc, { + apply(_originalFunc, thisArg, args) { + if (args.length >= originalFuncLength) { + const target = useThisArgAsTarget ? thisArg : args[0]; + if (typeof target === 'object' && target !== null || typeof target === 'function') { + const key = useThisArgAsTarget ? args[0] : args[1]; + const state = getLazyPropertyDescriptorStateByTarget(target); + if (state != null && state[key]) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + target[key]; + } + } + } + return ReflectApply(originalFunc, thisArg, args); + } + }); + }; + const wrapLookupAccessor = (originalFunc, lookupFixedAccessor) => new ProxyCtor(originalFunc, { + apply(_originalFunc, thisArg, args) { + if (args.length && (typeof thisArg === 'object' && thisArg !== null || typeof thisArg === 'function')) { + const { + 0: key + } = args; + const state = getLazyPropertyDescriptorStateByTarget(thisArg); + if (state != null && state[key]) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + thisArg[key]; + } + if (shouldFixChromeBug && thisArg === globalThisRef) { + return lookupFixedAccessor(thisArg, key); + } + } + return ReflectApply(originalFunc, thisArg, args); + } + }); + const wrapGetOwnPropertyDescriptor = originalFunc => new ProxyCtor(originalFunc, { + apply(_originalFunc, thisArg, args) { + if (args.length > 1) { + const { + 0: target, + 1: key + } = args; + if (typeof target === 'object' && target !== null || typeof target === 'function') { + const state = getLazyPropertyDescriptorStateByTarget(target); + if (state != null && state[key]) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + target[key]; + } + if (shouldFixChromeBug && target === globalThisRef) { + return getFixedDescriptor(target, key); + } + } + } + return ReflectApply(originalFunc, thisArg, args); + } + }); + const wrapGetOwnPropertyDescriptors = originalFunc => new ProxyCtor(originalFunc, { + apply(_originalFunc, thisArg, args) { + const target = args.length ? args[0] : undefined; + if (!(typeof target === 'object' && target !== null || typeof target === 'function')) { + // Defer to native method to throw exception. + return ReflectApply(originalFunc, thisArg, args); + } + const state = getLazyPropertyDescriptorStateByTarget(target); + const isFixingChromeBug = target === globalThisRef && shouldFixChromeBug; + const unsafeDescs = isFixingChromeBug ? + // Create an empty property descriptor map + // to populate with curated descriptors. + {} : + // Since this is not a global object it is + // safe to use the native method. + ReflectApply(originalFunc, thisArg, args); + if (!isFixingChromeBug && state === undefined) { + // Exit early if the target is not a global + // object and there are no lazy descriptors. + return unsafeDescs; + } + const ownKeys = ReflectOwnKeys(isFixingChromeBug ? target : unsafeDescs); + for (let i = 0, { + length + } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + const isLazyProp = !!(state != null && state[ownKey]); + if (isLazyProp) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + target[ownKey]; + } + if (isLazyProp || isFixingChromeBug) { + const unsafeDesc = isFixingChromeBug ? getFixedDescriptor(target, ownKey) : ReflectGetOwnPropertyDescriptor(target, ownKey); + // Update the descriptor map entry. + if (unsafeDesc) { + unsafeDescs[ownKey] = unsafeDesc; + } else if (!isFixingChromeBug) { + ReflectDeleteProperty(unsafeDescs, ownKey); + } + } + } + return unsafeDescs; + } + }); + try { + ReflectRef.defineProperty = wrapDefineAccessOrProperty(ReflectDefineProperty); + // eslint-disable-next-line no-empty + } catch (_unused19) {} + try { + ReflectRef.getOwnPropertyDescriptor = wrapGetOwnPropertyDescriptor(ReflectGetOwnPropertyDescriptor); + // eslint-disable-next-line no-empty + } catch (_unused20) {} + try { + ObjectCtor.getOwnPropertyDescriptor = wrapGetOwnPropertyDescriptor(ObjectGetOwnPropertyDescriptor); + // eslint-disable-next-line no-empty + } catch (_unused21) {} + try { + ObjectCtor.getOwnPropertyDescriptors = wrapGetOwnPropertyDescriptors(ObjectGetOwnPropertyDescriptors); + // eslint-disable-next-line no-empty + } catch (_unused22) {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-restricted-properties, no-underscore-dangle + ObjectProto.__defineGetter__ = wrapDefineAccessOrProperty(ObjectProtoDefineGetter); + // eslint-disable-next-line no-empty + } catch (_unused23) {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-restricted-properties, no-underscore-dangle + ObjectProto.__defineSetter__ = wrapDefineAccessOrProperty(ObjectProtoDefineSetter); + // eslint-disable-next-line no-empty + } catch (_unused24) {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle + ObjectProto.__lookupGetter__ = wrapLookupAccessor(ObjectProtoLookupGetter, lookupFixedGetter); + // eslint-disable-next-line no-empty + } catch (_unused25) {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle + ObjectProto.__lookupSetter__ = wrapLookupAccessor(ObjectProtoLookupSetter, lookupFixedSetter); + // eslint-disable-next-line no-empty + } catch (_unused26) {} + } : noop; + function lookupForeignDescriptor(foreignTargetPointer, shadowTarget, key) { + let protoPointerOrNull; + let safeDesc; + try { + protoPointerOrNull = foreignCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor(foreignTargetPointer, key, (_key, configurable, enumerable, writable, valuePointerOrPrimitive, getterPointerOrPrimitive, setterPointerOrPrimitive) => { + safeDesc = { + __proto__: null, + foreign: true + }; + if (configurable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.configurable = configurable; + } + if (enumerable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.enumerable = enumerable; + } + if (writable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.writable = writable; + } + if (getterPointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof getterPointerOrPrimitive === 'function') { + getterPointerOrPrimitive(); + safeDesc.get = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.get = undefined; + } + } + if (setterPointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof setterPointerOrPrimitive === 'function') { + setterPointerOrPrimitive(); + safeDesc.set = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.set = undefined; + } + } + if (valuePointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof valuePointerOrPrimitive === 'function') { + valuePointerOrPrimitive(); + safeDesc.value = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.value = valuePointerOrPrimitive; + } + } + if (configurable === false) { + // Update the descriptor to non-configurable on + // the shadow target. + ReflectDefineProperty(shadowTarget, key, safeDesc); + } + }); + } catch (error) { + var _selectedTarget10; + const errorToThrow = (_selectedTarget10 = selectedTarget) != null ? _selectedTarget10 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (safeDesc === undefined) { + // Avoiding calling the has trap for any proto chain operation, + // instead we implement the regular logic here in this trap. + let currentObject; + if (typeof protoPointerOrNull === 'function') { + protoPointerOrNull(); + currentObject = selectedTarget; + selectedTarget = undefined; + } else { + currentObject = null; + } + while (currentObject) { + safeDesc = ReflectGetOwnPropertyDescriptor(currentObject, key); + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + break; + } + currentObject = ReflectGetPrototypeOf(currentObject); + } + if (safeDesc) { + var _ref3; + const { + get: getter, + set: setter, + value: localValue + } = safeDesc; + const possibleProxy = (_ref3 = getter != null ? getter : setter) != null ? _ref3 : localValue; + safeDesc.foreign = (typeof possibleProxy === 'object' && possibleProxy !== null || typeof possibleProxy === 'function') && proxyPointerCache.get(possibleProxy) !== undefined; + } + } + return safeDesc; + } + function passthruForeignTraversedSet(foreignTargetPointer, shadowTarget, key, value, receiver) { + const safeDesc = lookupForeignDescriptor(foreignTargetPointer, shadowTarget, key); + // Following the specification steps for + // OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ). + // https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor + if (safeDesc) { + if ('get' in safeDesc || 'set' in safeDesc) { + const { + set: setter + } = safeDesc; + if (setter) { + if (safeDesc.foreign) { + foreignCallableApply(getTransferablePointer(setter), + // Inline getTransferableValue(). + typeof receiver === 'object' && receiver !== null || typeof receiver === 'function' ? getTransferablePointer(receiver) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof receiver === 'undefined' ? undefined : receiver, + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' ? undefined : value); + } else { + // Even though the setter function exists, we can't + // use `ReflectSet()` because there might be a + // distortion for that setter function, in which + // case we must resolve the local setter and call + // it instead. + ReflectApply(setter, receiver, [value]); + } + // If there is a setter, it either throw or we can assume + // the value was set. + return true; + } + return false; + } + if (safeDesc.writable === false) { + return false; + } + } + // Exit early if receiver is not object like. + if (!(typeof receiver === 'object' && receiver !== null || typeof receiver === 'function')) { + return false; + } + const safeReceiverDesc = ReflectGetOwnPropertyDescriptor(receiver, key); + if (safeReceiverDesc) { + ReflectSetPrototypeOf(safeReceiverDesc, null); + // Exit early for accessor descriptors or non-writable data + // descriptors. + if ('get' in safeReceiverDesc || 'set' in safeReceiverDesc || safeReceiverDesc.writable === false) { + return false; + } + // Setting the descriptor with only a value entry should not + // affect existing descriptor traits. + ReflectDefineProperty(receiver, key, { + __proto__: null, + value + }); + return true; + } + // `ReflectDefineProperty()` and `ReflectSet()` both are expected + // to return `false` when attempting to add a new property if the + // receiver is not extensible. + return ReflectDefineProperty(receiver, key, { + __proto__: null, + configurable: true, + enumerable: true, + value, + writable: true + }); + } + function pushErrorAcrossBoundary(error) { + if (LOCKER_DEBUGGABLE_FLAG) { + checkDebugMode(); + } + // Inline getTransferableValue(). + if (typeof error === 'object' && error !== null || typeof error === 'function') { + const foreignErrorPointer = getTransferablePointer(error, foreignCallablePushErrorTarget); + foreignErrorPointer(); + } + return error; + } + function pushTarget(foreignTargetPointer, foreignTargetTraits, foreignTargetFunctionArity, foreignTargetFunctionName, foreignTargetTypedArrayLength) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + const { + proxy + } = new BoundaryProxyHandler(foreignTargetPointer, foreignTargetTraits, foreignTargetFunctionArity, foreignTargetFunctionName, foreignTargetTypedArrayLength); + proxyPointerCache.set(proxy, foreignTargetPointer); + return createPointer(proxy); + } + const setLazyPropertyDescriptorStateByTarget = IS_IN_SHADOW_REALM ? (target, state) => { + lazyPropertyDescriptorStateCache.set(target, state); + foreignCallableSetLazyPropertyDescriptorStateByTarget(getTransferablePointer(target), getTransferablePointer(state)); + } : noop; + class BoundaryProxyHandler { + constructor(foreignTargetPointer, foreignTargetTraits, foreignTargetFunctionArity, foreignTargetFunctionName, foreignTargetTypedArrayLength) { + // Internal red/shadow realm side utilities: + this.makeProxyLive = IS_IN_SHADOW_REALM ? function () { + // Replace pending traps with live traps that can work with the + // target without taking snapshots. + this.deleteProperty = BoundaryProxyHandler.passthruDeletePropertyTrap; + this.defineProperty = BoundaryProxyHandler.passthruDefinePropertyTrap; + this.preventExtensions = BoundaryProxyHandler.passthruPreventExtensionsTrap; + this.set = BoundaryProxyHandler.passthruSetTrap; + this.setPrototypeOf = BoundaryProxyHandler.passthruSetPrototypeOfTrap; + } : noop; + this.makeProxyStatic = IS_IN_SHADOW_REALM ? function () { + // Reset all traps except apply and construct for static proxies + // since the proxy target is the shadow target and all operations + // are going to be applied to it rather than the real target. + this.defineProperty = BoundaryProxyHandler.staticDefinePropertyTrap; + this.deleteProperty = BoundaryProxyHandler.staticDeletePropertyTrap; + this.get = BoundaryProxyHandler.staticGetTrap; + this.getOwnPropertyDescriptor = BoundaryProxyHandler.staticGetOwnPropertyDescriptorTrap; + this.getPrototypeOf = BoundaryProxyHandler.staticGetPrototypeOfTrap; + this.has = BoundaryProxyHandler.staticHasTrap; + this.isExtensible = BoundaryProxyHandler.staticIsExtensibleTrap; + this.ownKeys = BoundaryProxyHandler.staticOwnKeysTrap; + this.preventExtensions = BoundaryProxyHandler.staticPreventExtensionsTrap; + this.set = BoundaryProxyHandler.staticSetTrap; + this.setPrototypeOf = BoundaryProxyHandler.staticSetPrototypeOfTrap; + const { + foreignTargetPointer, + foreignTargetTraits, + shadowTarget + } = this; + if (useFastForeignTargetPath) { + fastForeignTargetPointers.delete(foreignTargetPointer); + } + // We don't wrap `foreignCallableGetTargetIntegrityTraits()` + // in a try-catch because it cannot throw. + const targetIntegrityTraits = foreignCallableGetTargetIntegrityTraits(foreignTargetPointer); + if (targetIntegrityTraits & 8 /* TargetIntegrityTraits.Revoked */) { + // the target is a revoked proxy, in which case we revoke + // this proxy as well. + this.revoke(); + return; + } + // A proxy can revoke itself when traps are triggered and break + // the membrane, therefore we need protection. + try { + copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget(foreignTargetPointer, shadowTarget); + } catch (_unused27) { + // We don't wrap `foreignCallableIsTargetRevoked()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetRevoked(foreignTargetPointer)) { + this.revoke(); + return; + } + } + if (foreignTargetTraits & 16 /* TargetTraits.IsObject */ && !(SymbolToStringTag in shadowTarget)) { + let toStringTag = 'Object'; + try { + toStringTag = foreignCallableGetToStringTagOfTarget(foreignTargetPointer); + // eslint-disable-next-line no-empty + } catch (_unused28) {} + this.staticToStringTag = toStringTag; + } + // Preserve the semantics of the target. + if (targetIntegrityTraits & 4 /* TargetIntegrityTraits.IsFrozen */) { + ObjectFreeze(shadowTarget); + } else { + if (targetIntegrityTraits & 2 /* TargetIntegrityTraits.IsSealed */) { + ObjectSeal(shadowTarget); + } else if (targetIntegrityTraits & 1 /* TargetIntegrityTraits.IsNotExtensible */) { + ReflectPreventExtensions(shadowTarget); + } + if (LOCKER_UNMINIFIED_FLAG) { + // We don't wrap `foreignCallableDebugInfo()` in a try-catch + // because it cannot throw. + foreignCallableDebugInfo('Mutations on the membrane of an object originating ' + 'outside of the sandbox will not be reflected on ' + 'the object itself:', foreignTargetPointer); + } + } + } : noop; + let shadowTarget; + const isForeignTargetArray = foreignTargetTraits & 1 /* TargetTraits.IsArray */; + const isForeignTargetFunction = foreignTargetTraits & 4 /* TargetTraits.IsFunction */; + if (isForeignTargetFunction) { + // This shadow target is never invoked. It's needed to avoid + // proxy trap invariants. Because it's not invoked the code + // does not need to be instrumented for code coverage. + // + // istanbul ignore next + shadowTarget = foreignTargetTraits & 8 /* TargetTraits.IsArrowFunction */ ? () => {} : function () {}; + } else if (isForeignTargetArray) { + shadowTarget = []; + } else { + shadowTarget = {}; + } + const { + proxy, + revoke + } = ProxyRevocable(shadowTarget, this); + this.foreignTargetPointer = foreignTargetPointer; + this.foreignTargetTraits = foreignTargetTraits; + this.foreignTargetTypedArrayLength = foreignTargetTypedArrayLength; + // Define in the BoundaryProxyHandler constructor so it is bound + // to the BoundaryProxyHandler instance. + this.nonConfigurableDescriptorCallback = (key, configurable, enumerable, writable, valuePointer, getterPointer, setterPointer) => { + // Update the descriptor to non-configurable on the shadow + // target. + ReflectDefineProperty(this.shadowTarget, key, createDescriptorFromMeta(configurable, enumerable, writable, valuePointer, getterPointer, setterPointer)); + }; + this.proxy = proxy; + this.revoke = revoke; + this.serialize = noop; + this.shadowTarget = shadowTarget; + this.staticToStringTag = 'Object'; + // Define traps. + if (isForeignTargetFunction) { + var _applyTrapNameRegistr, _constructTrapNameReg; + this.apply = this[(_applyTrapNameRegistr = applyTrapNameRegistry[foreignTargetFunctionArity]) != null ? _applyTrapNameRegistr : applyTrapNameRegistry.n]; + this.construct = this[(_constructTrapNameReg = constructTrapNameRegistry[foreignTargetFunctionArity]) != null ? _constructTrapNameReg : constructTrapNameRegistry.n]; + } + this.defineProperty = BoundaryProxyHandler.defaultDefinePropertyTrap; + this.deleteProperty = BoundaryProxyHandler.defaultDeletePropertyTrap; + this.isExtensible = BoundaryProxyHandler.defaultIsExtensibleTrap; + this.getOwnPropertyDescriptor = BoundaryProxyHandler.defaultGetOwnPropertyDescriptorTrap; + this.getPrototypeOf = BoundaryProxyHandler.defaultGetPrototypeOfTrap; + this.get = foreignTargetTraits & 32 /* TargetTraits.IsTypedArray */ ? BoundaryProxyHandler.hybridGetTrapForTypedArray : BoundaryProxyHandler.defaultGetTrap; + this.has = BoundaryProxyHandler.defaultHasTrap; + this.ownKeys = BoundaryProxyHandler.defaultOwnKeysTrap; + this.preventExtensions = BoundaryProxyHandler.defaultPreventExtensionsTrap; + this.setPrototypeOf = BoundaryProxyHandler.defaultSetPrototypeOfTrap; + this.set = BoundaryProxyHandler.defaultSetTrap; + if (foreignTargetTraits & 64 /* TargetTraits.Revoked */) { + this.revoke(); + } else if (IS_IN_SHADOW_REALM) { + if (isForeignTargetArray || foreignTargetTraits & 2 /* TargetTraits.IsArrayBufferView */) { + this.makeProxyLive(); + } + } else { + if (foreignTargetTraits & 16 /* TargetTraits.IsObject */) { + // Lazily define serialize method. + let cachedSerializedValue = LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + this.serialize = () => { + if (cachedSerializedValue === LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + cachedSerializedValue = foreignCallableSerializeTarget(this.foreignTargetPointer); + } + return cachedSerializedValue; + }; + } + } + } + // Passthru traps: + static passthruDefinePropertyTrap(_shadowTarget, key, unsafePartialDesc) { + lastProxyTrapCalled = 4 /* ProxyHandlerTraps.DefineProperty */; + const { + foreignTargetPointer, + nonConfigurableDescriptorCallback + } = this; + const safePartialDesc = unsafePartialDesc; + ReflectSetPrototypeOf(safePartialDesc, null); + const { + get: getter, + set: setter, + value + } = safePartialDesc; + const valuePointerOrPrimitive = 'value' in safePartialDesc ? + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' ? undefined : value : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + const getterPointerOrUndefinedSymbol = 'get' in safePartialDesc ? + // Inline getTransferableValue(). + typeof getter === 'function' ? getTransferablePointer(getter) : getter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + const setterPointerOrUndefinedSymbol = 'set' in safePartialDesc ? + // Inline getTransferableValue(). + typeof setter === 'function' ? getTransferablePointer(setter) : setter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + let result = false; + try { + result = foreignCallableDefineProperty(foreignTargetPointer, key, 'configurable' in safePartialDesc ? !!safePartialDesc.configurable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'enumerable' in safePartialDesc ? !!safePartialDesc.enumerable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'writable' in safePartialDesc ? !!safePartialDesc.writable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, valuePointerOrPrimitive, getterPointerOrUndefinedSymbol, setterPointerOrUndefinedSymbol, nonConfigurableDescriptorCallback); + } catch (error) { + var _selectedTarget11; + const errorToThrow = (_selectedTarget11 = selectedTarget) != null ? _selectedTarget11 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (useFastForeignTargetPath && result && (typeof getterPointerOrUndefinedSymbol === 'function' || typeof setterPointerOrUndefinedSymbol === 'function')) { + fastForeignTargetPointers.delete(foreignTargetPointer); + } + return result; + } + static passthruDeletePropertyTrap(_shadowTarget, key) { + lastProxyTrapCalled = 8 /* ProxyHandlerTraps.DeleteProperty */; + let result = false; + try { + result = foreignCallableDeleteProperty(this.foreignTargetPointer, key); + } catch (error) { + var _selectedTarget12; + const errorToThrow = (_selectedTarget12 = selectedTarget) != null ? _selectedTarget12 : error; + selectedTarget = undefined; + throw errorToThrow; + } + return result; + } + static passthruGetPrototypeOfTrap(_shadowTarget) { + lastProxyTrapCalled = 64 /* ProxyHandlerTraps.GetPrototypeOf */; + let protoPointerOrNull; + try { + protoPointerOrNull = foreignCallableGetPrototypeOf(this.foreignTargetPointer); + } catch (error) { + var _selectedTarget13; + const errorToThrow = (_selectedTarget13 = selectedTarget) != null ? _selectedTarget13 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let proto; + if (typeof protoPointerOrNull === 'function') { + protoPointerOrNull(); + proto = selectedTarget; + selectedTarget = undefined; + } else { + proto = null; + } + return proto; + } + static passthruIsExtensibleTrap(_shadowTarget) { + lastProxyTrapCalled = 256 /* ProxyHandlerTraps.IsExtensible */; + const { + shadowTarget + } = this; + let result = false; + // Check if already locked. + if (ReflectIsExtensible(shadowTarget)) { + const { + foreignTargetPointer + } = this; + try { + result = foreignCallableIsExtensible(foreignTargetPointer); + } catch (error) { + var _selectedTarget14; + const errorToThrow = (_selectedTarget14 = selectedTarget) != null ? _selectedTarget14 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (!result) { + copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget(foreignTargetPointer, shadowTarget); + ReflectPreventExtensions(shadowTarget); + } + } + return result; + } + static passthruOwnKeysTrap(_shadowTarget) { + lastProxyTrapCalled = 512 /* ProxyHandlerTraps.OwnKeys */; + let ownKeys; + try { + foreignCallableOwnKeys(this.foreignTargetPointer, (...args) => { + ownKeys = args; + }); + } catch (error) { + var _selectedTarget15; + const errorToThrow = (_selectedTarget15 = selectedTarget) != null ? _selectedTarget15 : error; + selectedTarget = undefined; + throw errorToThrow; + } + return ownKeys || []; + } + static passthruGetOwnPropertyDescriptorTrap(_shadowTarget, key) { + lastProxyTrapCalled = 32 /* ProxyHandlerTraps.GetOwnPropertyDescriptor */; + const { + foreignTargetPointer, + shadowTarget + } = this; + let safeDesc; + try { + foreignCallableGetOwnPropertyDescriptor(foreignTargetPointer, key, (_key, configurable, enumerable, writable, valuePointer, getterPointer, setterPointer) => { + safeDesc = createDescriptorFromMeta(configurable, enumerable, writable, valuePointer, getterPointer, setterPointer); + if (safeDesc.configurable === false) { + // Update the descriptor to non-configurable on + // the shadow target. + ReflectDefineProperty(shadowTarget, key, safeDesc); + } + }); + } catch (error) { + var _selectedTarget16; + const errorToThrow = (_selectedTarget16 = selectedTarget) != null ? _selectedTarget16 : error; + selectedTarget = undefined; + throw errorToThrow; + } + // Getting forged descriptors of handshake properties is not allowed. + if (IS_NOT_IN_SHADOW_REALM && safeDesc && (key === LOCKER_NEAR_MEMBRANE_SYMBOL || key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL)) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + return safeDesc; + } + static passthruPreventExtensionsTrap(_shadowTarget) { + lastProxyTrapCalled = 1024 /* ProxyHandlerTraps.PreventExtensions */; + const { + foreignTargetPointer, + shadowTarget + } = this; + let result = true; + if (ReflectIsExtensible(shadowTarget)) { + let resultEnum = 0 /* PreventExtensionsResult.None */; + try { + resultEnum = foreignCallablePreventExtensions(foreignTargetPointer); + } catch (error) { + var _selectedTarget17; + const errorToThrow = (_selectedTarget17 = selectedTarget) != null ? _selectedTarget17 : error; + selectedTarget = undefined; + throw errorToThrow; + } + // If the target is a proxy it might reject the + // preventExtension call, in which case we should not + // attempt to lock down the shadow target. + if (!(resultEnum & 1 /* PreventExtensionsResult.Extensible */)) { + copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget(foreignTargetPointer, shadowTarget); + ReflectPreventExtensions(shadowTarget); + } + result = !(resultEnum & 2 /* PreventExtensionsResult.False */); + } + + return result; + } + static passthruSetPrototypeOfTrap(_shadowTarget, proto) { + lastProxyTrapCalled = 4096 /* ProxyHandlerTraps.SetPrototypeOf */; + const { + foreignTargetPointer + } = this; + const transferableProto = proto ? getTransferablePointer(proto) : proto; + let result = false; + try { + result = foreignCallableSetPrototypeOf(foreignTargetPointer, transferableProto); + } catch (error) { + var _selectedTarget18; + const errorToThrow = (_selectedTarget18 = selectedTarget) != null ? _selectedTarget18 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (useFastForeignTargetPath && result) { + fastForeignTargetPointers.delete(foreignTargetPointer); + } + return result; + } + static passthruSetTrap(_shadowTarget, key, value, receiver) { + lastProxyTrapCalled = 2048 /* ProxyHandlerTraps.Set */; + const { + foreignTargetPointer, + proxy, + shadowTarget + } = this; + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof value === 'undefined') { + value = undefined; + } + if (typeof receiver === 'undefined') { + receiver = proxy; + } + // Setting forged values of handshake properties is not allowed. + if (IS_NOT_IN_SHADOW_REALM && (key === LOCKER_NEAR_MEMBRANE_SYMBOL || key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL)) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + const isFastPath = proxy === receiver; + let result = false; + try { + result = isFastPath ? foreignCallableSet(foreignTargetPointer, key, + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : value) : passthruForeignTraversedSet(foreignTargetPointer, shadowTarget, key, value, receiver); + } catch (error) { + var _selectedTarget19; + const errorToThrow = (_selectedTarget19 = selectedTarget) != null ? _selectedTarget19 : error; + selectedTarget = undefined; + throw errorToThrow; + } + return result; + } + } + // Logic implementation of all traps. + // Hybrid traps: + // (traps that operate on their shadowTarget, proxy, and foreignTargetPointer): + BoundaryProxyHandler.hybridGetTrap = IS_IN_SHADOW_REALM ? function (_shadowTarget, key, receiver) { + const { + foreignTargetPointer, + foreignTargetTraits, + proxy, + shadowTarget + } = this; + let safeDesc; + let result; + if (useFastForeignTargetPath && fastForeignTargetPointers.has(foreignTargetPointer)) { + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGetPropertyValue(foreignTargetPointer, key); + } catch (error) { + var _selectedTarget20; + const errorToThrow = (_selectedTarget20 = selectedTarget) != null ? _selectedTarget20 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + safeDesc = lookupForeignDescriptor(foreignTargetPointer, shadowTarget, key); + if (safeDesc) { + const { + get: getter, + value: localValue + } = safeDesc; + if (getter) { + if (safeDesc.foreign) { + const foreignGetterPointer = getTransferablePointer(getter); + const transferableReceiver = proxy === receiver ? foreignTargetPointer : + // Inline getTransferableValue(). + typeof receiver === 'object' && receiver !== null || typeof receiver === 'function' ? getTransferablePointer(receiver) : receiver; + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableApply(foreignGetterPointer, transferableReceiver); + } catch (error) { + var _selectedTarget21; + const errorToThrow = (_selectedTarget21 = selectedTarget) != null ? _selectedTarget21 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + // Even though the getter function exists, + // we can't use `ReflectGet()` because there + // might be a distortion for that getter function, + // in which case we must resolve the local getter + // and call it instead. + result = ReflectApply(getter, receiver, []); + } + } else { + result = localValue; + } + } else { + const transferableReceiver = proxy === receiver ? foreignTargetPointer : + // Inline getTransferableValue(). + typeof receiver === 'object' && receiver !== null || typeof receiver === 'function' ? getTransferablePointer(receiver) : receiver; + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGet(foreignTargetPointer, foreignTargetTraits, key, transferableReceiver); + } catch (error) { + var _selectedTarget22; + const errorToThrow = (_selectedTarget22 = selectedTarget) != null ? _selectedTarget22 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } + } + if (safeDesc === undefined && result === undefined && key === SymbolToStringTag && foreignTargetTraits & 16 /* TargetTraits.IsObject */) { + let toStringTag; + try { + toStringTag = foreignCallableGetToStringTagOfTarget(foreignTargetPointer); + } catch (error) { + var _selectedTarget23; + const errorToThrow = (_selectedTarget23 = selectedTarget) != null ? _selectedTarget23 : error; + selectedTarget = undefined; + throw errorToThrow; + } + // The default language toStringTag is "Object". If we + // receive "Object" we return `undefined` to let the + // language resolve it naturally without projecting a + // value. + if (toStringTag !== 'Object') { + result = toStringTag; + } + } + return result; + } : noop; + BoundaryProxyHandler.hybridGetTrapForTypedArray = IS_IN_SHADOW_REALM ? function (_shadowTarget, key, receiver) { + const { + foreignTargetPointer, + foreignTargetTypedArrayLength, + proxy, + shadowTarget + } = this; + let useFastPath = useFastForeignTargetPathForTypedArrays; + if (!useFastPath && typeof key === 'string') { + const possibleIndex = +key; + useFastPath = possibleIndex > -1 && possibleIndex < foreignTargetTypedArrayLength && NumberIsInteger(possibleIndex); + } + let result; + if (useFastPath) { + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGetPropertyValue(foreignTargetPointer, key); + } catch (error) { + var _selectedTarget24; + const errorToThrow = (_selectedTarget24 = selectedTarget) != null ? _selectedTarget24 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + const safeDesc = lookupForeignDescriptor(foreignTargetPointer, shadowTarget, key); + if (safeDesc) { + const { + get: getter, + value: localValue + } = safeDesc; + if (getter) { + if (safeDesc.foreign) { + const foreignGetterPointer = getTransferablePointer(getter); + const transferableReceiver = proxy === receiver ? foreignTargetPointer : + // Inline getTransferableValue(). + typeof receiver === 'object' && receiver !== null || typeof receiver === 'function' ? getTransferablePointer(receiver) : receiver; + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableApply(foreignGetterPointer, transferableReceiver); + } catch (error) { + var _selectedTarget25; + const errorToThrow = (_selectedTarget25 = selectedTarget) != null ? _selectedTarget25 : error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + // Even though the getter function exists, + // we can't use `ReflectGet()` because there + // might be a distortion for that getter function, + // in which case we must resolve the local getter + // and call it instead. + result = ReflectApply(getter, receiver, []); + } + } else { + result = localValue; + } + } + } + return result; + } : noop; + BoundaryProxyHandler.hybridHasTrap = IS_IN_SHADOW_REALM ? function (_shadowTarget, key) { + let trueOrProtoPointerOrNull; + try { + trueOrProtoPointerOrNull = foreignCallableBatchGetPrototypeOfWhenHasNoOwnProperty(this.foreignTargetPointer, key); + } catch (error) { + var _selectedTarget26; + const errorToThrow = (_selectedTarget26 = selectedTarget) != null ? _selectedTarget26 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result = false; + if (trueOrProtoPointerOrNull === true) { + result = true; + } else { + // Avoiding calling the has trap for any proto chain operation, + // instead we implement the regular logic here in this trap. + let currentObject; + if (typeof trueOrProtoPointerOrNull === 'function') { + trueOrProtoPointerOrNull(); + currentObject = selectedTarget; + selectedTarget = undefined; + } else { + currentObject = null; + } + while (currentObject) { + if (ObjectHasOwn(currentObject, key)) { + result = true; + break; + } + currentObject = ReflectGetPrototypeOf(currentObject); + } + } + return result; + } : alwaysFalse; + BoundaryProxyHandler.passthruGetTrap = IS_NOT_IN_SHADOW_REALM ? function (_shadowTarget, key, receiver) { + // Only allow accessing handshake property values if the + // "has" trap has been triggered immediately BEFORE and + // the property does NOT exist. + handshakePropertyFlag && (handshakePropertyFlag = lastProxyTrapCalled === 128 /* ProxyHandlerTraps.Has */); + lastProxyTrapCalled = 16 /* ProxyHandlerTraps.Get */; + const isNearMembraneSymbol = key === LOCKER_NEAR_MEMBRANE_SYMBOL; + const isNearMembraneSerializedValueSymbol = key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL; + if (handshakePropertyFlag) { + // Exit without performing a [[Get]] for handshake + // properties because we know that when the + // `handshakePropertyFlag` is ON that there are NO + // shadowed values. + if (isNearMembraneSymbol) { + return true; + } + if (isNearMembraneSerializedValueSymbol) { + return this.serialize(); + } + } + const { + foreignTargetPointer, + foreignTargetTraits, + proxy + } = this; + if (typeof receiver === 'undefined') { + receiver = proxy; + } + const transferableReceiver = proxy === receiver ? LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL : + // Inline getTransferableValue(). + typeof receiver === 'object' && receiver !== null || typeof receiver === 'function' ? getTransferablePointer(receiver) : receiver; + let pointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGet(foreignTargetPointer, foreignTargetTraits, key, transferableReceiver); + } catch (error) { + var _selectedTarget27; + const errorToThrow = (_selectedTarget27 = selectedTarget) != null ? _selectedTarget27 : error; + selectedTarget = undefined; + throw errorToThrow; + } + let result; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + // Getting forged values of handshake properties is not allowed. + if (result !== undefined && (isNearMembraneSymbol || isNearMembraneSerializedValueSymbol)) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + return result; + } : noop; + BoundaryProxyHandler.passthruHasTrap = IS_NOT_IN_SHADOW_REALM ? function (_shadowTarget, key) { + lastProxyTrapCalled = 128 /* ProxyHandlerTraps.Has */; + let result; + try { + result = foreignCallableHas(this.foreignTargetPointer, key); + } catch (error) { + var _selectedTarget28; + const errorToThrow = (_selectedTarget28 = selectedTarget) != null ? _selectedTarget28 : error; + selectedTarget = undefined; + throw errorToThrow; + } + const isNearMembraneSymbol = key === LOCKER_NEAR_MEMBRANE_SYMBOL; + const isNearMembraneSerializedValueSymbol = key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL; + if (result) { + handshakePropertyFlag = false; + // Checking the existence of forged handshake properties + // is not allowed. + if (isNearMembraneSymbol || isNearMembraneSerializedValueSymbol) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + } else { + // The `handshakePropertyFlag` is ON if the handshake + // property does NOT exist on the object or its [[Prototype]]. + handshakePropertyFlag = isNearMembraneSymbol || isNearMembraneSerializedValueSymbol; + } + return result; + } : alwaysFalse; + // Pending traps: + BoundaryProxyHandler.pendingDefinePropertyTrap = IS_IN_SHADOW_REALM ? function (shadowTarget, key, unsafePartialDesc) { + const { + foreignTargetPointer, + foreignTargetTraits + } = this; + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(foreignTargetPointer, foreignTargetTraits)) { + this.makeProxyLive(); + } else { + if (useFastForeignTargetPath) { + if (isForeignPointerOfObjectProto(foreignTargetPointer)) { + disableFastForeignTargetPointers(); + } else if (isForeignPointerOfTypedArrayProto(foreignTargetPointer)) { + useFastForeignTargetPathForTypedArrays = false; + } + } + this.makeProxyStatic(); + } + return this.defineProperty(shadowTarget, key, unsafePartialDesc); + } : alwaysFalse; + BoundaryProxyHandler.pendingDeletePropertyTrap = IS_IN_SHADOW_REALM ? function (shadowTarget, key) { + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(this.foreignTargetPointer, this.foreignTargetTraits)) { + this.makeProxyLive(); + } else { + this.makeProxyStatic(); + } + return this.deleteProperty(shadowTarget, key); + } : alwaysFalse; + BoundaryProxyHandler.pendingPreventExtensionsTrap = IS_IN_SHADOW_REALM ? function (shadowTarget) { + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(this.foreignTargetPointer, this.foreignTargetTraits)) { + this.makeProxyLive(); + } else { + this.makeProxyStatic(); + } + return this.preventExtensions(shadowTarget); + } : alwaysFalse; + BoundaryProxyHandler.pendingSetPrototypeOfTrap = IS_IN_SHADOW_REALM ? function (shadowTarget, proto) { + const { + foreignTargetPointer, + foreignTargetTraits + } = this; + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(foreignTargetPointer, foreignTargetTraits)) { + this.makeProxyLive(); + } else { + if (useFastForeignTargetPath) { + if (isForeignPointerOfObjectProto(foreignTargetPointer)) { + disableFastForeignTargetPointers(); + } else if (isForeignPointerOfTypedArrayProto(foreignTargetPointer)) { + useFastForeignTargetPathForTypedArrays = false; + } + } + this.makeProxyStatic(); + } + return this.setPrototypeOf(shadowTarget, proto); + } : alwaysFalse; + BoundaryProxyHandler.pendingSetTrap = IS_IN_SHADOW_REALM ? function (shadowTarget, key, value, receiver) { + const { + foreignTargetPointer, + foreignTargetTraits + } = this; + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(foreignTargetPointer, foreignTargetTraits)) { + this.makeProxyLive(); + } else { + if (useFastForeignTargetPath) { + if (isForeignPointerOfObjectProto(foreignTargetPointer)) { + disableFastForeignTargetPointers(); + } else if (isForeignPointerOfTypedArrayProto(foreignTargetPointer)) { + useFastForeignTargetPathForTypedArrays = false; + } + } + this.makeProxyStatic(); + } + return this.set(shadowTarget, key, value, receiver); + } : alwaysFalse; + // Static traps: + BoundaryProxyHandler.staticDefinePropertyTrap = IS_IN_SHADOW_REALM ? ReflectDefineProperty : alwaysFalse; + BoundaryProxyHandler.staticDeletePropertyTrap = IS_IN_SHADOW_REALM ? ReflectDeleteProperty : alwaysFalse; + BoundaryProxyHandler.staticGetOwnPropertyDescriptorTrap = IS_IN_SHADOW_REALM ? ReflectGetOwnPropertyDescriptor : noop; + BoundaryProxyHandler.staticGetPrototypeOfTrap = IS_IN_SHADOW_REALM ? ReflectGetPrototypeOf : () => null; + BoundaryProxyHandler.staticGetTrap = IS_IN_SHADOW_REALM ? function (shadowTarget, key, receiver) { + const { + foreignTargetTraits, + staticToStringTag + } = this; + const result = ReflectGet(shadowTarget, key, receiver); + if (result === undefined && key === SymbolToStringTag && foreignTargetTraits & 16 /* TargetTraits.IsObject */ && + // The default language toStringTag is "Object". If we + // receive "Object" we return `undefined` to let the + // language resolve it naturally without projecting a + // value. + staticToStringTag !== 'Object' && !(key in shadowTarget)) { + return staticToStringTag; + } + return result; + } : noop; + BoundaryProxyHandler.staticHasTrap = IS_IN_SHADOW_REALM ? ReflectHas : alwaysFalse; + BoundaryProxyHandler.staticIsExtensibleTrap = IS_IN_SHADOW_REALM ? ReflectIsExtensible : alwaysFalse; + BoundaryProxyHandler.staticOwnKeysTrap = IS_IN_SHADOW_REALM ? ReflectOwnKeys : () => []; + BoundaryProxyHandler.staticPreventExtensionsTrap = IS_IN_SHADOW_REALM ? ReflectPreventExtensions : alwaysFalse; + BoundaryProxyHandler.staticSetPrototypeOfTrap = IS_IN_SHADOW_REALM ? ReflectSetPrototypeOf : alwaysFalse; + BoundaryProxyHandler.staticSetTrap = IS_IN_SHADOW_REALM ? ReflectSet : alwaysFalse; + // Default traps: + // Pending traps are needed for the shadow realm side of the membrane + // to avoid leaking mutation operations on the primary realm side. + BoundaryProxyHandler.defaultDefinePropertyTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.pendingDefinePropertyTrap : BoundaryProxyHandler.passthruDefinePropertyTrap; + BoundaryProxyHandler.defaultDeletePropertyTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.pendingDeletePropertyTrap : BoundaryProxyHandler.passthruDeletePropertyTrap; + BoundaryProxyHandler.defaultGetOwnPropertyDescriptorTrap = BoundaryProxyHandler.passthruGetOwnPropertyDescriptorTrap; + BoundaryProxyHandler.defaultGetPrototypeOfTrap = BoundaryProxyHandler.passthruGetPrototypeOfTrap; + BoundaryProxyHandler.defaultGetTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.hybridGetTrap : BoundaryProxyHandler.passthruGetTrap; + BoundaryProxyHandler.defaultHasTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.hybridHasTrap : BoundaryProxyHandler.passthruHasTrap; + BoundaryProxyHandler.defaultIsExtensibleTrap = BoundaryProxyHandler.passthruIsExtensibleTrap; + BoundaryProxyHandler.defaultOwnKeysTrap = BoundaryProxyHandler.passthruOwnKeysTrap; + BoundaryProxyHandler.defaultPreventExtensionsTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.pendingPreventExtensionsTrap : BoundaryProxyHandler.passthruPreventExtensionsTrap; + BoundaryProxyHandler.defaultSetTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.pendingSetTrap : BoundaryProxyHandler.passthruSetTrap; + BoundaryProxyHandler.defaultSetPrototypeOfTrap = IS_IN_SHADOW_REALM ? BoundaryProxyHandler.pendingSetPrototypeOfTrap : BoundaryProxyHandler.passthruSetPrototypeOfTrap; + if (IS_IN_SHADOW_REALM) { + // Initialize `fastForeignTargetPointers` weak map. + clearFastForeignTargetPointers(); + } + // Export callable hooks to a foreign realm. + foreignCallableHooksCallback( + // globalThisPointer + // When crossing, should be mapped to the foreign globalThis + createPointer(globalThisRef), + // getSelectedTarget + IS_NOT_IN_SHADOW_REALM ? () => { + const result = selectedTarget; + selectedTarget = undefined; + return result; + } : noop, + // getTransferableValue + value => { + if (typeof value === 'object' && value !== null || typeof value === 'function') { + return getTransferablePointer(value); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + return typeof value === 'undefined' ? undefined : value; + }, + // callableGetPropertyValuePointer: this callable function allows + // the foreign realm to access a linkable pointer for a property value. + // In order to do that, the foreign side must provide a pointer and + // a key access the value in order to produce a pointer + (targetPointer, key) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + const value = target == null ? void 0 : target[key]; + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + return createPointer(typeof value === 'undefined' ? undefined : value); + }, + // callableEvaluate + IS_IN_SHADOW_REALM ? sourceText => { + let result; + try { + result = localEval(sourceText); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + return typeof result === 'object' && result !== null || typeof result === 'function' ? getTransferablePointer(result) : result; + } : noop, + // callableLinkPointers: this callable function allows the foreign + // realm to define a linkage between two values across the membrane. + (targetPointer, newPointer) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + if (typeof target === 'object' && target !== null || typeof target === 'function') { + proxyPointerCache.set(target, newPointer); + } + }, + // callablePushErrorTarget + LOCKER_DEBUGGABLE_FLAG ? (foreignTargetPointer, foreignTargetTraits, foreignTargetFunctionArity, foreignTargetFunctionName, foreignTargetTypedArrayLength) => { + const pointer = pushTarget(foreignTargetPointer, foreignTargetTraits, foreignTargetFunctionArity, foreignTargetFunctionName, foreignTargetTypedArrayLength); + const pointerWrapper = () => { + checkDebugMode(); + return pointer(); + }; + return pointerWrapper; + } : pushTarget, + // callablePushTarget: This function can be used by a foreign realm + // to install a proxy into this realm that correspond to an object + // from the foreign realm. It returns a Pointer that can be used by + // the foreign realm to pass back a reference to this realm when + // passing arguments or returning from a foreign callable invocation. + // This function is extremely important to understand the mechanics + // of this membrane. + pushTarget, + // callableApply + (targetPointer, thisArgPointerOrUndefined, ...args) => { + targetPointer(); + const func = selectedTarget; + selectedTarget = undefined; + let thisArg; + if (typeof thisArgPointerOrUndefined === 'function') { + thisArgPointerOrUndefined(); + thisArg = selectedTarget; + selectedTarget = undefined; + } + for (let i = 0, { + length + } = args; i < length; i += 1) { + const pointerOrPrimitive = args[i]; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + args[i] = selectedTarget; + selectedTarget = undefined; + } + } + let result; + try { + result = ReflectApply(func, thisArg, args); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + return typeof result === 'object' && result !== null || typeof result === 'function' ? getTransferablePointer(result) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof result === 'undefined' ? undefined : result; + }, + // callableConstruct + (targetPointer, newTargetPointerOrUndefined, ...args) => { + targetPointer(); + const constructor = selectedTarget; + selectedTarget = undefined; + let newTarget; + if (typeof newTargetPointerOrUndefined === 'function') { + newTargetPointerOrUndefined(); + newTarget = selectedTarget; + selectedTarget = undefined; + } + for (let i = 0, { + length + } = args; i < length; i += 1) { + const pointerOrPrimitive = args[i]; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + args[i] = selectedTarget; + selectedTarget = undefined; + } + } + let result; + try { + result = ReflectConstruct(constructor, args, newTarget); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + return typeof result === 'object' && result !== null || typeof result === 'function' ? getTransferablePointer(result) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof result === 'undefined' ? undefined : result; + }, + // callableDefineProperty + (targetPointer, key, configurable, enumerable, writable, valuePointer, getterPointer, setterPointer, foreignCallableNonConfigurableDescriptorCallback) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + const safePartialDesc = createDescriptorFromMeta(configurable, enumerable, writable, valuePointer, getterPointer, setterPointer); + let result = false; + try { + result = ReflectDefineProperty(target, key, safePartialDesc); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + if (result && configurable === false) { + let safeDesc; + try { + safeDesc = ReflectGetOwnPropertyDescriptor(target, key); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + if (safeDesc.configurable === false) { + const { + get: getter, + set: setter, + value + } = safeDesc; + foreignCallableNonConfigurableDescriptorCallback(key, false, + // configurable + 'enumerable' in safeDesc ? safeDesc.enumerable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'writable' in safeDesc ? safeDesc.writable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'value' in safeDesc ? + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : value : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'get' in safeDesc ? + // Inline getTransferableValue(). + typeof getter === 'function' ? getTransferablePointer(getter) : getter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'set' in safeDesc ? + // Inline getTransferableValue(). + typeof setter === 'function' ? getTransferablePointer(setter) : setter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL); + } + } + } + return result; + }, + // callableDeleteProperty + (targetPointer, key) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + try { + return ReflectDeleteProperty(target, key); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableGet + (targetPointer, targetTraits, key, receiverPointerOrPrimitive) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let receiver; + if (typeof receiverPointerOrPrimitive === 'function') { + receiverPointerOrPrimitive(); + receiver = selectedTarget; + selectedTarget = undefined; + } else { + receiver = receiverPointerOrPrimitive === LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL ? target : receiverPointerOrPrimitive; + } + let result; + try { + result = ReflectGet(target, key, receiver); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + if (typeof result === 'object' && result !== null || typeof result === 'function') { + return getTransferablePointer(result); + } + if (result === undefined && key === SymbolToStringTag && targetTraits & 16 /* TargetTraits.IsObject */) { + try { + if (!(key in target)) { + // Section 19.1.3.6 Object.prototype.toString() + // https://tc39.github.io/ecma262/#sec-object.prototype.tostring + const brand = ReflectApply(ObjectProtoToString, target, []); + // The default language toStringTag is "Object". If + // we receive "[object Object]" we return `undefined` + // to let the language resolve it naturally without + // projecting a value. + if (brand !== '[object Object]') { + result = ReflectApply(StringProtoSlice, brand, [8, -1]); + } + } + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + return typeof result === 'undefined' ? undefined : result; + }, + // callableGetOwnPropertyDescriptor + (targetPointer, key, foreignCallableDescriptorCallback) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let safeDesc; + try { + safeDesc = ReflectGetOwnPropertyDescriptor(target, key); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + const { + get: getter, + set: setter, + value + } = safeDesc; + foreignCallableDescriptorCallback(key, 'configurable' in safeDesc ? safeDesc.configurable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'enumerable' in safeDesc ? safeDesc.enumerable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'writable' in safeDesc ? safeDesc.writable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'value' in safeDesc ? + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' ? undefined : value : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'get' in safeDesc ? + // Inline getTransferableValue(). + typeof getter === 'function' ? getTransferablePointer(getter) : getter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'set' in safeDesc ? + // Inline getTransferableValue(). + typeof setter === 'function' ? getTransferablePointer(setter) : setter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL); + } + }, + // callableGetPrototypeOf + targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let proto; + try { + proto = ReflectGetPrototypeOf(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }, + // callableHas + (targetPointer, key) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + try { + return key in target; + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableIsExtensible + targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + try { + return ReflectIsExtensible(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableOwnKeys + (targetPointer, foreignCallableKeysCallback) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let ownKeys; + try { + ownKeys = ReflectOwnKeys(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + ReflectApply(foreignCallableKeysCallback, undefined, ownKeys); + }, + // callablePreventExtensions + targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let result = 2 /* PreventExtensionsResult.False */; + try { + if (ReflectPreventExtensions(target)) { + result = 4 /* PreventExtensionsResult.True */; + } else if (ReflectIsExtensible(target)) { + result |= 1 /* PreventExtensionsResult.Extensible */; + } + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + return result; + }, + // callableSet + (targetPointer, key, valuePointerOrPrimitive) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let value; + if (typeof valuePointerOrPrimitive === 'function') { + valuePointerOrPrimitive(); + value = selectedTarget; + selectedTarget = undefined; + } else { + value = valuePointerOrPrimitive; + } + try { + return ReflectSet(target, key, value, target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableSetPrototypeOf + (targetPointer, protoPointerOrNull = null) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let proto; + if (typeof protoPointerOrNull === 'function') { + // Instead of calling `protoPointerOrNull()` directly we use + // `ReflectApply` to avoid a Maglev (https://v8.dev/blog/maglev) + // optimizing JIT bug in Chrome >= 117: + // https://bugs.chromium.org/p/chromium/issues/detail?id=1494060 + ReflectApply(protoPointerOrNull, undefined, []); + proto = selectedTarget; + selectedTarget = undefined; + } else { + proto = null; + } + try { + return ReflectSetPrototypeOf(target, proto); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableDebugInfo + LOCKER_DEBUGGABLE_FLAG ? (...args) => { + if (checkDebugMode()) { + for (let i = 0, { + length + } = args; i < length; i += 1) { + const pointerOrPrimitive = args[i]; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + args[i] = selectedTarget; + selectedTarget = undefined; + } + } + try { + ReflectApply(consoleInfo, consoleObject, args); + // eslint-disable-next-line no-empty + } catch (_unused29) {} + } + } : noop, + // callableDefineProperties + IS_IN_SHADOW_REALM ? (targetPointer, ...descriptorTuples) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + for (let i = 0, { + length + } = descriptorTuples; i < length; i += 7) { + // We don't use `ObjectDefineProperties()` here because it + // will throw an exception if it fails to define one of its + // properties. + ReflectDefineProperty(target, descriptorTuples[i], createDescriptorFromMeta(descriptorTuples[i + 1], + // configurable + descriptorTuples[i + 2], + // enumerable + descriptorTuples[i + 3], + // writable + descriptorTuples[i + 4], + // valuePointer + descriptorTuples[i + 5], + // getterPointer + descriptorTuples[i + 6] // setterPointer + )); + } + } : noop, + // callableGetLazyPropertyDescriptorStateByTarget + IS_NOT_IN_SHADOW_REALM ? targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + // We don't wrap the weak map `get()` call in a try-catch + // because we know `target` is an object. + const state = proxyTargetToLazyPropertyDescriptorStateMap.get(target); + return state ? getTransferablePointer(state) : state; + } : noop, + // callableGetPropertyValue + IS_NOT_IN_SHADOW_REALM ? (targetPointer, key) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let value; + try { + value = target[key]; + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + return typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : value; + } : noop, + // callableGetTargetIntegrityTraits + IS_NOT_IN_SHADOW_REALM ? targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + // A target may be a proxy that is revoked or throws in its + // "isExtensible" trap. + try { + if (!ReflectIsExtensible(target)) { + if (ObjectIsFrozen(target)) { + return 4 /* TargetIntegrityTraits.IsFrozen */ & 2 /* TargetIntegrityTraits.IsSealed */ & 1 /* TargetIntegrityTraits.IsNotExtensible */; + } + + if (ObjectIsSealed(target)) { + return 2 /* TargetIntegrityTraits.IsSealed */ & 1 /* TargetIntegrityTraits.IsNotExtensible */; + } + + return 1 /* TargetIntegrityTraits.IsNotExtensible */; + } + } catch (_unused30) { + try { + isArrayOrThrowForRevoked(target); + } catch (_unused31) { + return 8 /* TargetIntegrityTraits.Revoked */; + } + } + + return 0 /* TargetIntegrityTraits.None */; + } : () => 0 /* TargetIntegrityTraits.None */, + // callableGetToStringTagOfTarget + targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + try { + // Section 19.1.3.6 Object.prototype.toString() + // https://tc39.github.io/ecma262/#sec-object.prototype.tostring + const brand = ReflectApply(ObjectProtoToString, target, []); + return brand === '[object Object]' ? 'Object' : ReflectApply(StringProtoSlice, brand, [8, -1]); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableInstallErrorPrepareStackTrace + installErrorPrepareStackTrace, + // callableInstallLazyPropertyDescriptors + IS_IN_SHADOW_REALM ? (targetPointer, ...ownKeysAndUnforgeableGlobalThisKeys) => { + const sliceIndex = ReflectApply(ArrayProtoIndexOf, ownKeysAndUnforgeableGlobalThisKeys, [LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL]); + let ownKeys; + let unforgeableGlobalThisKeys; + if (sliceIndex === -1) { + ownKeys = ownKeysAndUnforgeableGlobalThisKeys; + } else { + ownKeys = ReflectApply(ArrayProtoSlice, ownKeysAndUnforgeableGlobalThisKeys, [0, sliceIndex]); + unforgeableGlobalThisKeys = ReflectApply(ArrayProtoSlice, ownKeysAndUnforgeableGlobalThisKeys, [sliceIndex + 1]); + } + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let state = getLazyPropertyDescriptorStateByTarget(target); + if (state === undefined) { + state = { + __proto__: null + }; + setLazyPropertyDescriptorStateByTarget(target, state); + } + for (let i = 0, { + length + } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + state[ownKey] = true; + ReflectDefineProperty(target, ownKey, + // The role of this descriptor is to serve as a + // bouncer. When either a getter or a setter is + // invoked the descriptor will be replaced with + // the descriptor from the foreign side and the + // get/set operation will carry on from there. + { + __proto__: null, + // We DO explicitly set configurability in the + // off chance that the property doesn't exist. + configurable: true, + // We DON'T explicitly set enumerability to + // defer to the enumerability of the existing + // property. In the off chance the property + // doesn't exist the property will be defined + // as non-enumerable. + get() { + activateLazyOwnPropertyDefinition(target, ownKey, state); + return target[ownKey]; + }, + set(value) { + activateLazyOwnPropertyDefinition(target, ownKey, state); + ReflectSet(target, ownKey, value); + } + }); + } + installPropertyDescriptorMethodWrappers(unforgeableGlobalThisKeys); + } : noop, + // callableIsTargetLive + IS_NOT_IN_SHADOW_REALM && liveTargetCallback ? (targetPointer, targetTraits) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + if (target !== ObjectProto && target !== RegExpProto) { + try { + return liveTargetCallback(target, targetTraits); + // eslint-disable-next-line no-empty + } catch (_unused32) {} + } + return false; + } : alwaysFalse, + // callableIsTargetRevoked + IS_NOT_IN_SHADOW_REALM ? targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + try { + isArrayOrThrowForRevoked(target); + return false; + // eslint-disable-next-line no-empty + } catch (_unused33) {} + return true; + } : alwaysFalse, + // callableSerializeTarget + IS_IN_SHADOW_REALM ? targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + try { + return SymbolToStringTag in target ? serializeTargetByTrialAndError(target) : + // Fast path. + serializeTargetByBrand(target); + // eslint-disable-next-line no-empty + } catch (_unused34) {} + return undefined; + } : noop, + // callableSetLazyPropertyDescriptorStateByTarget + IS_NOT_IN_SHADOW_REALM ? (targetPointer, statePointer) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + statePointer(); + const state = selectedTarget; + selectedTarget = undefined; + // We don't wrap the weak map `set()` call in a try-catch + // because we know `target` is an object. + proxyTargetToLazyPropertyDescriptorStateMap.set(target, state); + } : noop, + // callableTrackAsFastTarget + IS_IN_SHADOW_REALM ? targetPointer => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + if (useFastForeignTargetPath) { + fastForeignTargetPointers.add(getTransferablePointer(target)); + } + } : noop, + // callableBatchGetPrototypeOfAndGetOwnPropertyDescriptors + (targetPointer, foreignCallableDescriptorsCallback) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let unsafeDescs; + try { + unsafeDescs = ObjectGetOwnPropertyDescriptors(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + const ownKeys = ReflectOwnKeys(unsafeDescs); + const { + length + } = ownKeys; + const descriptorTuples = new ArrayCtor(length * 7); + for (let i = 0, j = 0; i < length; i += 1, j += 7) { + const ownKey = ownKeys[i]; + const safeDesc = unsafeDescs[ownKey]; + ReflectSetPrototypeOf(safeDesc, null); + const { + get: getter, + set: setter, + value + } = safeDesc; + descriptorTuples[j] = ownKey; + descriptorTuples[j + 1] = 'configurable' in safeDesc ? safeDesc.configurable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 2] = 'enumerable' in safeDesc ? safeDesc.enumerable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 3] = 'writable' in safeDesc ? safeDesc.writable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 4] = 'value' in safeDesc ? + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : value : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 5] = 'get' in safeDesc ? + // Inline getTransferableValue(). + typeof getter === 'function' ? getTransferablePointer(getter) : getter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 6] = 'set' in safeDesc ? + // Inline getTransferableValue(). + typeof setter === 'function' ? getTransferablePointer(setter) : setter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + } + ReflectApply(foreignCallableDescriptorsCallback, undefined, descriptorTuples); + let proto; + try { + proto = ReflectGetPrototypeOf(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }, + // callableBatchGetPrototypeOfWhenHasNoOwnProperty + (targetPointer, key) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let proto; + try { + if (ObjectHasOwn(target, key)) { + return true; + } + proto = ReflectGetPrototypeOf(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }, + // callableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + (targetPointer, key, foreignCallableDescriptorCallback) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + let safeDesc; + try { + safeDesc = ReflectGetOwnPropertyDescriptor(target, key); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + const { + get: getter, + set: setter, + value + } = safeDesc; + foreignCallableDescriptorCallback(key, 'configurable' in safeDesc ? safeDesc.configurable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'enumerable' in safeDesc ? safeDesc.enumerable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'writable' in safeDesc ? safeDesc.writable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'value' in safeDesc ? + // Inline getTransferableValue(). + typeof value === 'object' && value !== null || typeof value === 'function' ? getTransferablePointer(value) : + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' ? undefined : value : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'get' in safeDesc ? + // Inline getTransferableValue(). + typeof getter === 'function' ? getTransferablePointer(getter) : getter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, 'set' in safeDesc ? + // Inline getTransferableValue(). + typeof setter === 'function' ? getTransferablePointer(setter) : setter : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL); + return undefined; + } + let proto; + try { + proto = ReflectGetPrototypeOf(target); + } catch (error) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }); + let foreignCallablesHooked = false; + return (...hooks) => { + if (foreignCallablesHooked) { + return; + } + foreignCallablesHooked = true; + ({ + // 0: globalThisPointer, + // 1: getSelectedTarget, + // 2: getTransferableValue, + // 3: callableGetPropertyValuePointer, + // 4: callableEvaluate, + // 5: callableLinkPointers, + 6: foreignCallablePushErrorTarget, + 7: foreignCallablePushTarget, + 8: foreignCallableApply, + 9: foreignCallableConstruct, + 10: foreignCallableDefineProperty, + 11: foreignCallableDeleteProperty, + 12: foreignCallableGet, + 13: foreignCallableGetOwnPropertyDescriptor, + 14: foreignCallableGetPrototypeOf, + 15: foreignCallableHas, + 16: foreignCallableIsExtensible, + 17: foreignCallableOwnKeys, + 18: foreignCallablePreventExtensions, + 19: foreignCallableSet, + 20: foreignCallableSetPrototypeOf, + 21: foreignCallableDebugInfo, + // 22: callableDefineProperties, + 23: foreignCallableGetLazyPropertyDescriptorStateByTarget, + 24: foreignCallableGetPropertyValue, + 25: foreignCallableGetTargetIntegrityTraits, + 26: foreignCallableGetToStringTagOfTarget, + 27: foreignCallableInstallErrorPrepareStackTrace, + // 28: callableInstallLazyPropertyDescriptors, + 29: foreignCallableIsTargetLive, + 30: foreignCallableIsTargetRevoked, + 31: foreignCallableSerializeTarget, + 32: foreignCallableSetLazyPropertyDescriptorStateByTarget, + // 33: callableTrackAsFastTarget, + 34: foreignCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + 35: foreignCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + 36: foreignCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + } = hooks); + const applyTrapForZeroOrMoreArgs = createApplyOrConstructTrapForZeroOrMoreArgs(1 /* ProxyHandlerTraps.Apply */); + const applyTrapForOneOrMoreArgs = createApplyOrConstructTrapForOneOrMoreArgs(1 /* ProxyHandlerTraps.Apply */); + const applyTrapForTwoOrMoreArgs = createApplyOrConstructTrapForTwoOrMoreArgs(1 /* ProxyHandlerTraps.Apply */); + const applyTrapForThreeOrMoreArgs = createApplyOrConstructTrapForThreeOrMoreArgs(1 /* ProxyHandlerTraps.Apply */); + const applyTrapForFourOrMoreArgs = createApplyOrConstructTrapForFourOrMoreArgs(1 /* ProxyHandlerTraps.Apply */); + const applyTrapForFiveOrMoreArgs = createApplyOrConstructTrapForFiveOrMoreArgs(1 /* ProxyHandlerTraps.Apply */); + const applyTrapForAnyNumberOfArgs = createApplyOrConstructTrapForAnyNumberOfArgs(1 /* ProxyHandlerTraps.Apply */); + const constructTrapForZeroOrMoreArgs = createApplyOrConstructTrapForZeroOrMoreArgs(2 /* ProxyHandlerTraps.Construct */); + const constructTrapForOneOrMoreArgs = createApplyOrConstructTrapForOneOrMoreArgs(2 /* ProxyHandlerTraps.Construct */); + const constructTrapForTwoOrMoreArgs = createApplyOrConstructTrapForTwoOrMoreArgs(2 /* ProxyHandlerTraps.Construct */); + const constructTrapForThreeOrMoreArgs = createApplyOrConstructTrapForThreeOrMoreArgs(2 /* ProxyHandlerTraps.Construct */); + const constructTrapForFourOrMoreArgs = createApplyOrConstructTrapForFourOrMoreArgs(2 /* ProxyHandlerTraps.Construct */); + const constructTrapForFiveOrMoreArgs = createApplyOrConstructTrapForFiveOrMoreArgs(2 /* ProxyHandlerTraps.Construct */); + const constructTrapForAnyNumberOfArgs = createApplyOrConstructTrapForAnyNumberOfArgs(2 /* ProxyHandlerTraps.Construct */); + if (MINIFICATION_SAFE_TRAP_PROPERTY_NAMES === undefined) { + // A minification safe way to get the 'apply' and 'construct' + // trap property names. + MINIFICATION_SAFE_TRAP_PROPERTY_NAMES = ObjectKeys({ + applyTrapForZeroOrMoreArgs, + applyTrapForOneOrMoreArgs, + applyTrapForTwoOrMoreArgs, + applyTrapForThreeOrMoreArgs, + applyTrapForFourOrMoreArgs, + applyTrapForFiveOrMoreArgs, + applyTrapForAnyNumberOfArgs, + constructTrapForZeroOrMoreArgs, + constructTrapForOneOrMoreArgs, + constructTrapForTwoOrMoreArgs, + constructTrapForThreeOrMoreArgs, + constructTrapForFourOrMoreArgs, + constructTrapForFiveOrMoreArgs, + constructTrapForAnyNumberOfArgs + }); + } + applyTrapNameRegistry[0] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[0]; + applyTrapNameRegistry[1] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[1]; + applyTrapNameRegistry[2] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[2]; + applyTrapNameRegistry[3] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[3]; + applyTrapNameRegistry[4] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[4]; + applyTrapNameRegistry[5] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[5]; + applyTrapNameRegistry.n = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[6]; + constructTrapNameRegistry[0] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[7]; + constructTrapNameRegistry[1] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[8]; + constructTrapNameRegistry[2] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[9]; + constructTrapNameRegistry[3] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[10]; + constructTrapNameRegistry[4] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[11]; + constructTrapNameRegistry[5] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[12]; + constructTrapNameRegistry.n = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[13]; + const { + prototype: BoundaryProxyHandlerProto + } = BoundaryProxyHandler; + BoundaryProxyHandlerProto[applyTrapNameRegistry[0]] = applyTrapForZeroOrMoreArgs; + BoundaryProxyHandlerProto[applyTrapNameRegistry[1]] = applyTrapForOneOrMoreArgs; + BoundaryProxyHandlerProto[applyTrapNameRegistry[2]] = applyTrapForTwoOrMoreArgs; + BoundaryProxyHandlerProto[applyTrapNameRegistry[3]] = applyTrapForThreeOrMoreArgs; + BoundaryProxyHandlerProto[applyTrapNameRegistry[4]] = applyTrapForFourOrMoreArgs; + BoundaryProxyHandlerProto[applyTrapNameRegistry[5]] = applyTrapForFiveOrMoreArgs; + BoundaryProxyHandlerProto[applyTrapNameRegistry.n] = applyTrapForAnyNumberOfArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry[0]] = constructTrapForZeroOrMoreArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry[1]] = constructTrapForOneOrMoreArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry[2]] = constructTrapForTwoOrMoreArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry[3]] = constructTrapForThreeOrMoreArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry[4]] = constructTrapForFourOrMoreArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry[5]] = constructTrapForFiveOrMoreArgs; + BoundaryProxyHandlerProto[constructTrapNameRegistry.n] = constructTrapForAnyNumberOfArgs; + ReflectSetPrototypeOf(BoundaryProxyHandlerProto, null); + }; + }; + /* eslint-enable prefer-object-spread */ +} + +const createMembraneMarshallSourceInStrictMode = ` +'use strict'; +(${createMembraneMarshall})`; +function createBlueConnector(globalObject) { + if (typeof globalObject !== 'object' || globalObject === null) { + throw new TypeErrorCtor('Missing globalObject.'); + } + return createMembraneMarshall(globalObject); +} +function createRedConnector(evaluator) { + if (typeof evaluator !== 'function') { + throw new TypeErrorCtor('Missing evaluator function.'); + } + return evaluator(createMembraneMarshallSourceInStrictMode)(); +} +const LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL = SymbolFor('@@lockerNearMembraneUndefinedValue'); +class VirtualEnvironment { + constructor(options) { + if (options === undefined) { + throw new ErrorCtor('Missing required VirtualEnvironment options.'); + } + // prettier-ignore + const { + blueConnector, + redConnector, + distortionCallback, + instrumentation, + liveTargetCallback, + revokedProxyCallback, + signSourceCallback + // eslint-disable-next-line prefer-object-spread + } = ObjectAssign({ + __proto__: null + }, options); + let blueHooks; + const blueConnect = blueConnector('blue', (...hooks) => { + blueHooks = hooks; + }, { + distortionCallback, + instrumentation, + liveTargetCallback, + revokedProxyCallback + }); + const { + 0: blueGlobalThisPointer, + 1: blueGetSelectedTarget, + 2: blueGetTransferableValue, + 3: blueCallableGetPropertyValuePointer, + // 4: blueCallableEvaluate, + 5: blueCallableLinkPointers, + 6: blueCallablePushErrorTarget, + 7: blueCallablePushTarget, + 8: blueCallableApply, + 9: blueCallableConstruct, + 10: blueCallableDefineProperty, + 11: blueCallableDeleteProperty, + 12: blueCallableGet, + 13: blueCallableGetOwnPropertyDescriptor, + 14: blueCallableGetPrototypeOf, + 15: blueCallableHas, + 16: blueCallableIsExtensible, + 17: blueCallableOwnKeys, + 18: blueCallablePreventExtensions, + 19: blueCallableSet, + 20: blueCallableSetPrototypeOf, + // 21: blueCallableDebugInfo, + // 22: blueCallableDefineProperties, + 23: blueCallableGetLazyPropertyDescriptorStateByTarget, + 24: blueCallableGetPropertyValue, + 25: blueCallableGetTargetIntegrityTraits, + 26: blueCallableGetToStringTagOfTarget, + 27: blueCallableInstallErrorPrepareStackTrace, + // 28: blueCallableInstallLazyPropertyDescriptors, + 29: blueCallableIsTargetLive, + // 30: blueCallableIsTargetRevoked, + // 31: blueCallableSerializeTarget, + 32: blueCallableSetLazyPropertyDescriptorStateByTarget, + // 33: blueTrackAsFastTarget, + 34: blueCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + 35: blueCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + 36: blueCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + } = blueHooks; + let redHooks; + const redConnect = redConnector('red', (...hooks) => { + redHooks = hooks; + }); + const { + 0: redGlobalThisPointer, + // 1: redGetSelectedTarget, + // 2: redGetTransferableValue, + 3: redCallableGetPropertyValuePointer, + 4: redCallableEvaluate, + 5: redCallableLinkPointers, + 6: redCallablePushErrorTarget, + 7: redCallablePushTarget, + 8: redCallableApply, + 9: redCallableConstruct, + 10: redCallableDefineProperty, + 11: redCallableDeleteProperty, + 12: redCallableGet, + 13: redCallableGetOwnPropertyDescriptor, + 14: redCallableGetPrototypeOf, + 15: redCallableHas, + 16: redCallableIsExtensible, + 17: redCallableOwnKeys, + 18: redCallablePreventExtensions, + 19: redCallableSet, + 20: redCallableSetPrototypeOf, + 21: redCallableDebugInfo, + 22: redCallableDefineProperties, + 23: redCallableGetLazyPropertyDescriptorStateByTarget, + // 24: redCallableGetPropertyValue, + 25: redCallableGetTargetIntegrityTraits, + 26: redCallableGetToStringTagOfTarget, + 27: redCallableInstallErrorPrepareStackTrace, + 28: redCallableInstallLazyPropertyDescriptors, + // 29: redCallableIsTargetLive, + 30: redCallableIsTargetRevoked, + 31: redCallableSerializeTarget, + 32: redCallableSetLazyPropertyDescriptorStateByTarget, + 33: redCallableTrackAsFastTarget, + 34: redCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + 35: redCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + 36: redCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + } = redHooks; + blueConnect(noop, + // redGlobalThisPointer, + noop, + // redGetSelectedTarget, + noop, + // redGetTransferableValue, + noop, + // redCallableGetPropertyValuePointer, + noop, + // redCallableEvaluate, + noop, + // redCallableLinkPointers, + redCallablePushErrorTarget, redCallablePushTarget, redCallableApply, redCallableConstruct, redCallableDefineProperty, redCallableDeleteProperty, redCallableGet, redCallableGetOwnPropertyDescriptor, redCallableGetPrototypeOf, redCallableHas, redCallableIsExtensible, redCallableOwnKeys, redCallablePreventExtensions, redCallableSet, redCallableSetPrototypeOf, redCallableDebugInfo, noop, + // redCallableDefineProperties, + redCallableGetLazyPropertyDescriptorStateByTarget, noop, + // redCallableGetPropertyValue, + redCallableGetTargetIntegrityTraits, redCallableGetToStringTagOfTarget, redCallableInstallErrorPrepareStackTrace, noop, + // redCallableInstallLazyPropertyDescriptors, + noop, + // redCallableIsTargetLive, + redCallableIsTargetRevoked, redCallableSerializeTarget, redCallableSetLazyPropertyDescriptorStateByTarget, redCallableTrackAsFastTarget, redCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, redCallableBatchGetPrototypeOfWhenHasNoOwnProperty, redCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor); + redConnect(noop, + // blueGlobalThisPointer, + noop, + // blueGetSelectedTarget, + noop, + // blueGetTransferableValue, + noop, + // blueCallableGetPropertyValuePointer, + noop, + // blueCallableEvaluate, + noop, + // blueCallableLinkPointers, + blueCallablePushErrorTarget, blueCallablePushTarget, blueCallableApply, blueCallableConstruct, blueCallableDefineProperty, blueCallableDeleteProperty, blueCallableGet, blueCallableGetOwnPropertyDescriptor, blueCallableGetPrototypeOf, blueCallableHas, blueCallableIsExtensible, blueCallableOwnKeys, blueCallablePreventExtensions, blueCallableSet, blueCallableSetPrototypeOf, noop, + // blueCallableDebugInfo + noop, + // blueCallableDefineProperties, + blueCallableGetLazyPropertyDescriptorStateByTarget, blueCallableGetPropertyValue, blueCallableGetTargetIntegrityTraits, blueCallableGetToStringTagOfTarget, blueCallableInstallErrorPrepareStackTrace, noop, + // blueCallableInstallLazyPropertyDescriptors, + blueCallableIsTargetLive, noop, + // blueCallableIsTargetRevoked, + noop, + // blueCallableSerializeTarget,, + blueCallableSetLazyPropertyDescriptorStateByTarget, noop, + // blueCallableTrackAsFastTarget, + blueCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, blueCallableBatchGetPrototypeOfWhenHasNoOwnProperty, blueCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor); + this.blueGlobalThisPointer = blueGlobalThisPointer; + this.blueGetSelectedTarget = blueGetSelectedTarget; + this.blueGetTransferableValue = blueGetTransferableValue; + this.blueCallableGetPropertyValuePointer = blueCallableGetPropertyValuePointer; + this.blueCallableLinkPointers = blueCallableLinkPointers; + // Ensure the `this` context of red callable functions is `undefined`. + this.redGlobalThisPointer = () => redGlobalThisPointer(); + this.redCallableGetPropertyValuePointer = (targetPointer, key) => redCallableGetPropertyValuePointer(targetPointer, key); + this.redCallableEvaluate = signSourceCallback ? sourceText => redCallableEvaluate(signSourceCallback(sourceText)) : sourceText => redCallableEvaluate(sourceText); + this.redCallableLinkPointers = (targetPointer, foreignTargetPointer) => redCallableLinkPointers(targetPointer, foreignTargetPointer); + this.redCallableSetPrototypeOf = (targetPointer, protoPointerOrNull) => redCallableSetPrototypeOf(targetPointer, protoPointerOrNull); + this.redCallableDefineProperties = (targetPointer, ...descriptorTuples) => { + const { + length + } = descriptorTuples; + const args = new ArrayCtor(length + 1); + args[0] = targetPointer; + for (let i = 0; i < length; i += 1) { + args[i + 1] = descriptorTuples[i]; + } + ReflectApply(redCallableDefineProperties, undefined, args); + }; + this.redCallableInstallLazyPropertyDescriptors = (targetPointer, ...ownKeysAndUnforgeableGlobalThisKeys) => { + const { + length + } = ownKeysAndUnforgeableGlobalThisKeys; + const args = new ArrayCtor(length + 1); + args[0] = targetPointer; + for (let i = 0; i < length; i += 1) { + args[i + 1] = ownKeysAndUnforgeableGlobalThisKeys[i]; + } + ReflectApply(redCallableInstallLazyPropertyDescriptors, undefined, args); + }; + this.redCallableTrackAsFastTarget = targetPointer => redCallableTrackAsFastTarget(targetPointer); + } + evaluate(sourceText) { + try { + const bluePointerOrPrimitiveValue = this.redCallableEvaluate(sourceText); + if (typeof bluePointerOrPrimitiveValue === 'function') { + bluePointerOrPrimitiveValue(); + return this.blueGetSelectedTarget(); + } + return bluePointerOrPrimitiveValue; + } catch (error) { + var _this$blueGetSelected; + throw (_this$blueGetSelected = this.blueGetSelectedTarget()) != null ? _this$blueGetSelected : error; + } + } + lazyRemapProperties(target, ownKeys, unforgeableGlobalThisKeys) { + if (typeof target === 'object' && target !== null || typeof target === 'function') { + const args = [this.blueGetTransferableValue(target)]; + ReflectApply(ArrayProtoPush, args, ownKeys); + if (unforgeableGlobalThisKeys != null && unforgeableGlobalThisKeys.length) { + // Use `LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL` to delimit + // `ownKeys` and `unforgeableGlobalThisKeys`. + args[args.length] = LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + ReflectApply(ArrayProtoPush, args, unforgeableGlobalThisKeys); + } + ReflectApply(this.redCallableInstallLazyPropertyDescriptors, undefined, args); + } + } + link(...keys) { + let bluePointer = this.blueGlobalThisPointer; + let redPointer = this.redGlobalThisPointer; + for (let i = 0, { + length + } = keys; i < length; i += 1) { + const key = keys[i]; + bluePointer = this.blueCallableGetPropertyValuePointer(bluePointer, key); + redPointer = this.redCallableGetPropertyValuePointer(redPointer, key); + this.redCallableLinkPointers(redPointer, bluePointer); + this.blueCallableLinkPointers(bluePointer, redPointer); + } + } + remapProperties(target, unsafeBlueDescs) { + if (typeof target === 'object' && target !== null || typeof target === 'function') { + const targetPointer = this.blueGetTransferableValue(target); + const ownKeys = ReflectOwnKeys(unsafeBlueDescs); + const { + length + } = ownKeys; + const args = new ArrayCtor(1 + length * 7); + args[0] = targetPointer; + for (let i = 0, j = 1; i < length; i += 1, j += 7) { + const ownKey = ownKeys[i]; + const unsafeBlueDesc = unsafeBlueDescs[ownKey]; + // Avoid poisoning by only installing own properties from unsafeBlueDescs. + // We don't use a toSafeDescriptor() style helper since that mutates + // the unsafeBlueDesc. + // eslint-disable-next-line prefer-object-spread + const safeBlueDesc = ObjectAssign({ + __proto__: null + }, unsafeBlueDesc); + args[j] = ownKey; + args[j + 1] = 'configurable' in safeBlueDesc ? !!safeBlueDesc.configurable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 2] = 'enumerable' in safeBlueDesc ? !!safeBlueDesc.enumerable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 3] = 'writable' in safeBlueDesc ? !!safeBlueDesc.writable : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 4] = 'value' in safeBlueDesc ? this.blueGetTransferableValue(safeBlueDesc.value) : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 5] = 'get' in safeBlueDesc ? this.blueGetTransferableValue(safeBlueDesc.get) : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 6] = 'set' in safeBlueDesc ? this.blueGetTransferableValue(safeBlueDesc.set) : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + } + ReflectApply(this.redCallableDefineProperties, this, args); + } + } + remapProto(target, proto) { + if (typeof target === 'object' && target !== null || typeof target === 'function') { + const foreignTargetPointer = this.blueGetTransferableValue(target); + const transferableProto = proto ? this.blueGetTransferableValue(proto) : proto; + this.redCallableSetPrototypeOf(foreignTargetPointer, transferableProto); + } + } + trackAsFastTarget(target) { + if (typeof target === 'object' && target !== null || typeof target === 'function') { + this.redCallableTrackAsFastTarget(this.blueGetTransferableValue(target)); + } + } +} + +/** + * This list must be in sync with ecma-262, anything new added to the global object + * should be considered, to decide whether or not they need remapping. The default + * behavior, if missing form the following list, is to be remapped, which is safer. + * + * Note: remapped means the functionality is provided by the blue realm, rather than + * the red one. This helps with the identity discontinuity issue, e.g.: all Set objects + * have the same identity because it is always derived from the outer realm's Set. + * + * Note 1: We have identified 3 types of intrinsics + * A: primitives driven intrinsics + * B: syntax driven intrinsics (they usually have a imperative form as well) + * C: imperative only intrinsics + * + * While A is not remapped, it is safe, and works fast that way, and C is remapped to + * preserve the identity of all produced objects from the same realm, B is really + * problematic, and requires a lot more work to guarantee that objects from both sides + * can be considered equivalents (without identity discontinuity). + */ +function getESGlobalKeys(maxPerfMode) { + const ESGlobalKeys = [ + // *** 19.1 Value Properties of the Global Object + 'globalThis', 'Infinity', 'NaN', 'undefined', + // *** 19.2 Function Properties of the Global Object + // 'eval', // dangerous & Reflective + 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', + // *** 19.3 Constructor Properties of the Global Object + // 'AggregateError', // Reflective + // 'Array', // Reflective + 'BigInt', 'Boolean', + // 'Date', // Remapped + // 'Error', // Reflective + // 'EvalError', // Reflective + 'FinalizationRegistry', + // 'Function', // dangerous & Reflective + 'Map', 'Number', + // 'Object', // Reflective + // Allow blue `Promise` constructor to overwrite the Red one so that promises + // created by the `Promise` constructor or APIs like `fetch` will work. + // 'Promise', // Remapped + // 'Proxy', // Reflective + // 'RangeError', // Reflective + // 'ReferenceError', // Reflective + 'RegExp', 'Set', 'String', 'Symbol', + // 'SyntaxError', // Reflective + // 'TypeError', // Reflective + // 'URIError', // Reflective + 'WeakMap', 'WeakSet', 'WeakRef', + // *** 18.4 Other Properties of the Global Object + // 'Atomics', // Remapped + 'JSON', 'Math', 'Reflect', + // *** Annex B + 'escape', 'unescape' + // *** ECMA-402 + // 'Intl', // Remapped + ]; + // This set is for maxPerfMode, all of these must be from the same global object + const maxPerfModeKeys = { + intrinsics: ['ArrayBuffer', 'Atomics', 'BigInt64Array', 'BigUint64Array', 'DataView', 'Float32Array', 'Float64Array', 'Int16Array', 'Int32Array', 'Int8Array', 'SharedArrayBuffer', 'Uint16Array', 'Uint32Array', 'Uint8Array', 'Uint8ClampedArray'], + // Ideally these should come from browser-realm, that's a code reorg improvement for later + browser: ['Blob', + // 'createImageBitmap', + 'crypto', 'Crypto', 'fetch', 'File', 'FileReader', 'FileReaderSync', + // 'ImageData', + 'Request', 'Response', 'SubtleCrypto', 'TextDecoder', 'TextEncoder', 'URL', 'XMLHttpRequest'] + }; + if (maxPerfMode) { + ESGlobalKeys.push(...maxPerfModeKeys.intrinsics, ...maxPerfModeKeys.browser); + } + return ESGlobalKeys; +} +// These are foundational things that should never be wrapped but are equivalent +// @TODO: Revisit this list. +const ReflectiveIntrinsicObjectNames = ['AggregateError', 'Array', 'Error', 'EvalError', 'Function', 'Object', 'Proxy', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'eval', 'globalThis']; +function getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode) { + const ESGlobalKeys = getESGlobalKeys(maxPerfMode); + return toSafeArray([...ESGlobalKeys, ...ReflectiveIntrinsicObjectNames]); +} +function getGlobalObjectOwnKeys(source) { + const ownKeys = ReflectOwnKeys(source); + // WKWebView incorrectly excludes the 'webkit' own property of the global + // object from `Object.keys()` and `Reflect.ownKeys()` results, so add it. + // istanbul ignore if: currently unreachable via tests + if (ObjectHasOwn(source, 'webkit') && !ReflectApply(ArrayProtoIncludes, ownKeys, ['webkit'])) { + ownKeys[ownKeys.length] = 'webkit'; + } + return ownKeys; +} +function assignFilteredGlobalDescriptorsFromPropertyDescriptorMap(descs, source, maxPerfMode) { + const ownKeys = getGlobalObjectOwnKeys(source); + const ESGlobalsAndReflectiveIntrinsicObjectNames = getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode); + for (let i = 0, { + length + } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + // Avoid overriding ECMAScript global names that correspond to + // global intrinsics. This guarantee that those entries will be + // ignored if present in the source property descriptor map. + if (!ESGlobalsAndReflectiveIntrinsicObjectNames.includes(ownKey)) { + const unsafeDesc = source[ownKey]; + if (unsafeDesc) { + // Avoid poisoning by only installing own properties from + // unsafeDesc. We don't use a toSafeDescriptor() style helper + // since that mutates the unsafeBlueDesc. + // eslint-disable-next-line prefer-object-spread + descs[ownKey] = ObjectAssign({ + __proto__: null + }, unsafeDesc); + } + } + } + return descs; +} +function getFilteredGlobalOwnKeys(source, maxPerfMode) { + const result = []; + let resultOffset = 0; + const ownKeys = getGlobalObjectOwnKeys(source); + const ESGlobalsAndReflectiveIntrinsicObjectNames = getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode); + for (let i = 0, { + length + } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + // Avoid overriding ECMAScript global names that correspond to global + // intrinsics. This guarantees that those entries will be ignored if + // present in the source object. + if (!ESGlobalsAndReflectiveIntrinsicObjectNames.includes(ownKey)) { + result[resultOffset++] = ownKey; + } + } + return result; +} +function linkIntrinsics(env, globalObject) { + // Remap intrinsics that are realm agnostic. + for (let i = 0, { + length + } = ReflectiveIntrinsicObjectNames; i < length; i += 1) { + const globalName = ReflectiveIntrinsicObjectNames[i]; + const reflectiveValue = globalObject[globalName]; + if (reflectiveValue) { + // Proxy.prototype is undefined. + if (reflectiveValue.prototype) { + env.link(globalName, 'prototype'); + } else { + env.link(globalName); + } + } + } +} +export { VirtualEnvironment, assignFilteredGlobalDescriptorsFromPropertyDescriptorMap, createBlueConnector, createMembraneMarshall, createRedConnector, getFilteredGlobalOwnKeys, linkIntrinsics }; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 | + + + +4x + + + + +4x + + +4x + + + +23x + + +23x + + | import { TypeErrorCtor } from '@locker/near-membrane-shared'; +import { createMembraneMarshall } from './membrane'; +import type { Connector } from './types'; + +const createMembraneMarshallSourceInStrictMode = ` +'use strict'; +(${createMembraneMarshall})`; + +export function createBlueConnector(globalObject: typeof globalThis): Connector { + Iif (typeof globalObject !== 'object' || globalObject === null) { + throw new TypeErrorCtor('Missing globalObject.'); + } + return createMembraneMarshall(globalObject); +} + +export function createRedConnector(evaluator: typeof eval): Connector { + Iif (typeof evaluator !== 'function') { + throw new TypeErrorCtor('Missing evaluator function.'); + } + return evaluator(createMembraneMarshallSourceInStrictMode)() as Connector; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +4x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +23x + + + + + + + + + + + + +23x + +23x + + +23x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +23x + +23x +23x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +23x +23x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +23x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +23x +23x +23x +23x +23x + + +322x +23x +575x +23x + +30x +23x +575x +23x + + + +23x + + + +15x +15x +15x +15x +154x + +15x + +23x + + + +23x +23x +23x +23x +3024x + +23x + +23x + + + + +30x +30x +28x + + + +28x + +2x + + + + + + + + +23x +23x + + +23x +23x + + + + + +23x + + + + +322x +322x +322x +575x +575x +575x +575x +575x + + + + +15x +15x +15x +15x +15x +15x +15x +22x +22x + + + + +22x +22x +22x + + + +22x + + + +22x + + + +22x + + + +22x + + + +22x + + + + +15x + + + + + + + + + + + + + + + + + + + + | import { + ArrayCtor, + ArrayProtoPush, + ErrorCtor, + noop, + ObjectAssign, + ReflectApply, + ReflectOwnKeys, + SymbolFor, +} from '@locker/near-membrane-shared'; +import type { ProxyTarget } from '@locker/near-membrane-shared'; +import type { + CallableDefineProperties, + CallableDescriptorCallback, + CallableEvaluate, + CallableGetPropertyValuePointer, + CallableInstallLazyPropertyDescriptors, + CallableIsTargetLive, + CallableIsTargetRevoked, + CallableLinkPointers, + CallableSerializeTarget, + CallableSetPrototypeOf, + CallableTrackAsFastTarget, + GetSelectedTarget, + GetTransferableValue, + HooksCallback, + Pointer, + VirtualEnvironmentOptions, +} from './types'; + +const LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL = SymbolFor('@@lockerNearMembraneUndefinedValue'); + +export class VirtualEnvironment { + private readonly blueCallableGetPropertyValuePointer: CallableGetPropertyValuePointer; + + private readonly blueCallableLinkPointers: CallableLinkPointers; + + private readonly blueGetSelectedTarget: GetSelectedTarget; + + private readonly blueGetTransferableValue: GetTransferableValue; + + private readonly blueGlobalThisPointer: Pointer; + + private readonly redCallableDefineProperties: CallableDefineProperties; + + private readonly redCallableEvaluate: CallableEvaluate; + + private readonly redCallableGetPropertyValuePointer: CallableGetPropertyValuePointer; + + private readonly redCallableInstallLazyPropertyDescriptors: CallableInstallLazyPropertyDescriptors; + + private readonly redCallableLinkPointers: CallableLinkPointers; + + private readonly redCallableSetPrototypeOf: CallableSetPrototypeOf; + + private readonly redCallableTrackAsFastTarget: CallableTrackAsFastTarget; + + private readonly redGlobalThisPointer: Pointer; + + constructor(options: VirtualEnvironmentOptions) { + Iif (options === undefined) { + throw new ErrorCtor('Missing required VirtualEnvironment options.'); + } + // prettier-ignore + const { + blueConnector, + redConnector, + distortionCallback, + instrumentation, + liveTargetCallback, + revokedProxyCallback, + signSourceCallback, + // eslint-disable-next-line prefer-object-spread + } = ObjectAssign({ __proto__: null }, options); + let blueHooks: Parameters<HooksCallback>; + const blueConnect = blueConnector( + 'blue', + (...hooks: Parameters<HooksCallback>) => { + blueHooks = hooks; + }, + { + distortionCallback, + instrumentation, + liveTargetCallback, + revokedProxyCallback, + } + ); + const { + 0: blueGlobalThisPointer, + 1: blueGetSelectedTarget, + 2: blueGetTransferableValue, + 3: blueCallableGetPropertyValuePointer, + // 4: blueCallableEvaluate, + 5: blueCallableLinkPointers, + 6: blueCallablePushErrorTarget, + 7: blueCallablePushTarget, + 8: blueCallableApply, + 9: blueCallableConstruct, + 10: blueCallableDefineProperty, + 11: blueCallableDeleteProperty, + 12: blueCallableGet, + 13: blueCallableGetOwnPropertyDescriptor, + 14: blueCallableGetPrototypeOf, + 15: blueCallableHas, + 16: blueCallableIsExtensible, + 17: blueCallableOwnKeys, + 18: blueCallablePreventExtensions, + 19: blueCallableSet, + 20: blueCallableSetPrototypeOf, + // 21: blueCallableDebugInfo, + // 22: blueCallableDefineProperties, + 23: blueCallableGetLazyPropertyDescriptorStateByTarget, + 24: blueCallableGetPropertyValue, + 25: blueCallableGetTargetIntegrityTraits, + 26: blueCallableGetToStringTagOfTarget, + 27: blueCallableInstallErrorPrepareStackTrace, + // 28: blueCallableInstallLazyPropertyDescriptors, + 29: blueCallableIsTargetLive, + // 30: blueCallableIsTargetRevoked, + // 31: blueCallableSerializeTarget, + 32: blueCallableSetLazyPropertyDescriptorStateByTarget, + // 33: blueTrackAsFastTarget, + 34: blueCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + 35: blueCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + 36: blueCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor, + } = blueHooks!; + let redHooks: Parameters<HooksCallback>; + const redConnect = redConnector('red', (...hooks: Parameters<HooksCallback>) => { + redHooks = hooks; + }); + const { + 0: redGlobalThisPointer, + // 1: redGetSelectedTarget, + // 2: redGetTransferableValue, + 3: redCallableGetPropertyValuePointer, + 4: redCallableEvaluate, + 5: redCallableLinkPointers, + 6: redCallablePushErrorTarget, + 7: redCallablePushTarget, + 8: redCallableApply, + 9: redCallableConstruct, + 10: redCallableDefineProperty, + 11: redCallableDeleteProperty, + 12: redCallableGet, + 13: redCallableGetOwnPropertyDescriptor, + 14: redCallableGetPrototypeOf, + 15: redCallableHas, + 16: redCallableIsExtensible, + 17: redCallableOwnKeys, + 18: redCallablePreventExtensions, + 19: redCallableSet, + 20: redCallableSetPrototypeOf, + 21: redCallableDebugInfo, + 22: redCallableDefineProperties, + 23: redCallableGetLazyPropertyDescriptorStateByTarget, + // 24: redCallableGetPropertyValue, + 25: redCallableGetTargetIntegrityTraits, + 26: redCallableGetToStringTagOfTarget, + 27: redCallableInstallErrorPrepareStackTrace, + 28: redCallableInstallLazyPropertyDescriptors, + // 29: redCallableIsTargetLive, + 30: redCallableIsTargetRevoked, + 31: redCallableSerializeTarget, + 32: redCallableSetLazyPropertyDescriptorStateByTarget, + 33: redCallableTrackAsFastTarget, + 34: redCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + 35: redCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + 36: redCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor, + } = redHooks!; + blueConnect( + noop, // redGlobalThisPointer, + noop, // redGetSelectedTarget, + noop as GetTransferableValue, // redGetTransferableValue, + noop as unknown as CallableGetPropertyValuePointer, // redCallableGetPropertyValuePointer, + noop as CallableEvaluate, // redCallableEvaluate, + noop, // redCallableLinkPointers, + redCallablePushErrorTarget, + redCallablePushTarget, + redCallableApply, + redCallableConstruct, + redCallableDefineProperty, + redCallableDeleteProperty, + redCallableGet, + redCallableGetOwnPropertyDescriptor, + redCallableGetPrototypeOf, + redCallableHas, + redCallableIsExtensible, + redCallableOwnKeys, + redCallablePreventExtensions, + redCallableSet, + redCallableSetPrototypeOf, + redCallableDebugInfo, + noop, // redCallableDefineProperties, + redCallableGetLazyPropertyDescriptorStateByTarget, + noop, // redCallableGetPropertyValue, + redCallableGetTargetIntegrityTraits, + redCallableGetToStringTagOfTarget, + redCallableInstallErrorPrepareStackTrace, + noop, // redCallableInstallLazyPropertyDescriptors, + noop as unknown as CallableIsTargetLive, // redCallableIsTargetLive, + redCallableIsTargetRevoked, + redCallableSerializeTarget, + redCallableSetLazyPropertyDescriptorStateByTarget, + redCallableTrackAsFastTarget, + redCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + redCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + redCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + ); + redConnect( + noop, // blueGlobalThisPointer, + noop, // blueGetSelectedTarget, + noop as GetTransferableValue, // blueGetTransferableValue, + noop as unknown as CallableGetPropertyValuePointer, // blueCallableGetPropertyValuePointer, + noop as CallableEvaluate, // blueCallableEvaluate, + noop, // blueCallableLinkPointers, + blueCallablePushErrorTarget, + blueCallablePushTarget, + blueCallableApply, + blueCallableConstruct, + blueCallableDefineProperty, + blueCallableDeleteProperty, + blueCallableGet, + blueCallableGetOwnPropertyDescriptor, + blueCallableGetPrototypeOf, + blueCallableHas, + blueCallableIsExtensible, + blueCallableOwnKeys, + blueCallablePreventExtensions, + blueCallableSet, + blueCallableSetPrototypeOf, + noop, // blueCallableDebugInfo + noop, // blueCallableDefineProperties, + blueCallableGetLazyPropertyDescriptorStateByTarget, + blueCallableGetPropertyValue, + blueCallableGetTargetIntegrityTraits, + blueCallableGetToStringTagOfTarget, + blueCallableInstallErrorPrepareStackTrace, + noop, // blueCallableInstallLazyPropertyDescriptors, + blueCallableIsTargetLive, + noop as unknown as CallableIsTargetRevoked, // blueCallableIsTargetRevoked, + noop as CallableSerializeTarget, // blueCallableSerializeTarget,, + blueCallableSetLazyPropertyDescriptorStateByTarget, + noop, // blueCallableTrackAsFastTarget, + blueCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + blueCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + blueCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + ); + this.blueGlobalThisPointer = blueGlobalThisPointer; + this.blueGetSelectedTarget = blueGetSelectedTarget; + this.blueGetTransferableValue = blueGetTransferableValue; + this.blueCallableGetPropertyValuePointer = blueCallableGetPropertyValuePointer; + this.blueCallableLinkPointers = blueCallableLinkPointers; + + // Ensure the `this` context of red callable functions is `undefined`. + this.redGlobalThisPointer = () => redGlobalThisPointer(); + this.redCallableGetPropertyValuePointer = (targetPointer: Pointer, key: PropertyKey) => + redCallableGetPropertyValuePointer(targetPointer, key); + this.redCallableEvaluate = signSourceCallback + ? (sourceText: string) => redCallableEvaluate(signSourceCallback(sourceText)) + : (sourceText: string) => redCallableEvaluate(sourceText); + this.redCallableLinkPointers = (targetPointer: Pointer, foreignTargetPointer: Pointer) => + redCallableLinkPointers(targetPointer, foreignTargetPointer); + this.redCallableSetPrototypeOf = ( + targetPointer: Pointer, + protoPointerOrNull: Pointer | null + ) => redCallableSetPrototypeOf(targetPointer, protoPointerOrNull); + this.redCallableDefineProperties = ( + targetPointer: Pointer, + ...descriptorTuples: [...Parameters<CallableDescriptorCallback>] + ) => { + const { length } = descriptorTuples; + const args = new ArrayCtor(length + 1); + args[0] = targetPointer; + for (let i = 0; i < length; i += 1) { + args[i + 1] = descriptorTuples[i]; + } + ReflectApply(redCallableDefineProperties, undefined, args); + }; + this.redCallableInstallLazyPropertyDescriptors = ( + targetPointer: Pointer, + ...ownKeysAndUnforgeableGlobalThisKeys: PropertyKey[] + ) => { + const { length } = ownKeysAndUnforgeableGlobalThisKeys; + const args = new ArrayCtor(length + 1); + args[0] = targetPointer; + for (let i = 0; i < length; i += 1) { + args[i + 1] = ownKeysAndUnforgeableGlobalThisKeys[i]; + } + ReflectApply(redCallableInstallLazyPropertyDescriptors, undefined, args); + }; + this.redCallableTrackAsFastTarget = (targetPointer: Pointer) => + redCallableTrackAsFastTarget(targetPointer); + } + + evaluate(sourceText: string): any { + try { + const bluePointerOrPrimitiveValue = this.redCallableEvaluate(sourceText); + Iif (typeof bluePointerOrPrimitiveValue === 'function') { + bluePointerOrPrimitiveValue(); + return this.blueGetSelectedTarget(); + } + return bluePointerOrPrimitiveValue; + } catch (error: any) { + throw this.blueGetSelectedTarget() ?? error; + } + } + + lazyRemapProperties( + target: ProxyTarget, + ownKeys: PropertyKey[], + unforgeableGlobalThisKeys?: PropertyKey[] + ) { + Eif ((typeof target === 'object' && target !== null) || typeof target === 'function') { + const args: Parameters<CallableInstallLazyPropertyDescriptors> = [ + this.blueGetTransferableValue(target) as Pointer, + ]; + ReflectApply(ArrayProtoPush, args, ownKeys); + Iif (unforgeableGlobalThisKeys?.length) { + // Use `LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL` to delimit + // `ownKeys` and `unforgeableGlobalThisKeys`. + args[args.length] = LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + ReflectApply(ArrayProtoPush, args, unforgeableGlobalThisKeys); + } + ReflectApply(this.redCallableInstallLazyPropertyDescriptors, undefined, args); + } + } + + link(...keys: PropertyKey[]) { + let bluePointer = this.blueGlobalThisPointer; + let redPointer = this.redGlobalThisPointer; + for (let i = 0, { length } = keys; i < length; i += 1) { + const key = keys[i]; + bluePointer = this.blueCallableGetPropertyValuePointer(bluePointer, key); + redPointer = this.redCallableGetPropertyValuePointer(redPointer, key); + this.redCallableLinkPointers(redPointer, bluePointer); + this.blueCallableLinkPointers(bluePointer, redPointer); + } + } + + remapProperties(target: ProxyTarget, unsafeBlueDescs: PropertyDescriptorMap) { + Eif ((typeof target === 'object' && target !== null) || typeof target === 'function') { + const targetPointer = this.blueGetTransferableValue(target) as Pointer; + const ownKeys = ReflectOwnKeys(unsafeBlueDescs); + const { length } = ownKeys; + const args = new ArrayCtor(1 + length * 7) as Parameters<CallableDefineProperties>; + args[0] = targetPointer; + for (let i = 0, j = 1; i < length; i += 1, j += 7) { + const ownKey = ownKeys[i]; + const unsafeBlueDesc = (unsafeBlueDescs as any)[ownKey]; + // Avoid poisoning by only installing own properties from unsafeBlueDescs. + // We don't use a toSafeDescriptor() style helper since that mutates + // the unsafeBlueDesc. + // eslint-disable-next-line prefer-object-spread + const safeBlueDesc = ObjectAssign({ __proto__: null }, unsafeBlueDesc); + args[j] = ownKey; + args[j + 1] = + 'configurable' in safeBlueDesc + ? !!safeBlueDesc.configurable + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 2] = + 'enumerable' in safeBlueDesc + ? !!safeBlueDesc.enumerable + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 3] = + 'writable' in safeBlueDesc + ? !!safeBlueDesc.writable + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 4] = + 'value' in safeBlueDesc + ? this.blueGetTransferableValue(safeBlueDesc.value) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 5] = + 'get' in safeBlueDesc + ? (this.blueGetTransferableValue(safeBlueDesc.get) as Pointer) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + args[j + 6] = + 'set' in safeBlueDesc + ? (this.blueGetTransferableValue(safeBlueDesc.set) as Pointer) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + } + ReflectApply(this.redCallableDefineProperties, this, args); + } + } + + remapProto(target: ProxyTarget, proto: object | null) { + if ((typeof target === 'object' && target !== null) || typeof target === 'function') { + const foreignTargetPointer = this.blueGetTransferableValue(target) as Pointer; + const transferableProto = proto + ? (this.blueGetTransferableValue(proto) as Pointer) + : proto; + this.redCallableSetPrototypeOf(foreignTargetPointer, transferableProto); + } + } + + trackAsFastTarget(target: ProxyTarget) { + if ((typeof target === 'object' && target !== null) || typeof target === 'function') { + this.redCallableTrackAsFastTarget(this.blueGetTransferableValue(target) as Pointer); + } + } +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
connector.ts | +
+
+ |
+ 71.43% | +5/7 | +66.67% | +4/6 | +100% | +2/2 | +71.43% | +5/7 | +
environment.ts | +
+
+ |
+ 85.42% | +82/96 | +38.64% | +17/44 | +72.22% | +13/18 | +84.27% | +75/89 | +
index.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +
intrinsics.ts | +
+
+ |
+ 97.62% | +41/42 | +66.67% | +10/15 | +100% | +6/6 | +97.22% | +35/36 | +
membrane.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
types.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 | + + + + + | export * from './connector'; +export * from './environment'; +export * from './intrinsics'; +export * from './membrane'; +export * from './types'; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +29x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +29x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +29x + + +29x + + + + +4x + + + + + + + + + + + + + + + + + +29x +29x + + + +29x + + + +29x + + +29x + + + + + +15x + +15x +15x +22x + + + +22x +22x +22x + + + + +22x + + + +15x + + + +14x +14x +14x + +14x +14x +3432x + + + +3432x +2844x + + +14x + + + + +23x +322x +322x +322x + +322x +253x + +69x + + + + + | import { + ArrayProtoIncludes, + ObjectAssign, + ObjectHasOwn, + ReflectApply, + ReflectOwnKeys, + toSafeArray, +} from '@locker/near-membrane-shared'; +import { VirtualEnvironment } from './environment'; + +/** + * This list must be in sync with ecma-262, anything new added to the global object + * should be considered, to decide whether or not they need remapping. The default + * behavior, if missing form the following list, is to be remapped, which is safer. + * + * Note: remapped means the functionality is provided by the blue realm, rather than + * the red one. This helps with the identity discontinuity issue, e.g.: all Set objects + * have the same identity because it is always derived from the outer realm's Set. + * + * Note 1: We have identified 3 types of intrinsics + * A: primitives driven intrinsics + * B: syntax driven intrinsics (they usually have a imperative form as well) + * C: imperative only intrinsics + * + * While A is not remapped, it is safe, and works fast that way, and C is remapped to + * preserve the identity of all produced objects from the same realm, B is really + * problematic, and requires a lot more work to guarantee that objects from both sides + * can be considered equivalents (without identity discontinuity). + */ +function getESGlobalKeys(maxPerfMode: boolean) { + const ESGlobalKeys = [ + // *** 19.1 Value Properties of the Global Object + 'globalThis', + 'Infinity', + 'NaN', + 'undefined', + + // *** 19.2 Function Properties of the Global Object + // 'eval', // dangerous & Reflective + 'isFinite', + 'isNaN', + 'parseFloat', + 'parseInt', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent', + + // *** 19.3 Constructor Properties of the Global Object + // 'AggregateError', // Reflective + // 'Array', // Reflective + 'BigInt', + 'Boolean', + // 'Date', // Remapped + // 'Error', // Reflective + // 'EvalError', // Reflective + 'FinalizationRegistry', + // 'Function', // dangerous & Reflective + 'Map', + 'Number', + // 'Object', // Reflective + // Allow blue `Promise` constructor to overwrite the Red one so that promises + // created by the `Promise` constructor or APIs like `fetch` will work. + // 'Promise', // Remapped + // 'Proxy', // Reflective + // 'RangeError', // Reflective + // 'ReferenceError', // Reflective + 'RegExp', + 'Set', + + 'String', + 'Symbol', + // 'SyntaxError', // Reflective + // 'TypeError', // Reflective + // 'URIError', // Reflective + 'WeakMap', + 'WeakSet', + 'WeakRef', + + // *** 18.4 Other Properties of the Global Object + // 'Atomics', // Remapped + 'JSON', + 'Math', + 'Reflect', + + // *** Annex B + 'escape', + 'unescape', + + // *** ECMA-402 + // 'Intl', // Remapped + ]; + + // This set is for maxPerfMode, all of these must be from the same global object + const maxPerfModeKeys = { + intrinsics: [ + 'ArrayBuffer', + 'Atomics', + 'BigInt64Array', + 'BigUint64Array', + 'DataView', + 'Float32Array', + 'Float64Array', + 'Int16Array', + 'Int32Array', + 'Int8Array', + 'SharedArrayBuffer', + 'Uint16Array', + 'Uint32Array', + 'Uint8Array', + 'Uint8ClampedArray', + ], + // Ideally these should come from browser-realm, that's a code reorg improvement for later + browser: [ + 'Blob', + // 'createImageBitmap', + 'crypto', + 'Crypto', + 'fetch', + 'File', + 'FileReader', + 'FileReaderSync', + // 'ImageData', + 'Request', + 'Response', + 'SubtleCrypto', + 'TextDecoder', + 'TextEncoder', + 'URL', + 'XMLHttpRequest', + ], + }; + + Iif (maxPerfMode) { + ESGlobalKeys.push(...maxPerfModeKeys.intrinsics, ...maxPerfModeKeys.browser); + } + return ESGlobalKeys; +} + +// These are foundational things that should never be wrapped but are equivalent +// @TODO: Revisit this list. +const ReflectiveIntrinsicObjectNames = [ + 'AggregateError', + 'Array', + 'Error', + 'EvalError', + 'Function', + 'Object', + 'Proxy', + 'RangeError', + 'ReferenceError', + 'SyntaxError', + 'TypeError', + 'URIError', + 'eval', + 'globalThis', +]; + +function getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode: boolean) { + const ESGlobalKeys = getESGlobalKeys(maxPerfMode); + return toSafeArray([...ESGlobalKeys, ...ReflectiveIntrinsicObjectNames]); +} + +function getGlobalObjectOwnKeys(source: object): PropertyKey[] { + const ownKeys = ReflectOwnKeys(source); + // WKWebView incorrectly excludes the 'webkit' own property of the global + // object from `Object.keys()` and `Reflect.ownKeys()` results, so add it. + // istanbul ignore if: currently unreachable via tests + if (ObjectHasOwn(source, 'webkit') && !ReflectApply(ArrayProtoIncludes, ownKeys, ['webkit'])) { + ownKeys[ownKeys.length] = 'webkit'; + } + return ownKeys; +} + +export function assignFilteredGlobalDescriptorsFromPropertyDescriptorMap< + T extends PropertyDescriptorMap +>(descs: T, source: PropertyDescriptorMap, maxPerfMode: boolean): T { + const ownKeys = getGlobalObjectOwnKeys(source); + const ESGlobalsAndReflectiveIntrinsicObjectNames = + getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode); + for (let i = 0, { length } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + // Avoid overriding ECMAScript global names that correspond to + // global intrinsics. This guarantee that those entries will be + // ignored if present in the source property descriptor map. + Eif (!ESGlobalsAndReflectiveIntrinsicObjectNames.includes(ownKey as any)) { + const unsafeDesc = (source as any)[ownKey]; + Eif (unsafeDesc) { + // Avoid poisoning by only installing own properties from + // unsafeDesc. We don't use a toSafeDescriptor() style helper + // since that mutates the unsafeBlueDesc. + // eslint-disable-next-line prefer-object-spread + (descs as any)[ownKey] = ObjectAssign({ __proto__: null }, unsafeDesc); + } + } + } + return descs; +} + +export function getFilteredGlobalOwnKeys(source: object, maxPerfMode: boolean): PropertyKey[] { + const result: PropertyKey[] = []; + let resultOffset = 0; + const ownKeys = getGlobalObjectOwnKeys(source); + const ESGlobalsAndReflectiveIntrinsicObjectNames = + getESGlobalsAndReflectiveIntrinsicObjectNames(maxPerfMode); + for (let i = 0, { length } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + // Avoid overriding ECMAScript global names that correspond to global + // intrinsics. This guarantees that those entries will be ignored if + // present in the source object. + if (!ESGlobalsAndReflectiveIntrinsicObjectNames.includes(ownKey as any)) { + result[resultOffset++] = ownKey; + } + } + return result; +} + +export function linkIntrinsics(env: VirtualEnvironment, globalObject: typeof globalThis) { + // Remap intrinsics that are realm agnostic. + for (let i = 0, { length } = ReflectiveIntrinsicObjectNames; i < length; i += 1) { + const globalName = ReflectiveIntrinsicObjectNames[i]; + const reflectiveValue = (globalObject as any)[globalName]; + Eif (reflectiveValue) { + // Proxy.prototype is undefined. + if (reflectiveValue.prototype) { + env.link(globalName, 'prototype'); + } else { + env.link(globalName); + } + } + } +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 +3761 +3762 +3763 +3764 +3765 +3766 +3767 +3768 +3769 +3770 +3771 +3772 +3773 +3774 +3775 +3776 +3777 +3778 +3779 +3780 +3781 +3782 +3783 +3784 +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815 +3816 +3817 +3818 +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829 +3830 +3831 +3832 +3833 +3834 +3835 +3836 +3837 +3838 +3839 +3840 +3841 +3842 +3843 +3844 +3845 +3846 +3847 +3848 +3849 +3850 +3851 +3852 +3853 +3854 +3855 +3856 +3857 +3858 +3859 +3860 +3861 +3862 +3863 +3864 +3865 +3866 +3867 +3868 +3869 +3870 +3871 +3872 +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885 +3886 +3887 +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901 +3902 +3903 +3904 +3905 +3906 +3907 +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917 +3918 +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927 +3928 +3929 +3930 +3931 +3932 +3933 +3934 +3935 +3936 +3937 +3938 +3939 +3940 +3941 +3942 +3943 +3944 +3945 +3946 +3947 +3948 +3949 +3950 +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962 +3963 +3964 +3965 +3966 +3967 +3968 +3969 +3970 +3971 +3972 +3973 +3974 +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986 +3987 +3988 +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009 +4010 +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030 +4031 +4032 +4033 +4034 +4035 +4036 +4037 +4038 +4039 +4040 +4041 +4042 +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050 +4051 +4052 +4053 +4054 +4055 +4056 +4057 +4058 +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068 +4069 +4070 +4071 +4072 +4073 +4074 +4075 +4076 +4077 +4078 +4079 +4080 +4081 +4082 +4083 +4084 +4085 +4086 +4087 +4088 +4089 +4090 +4091 +4092 +4093 +4094 +4095 +4096 +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105 +4106 +4107 +4108 +4109 +4110 +4111 +4112 +4113 +4114 +4115 +4116 +4117 +4118 +4119 +4120 +4121 +4122 +4123 +4124 +4125 +4126 +4127 +4128 +4129 +4130 +4131 +4132 +4133 +4134 +4135 +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147 +4148 +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159 +4160 +4161 +4162 +4163 +4164 +4165 +4166 +4167 +4168 +4169 +4170 +4171 +4172 +4173 +4174 +4175 +4176 +4177 +4178 +4179 +4180 +4181 +4182 +4183 +4184 +4185 +4186 +4187 +4188 +4189 +4190 +4191 +4192 +4193 +4194 +4195 +4196 +4197 +4198 +4199 +4200 +4201 +4202 +4203 +4204 +4205 +4206 +4207 +4208 +4209 +4210 +4211 +4212 +4213 +4214 +4215 +4216 +4217 +4218 +4219 +4220 +4221 +4222 +4223 +4224 +4225 +4226 +4227 +4228 +4229 +4230 +4231 +4232 +4233 +4234 +4235 +4236 +4237 +4238 +4239 +4240 +4241 +4242 +4243 +4244 +4245 +4246 +4247 +4248 +4249 +4250 +4251 +4252 +4253 +4254 +4255 +4256 +4257 +4258 +4259 +4260 +4261 +4262 +4263 +4264 +4265 +4266 +4267 +4268 +4269 +4270 +4271 +4272 +4273 +4274 +4275 +4276 +4277 +4278 +4279 +4280 +4281 +4282 +4283 +4284 +4285 +4286 +4287 +4288 +4289 +4290 +4291 +4292 +4293 +4294 +4295 +4296 +4297 +4298 +4299 +4300 +4301 +4302 +4303 +4304 +4305 +4306 +4307 +4308 +4309 +4310 +4311 +4312 +4313 +4314 +4315 +4316 +4317 +4318 +4319 +4320 +4321 +4322 +4323 +4324 +4325 +4326 +4327 +4328 +4329 +4330 +4331 +4332 +4333 +4334 +4335 +4336 +4337 +4338 +4339 +4340 +4341 +4342 +4343 +4344 +4345 +4346 +4347 +4348 +4349 +4350 +4351 +4352 +4353 +4354 +4355 +4356 +4357 +4358 +4359 +4360 +4361 +4362 +4363 +4364 +4365 +4366 +4367 +4368 +4369 +4370 +4371 +4372 +4373 +4374 +4375 +4376 +4377 +4378 +4379 +4380 +4381 +4382 +4383 +4384 +4385 +4386 +4387 +4388 +4389 +4390 +4391 +4392 +4393 +4394 +4395 +4396 +4397 +4398 +4399 +4400 +4401 +4402 +4403 +4404 +4405 +4406 +4407 +4408 +4409 +4410 +4411 +4412 +4413 +4414 +4415 +4416 +4417 +4418 +4419 +4420 +4421 +4422 +4423 +4424 +4425 +4426 +4427 +4428 +4429 +4430 +4431 +4432 +4433 +4434 +4435 +4436 +4437 +4438 +4439 +4440 +4441 +4442 +4443 +4444 +4445 +4446 +4447 +4448 +4449 +4450 +4451 +4452 +4453 +4454 +4455 +4456 +4457 +4458 +4459 +4460 +4461 +4462 +4463 +4464 +4465 +4466 +4467 +4468 +4469 +4470 +4471 +4472 +4473 +4474 +4475 +4476 +4477 +4478 +4479 +4480 +4481 +4482 +4483 +4484 +4485 +4486 +4487 +4488 +4489 +4490 +4491 +4492 +4493 +4494 +4495 +4496 +4497 +4498 +4499 +4500 +4501 +4502 +4503 +4504 +4505 +4506 +4507 +4508 +4509 +4510 +4511 +4512 +4513 +4514 +4515 +4516 +4517 +4518 +4519 +4520 +4521 +4522 +4523 +4524 +4525 +4526 +4527 +4528 +4529 +4530 +4531 +4532 +4533 +4534 +4535 +4536 +4537 +4538 +4539 +4540 +4541 +4542 +4543 +4544 +4545 +4546 +4547 +4548 +4549 +4550 +4551 +4552 +4553 +4554 +4555 +4556 +4557 +4558 +4559 +4560 +4561 +4562 +4563 +4564 +4565 +4566 +4567 +4568 +4569 +4570 +4571 +4572 +4573 +4574 +4575 +4576 +4577 +4578 +4579 +4580 +4581 +4582 +4583 +4584 +4585 +4586 +4587 +4588 +4589 +4590 +4591 +4592 +4593 +4594 +4595 +4596 +4597 +4598 +4599 +4600 +4601 +4602 +4603 +4604 +4605 +4606 +4607 +4608 +4609 +4610 +4611 +4612 +4613 +4614 +4615 +4616 +4617 +4618 +4619 +4620 +4621 +4622 +4623 +4624 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +4x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | /** + * This file contains an exportable (portable) function `init()` used to initialize + * one side of a membrane on any realm. The only prerequisite is the ability to + * evaluate the sourceText of the `init()` function there. Once evaluated, the + * function will return a set of values that can be used to wire up the side of + * the membrane with another existing `init()` function from another realm, in + * which case they will exchange callable functions that are required to connect + * the two realms via the membrane. + * + * About the mechanics of the membrane, there are few important considerations: + * + * 1. Pointers are the way to pass reference to object and functions. + * 2. A dedicated symbol (LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) is needed + * to represent the absence of a value. + * 3. The realm that owns the object or function is responsible for projecting + * the proxy onto the other side (via callablePushTarget), which returns a + * Pointer that can be used by the realm to pass the reference to the same + * proxy over and over again. + * 4. The realm that owns the proxy (after the other side projects it into it) + * will hold a Pointer alongside the proxy to signal what original object or + * function should the foreign operation operates, it is always the first + * argument of the foreign callable for proxies, and the other side can use + * it via `selectedTarget!`. + */ +import { toSafeWeakMap, WeakMapCtor } from '@locker/near-membrane-shared'; +import type { Getter, ProxyTarget, Setter } from '@locker/near-membrane-shared'; +import type { + CallableApply, + CallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + CallableBatchGetPrototypeOfWhenHasNoOwnProperty, + CallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor, + CallableConstruct, + CallableDebugInfo, + CallableDefineProperties, + CallableDefineProperty, + CallableDeleteProperty, + CallableDescriptorCallback, + CallableDescriptorsCallback, + CallableEvaluate, + CallableGet, + CallableGetLazyPropertyDescriptorStateByTarget, + CallableGetOwnPropertyDescriptor, + CallableGetPropertyValue, + CallableGetPrototypeOf, + CallableGetTargetIntegrityTraits, + CallableGetToStringTagOfTarget, + CallableHas, + CallableInstallErrorPrepareStackTrace, + CallableInstallLazyPropertyDescriptors, + CallableIsExtensible, + CallableIsTargetLive, + CallableIsTargetRevoked, + CallableNonConfigurableDescriptorCallback, + CallableOwnKeys, + CallablePreventExtensions, + CallablePushErrorTarget, + CallablePushTarget, + CallableSerializeTarget, + CallableSet, + CallableSetLazyPropertyDescriptorStateByTarget, + CallableSetPrototypeOf, + CallableTrackAsFastTarget, + ForeignPropertyDescriptor, + GetSelectedTarget, + GlobalThisGetter, + HooksCallback, + HooksOptions, + Pointer, + PointerOrPrimitive, + Primitive, + SerializedValue, + ShadowTarget, +} from './types'; + +const proxyTargetToLazyPropertyDescriptorStateMap: WeakMap<ProxyTarget, object> = toSafeWeakMap( + new WeakMapCtor() +); + +// istanbul ignore next +export function createMembraneMarshall( + globalObject?: typeof globalThis | (WindowProxy & typeof globalThis) +) { + /* eslint-disable prefer-object-spread */ + const ArrayCtor = Array; + const ArrayBufferCtor = ArrayBuffer; + const ErrorCtor = Error; + const NumberCtor = Number; + const ObjectCtor = Object; + const ProxyCtor = Proxy; + const ReflectRef = Reflect; + const RegExpCtor = RegExp; + const StringCtor = String; + const SymbolCtor = Symbol; + const TypeErrorCtor = TypeError; + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + const WeakMapCtor = WeakMap; + const WeakSetCtor = WeakSet; + const { for: SymbolFor, toStringTag: SymbolToStringTag } = SymbolCtor; + const { + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + apply: ReflectApply, + construct: ReflectConstruct, + defineProperty: ReflectDefineProperty, + deleteProperty: ReflectDeleteProperty, + get: ReflectGet, + getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor, + getPrototypeOf: ReflectGetPrototypeOf, + has: ReflectHas, + isExtensible: ReflectIsExtensible, + ownKeys: ReflectOwnKeys, + preventExtensions: ReflectPreventExtensions, + set: ReflectSet, + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + setPrototypeOf: ReflectSetPrototypeOf, + } = ReflectRef; + const { + assign: ObjectAssign, + defineProperties: ObjectDefineProperties, + freeze: ObjectFreeze, + getOwnPropertyDescriptor: ObjectGetOwnPropertyDescriptor, + getOwnPropertyDescriptors: ObjectGetOwnPropertyDescriptors, + isFrozen: ObjectIsFrozen, + isSealed: ObjectIsSealed, + keys: ObjectKeys, + prototype: ObjectProto, + seal: ObjectSeal, + } = ObjectCtor; + const { + hasOwnProperty: ObjectProtoHasOwnProperty, + propertyIsEnumerable: ObjectProtoPropertyIsEnumerable, + toString: ObjectProtoToString, + } = ObjectProto; + const { hasOwn: OriginalObjectHasOwn } = ObjectCtor as any; + const { + __defineGetter__: ObjectProtoDefineGetter, + __defineSetter__: ObjectProtoDefineSetter, + __lookupGetter__: ObjectProtoLookupGetter, + __lookupSetter__: ObjectProtoLookupSetter, + } = ObjectProto as any; + const ObjectHasOwn = + typeof OriginalObjectHasOwn === 'function' + ? (OriginalObjectHasOwn as (object: any, key: PropertyKey) => boolean) + : (object: any, key: PropertyKey): boolean => + ReflectApply(ObjectProtoHasOwnProperty, object, [key]); + const globalThisRef = + globalObject ?? + // Support for globalThis was added in Chrome 71. + // https://caniuse.com/mdn-javascript_builtins_globalthisfor + (typeof globalThis !== 'undefined' ? globalThis : undefined) ?? + // However, environments like Android emulators are running Chrome 69. + // eslint-disable-next-line no-restricted-globals + (typeof self !== 'undefined' ? self : undefined) ?? + // See https://mathiasbynens.be/notes/globalthis for more details. + (ReflectDefineProperty(ObjectProto, 'globalThis', { + __proto__: null, + configurable: true, + get() { + ReflectDeleteProperty(ObjectProto, 'globalThis'); + // Safari 12 on iOS 12.1 has a `this` of `undefined` so we + // fallback to `self`. + // eslint-disable-next-line no-restricted-globals + return this ?? self; + }, + } as PropertyDescriptor), + globalThis); + // @rollup/plugin-replace replaces `DEV_MODE` references. + const DEV_MODE = true; + const IS_IN_SHADOW_REALM = typeof globalObject !== 'object' || globalObject === null; + const IS_NOT_IN_SHADOW_REALM = !IS_IN_SHADOW_REALM; + const LOCKER_DEBUG_MODE_SYMBOL = IS_NOT_IN_SHADOW_REALM + ? SymbolFor('@@lockerDebugMode') + : undefined; + const LOCKER_IDENTIFIER_MARKER = '$LWS'; + const LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL = IS_NOT_IN_SHADOW_REALM + ? SymbolFor('@@lockerNearMembraneSerializedValue') + : undefined; + const LOCKER_NEAR_MEMBRANE_SYMBOL = IS_NOT_IN_SHADOW_REALM + ? SymbolFor('@@lockerNearMembrane') + : undefined; + const LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL = SymbolFor( + '@@lockerNearMembraneUndefinedValue' + ); + // The default stack trace limit in Chrome is 10. + // Set to 20 to account for stack trace filtering. + const LOCKER_STACK_TRACE_LIMIT = 20; + // This package is bundled by third-parties that have their own build time + // replacement logic. Instead of customizing each build system to be aware + // of this package we implement a two phase debug mode by performing small + // runtime checks to determine phase one, our code is unminified, and + // phase two, the user opted-in to custom devtools formatters. Phase one + // is used for light weight initialization time debug while phase two is + // reserved for post initialization runtime. + + // eslint-disable-next-line @typescript-eslint/naming-convention + const LOCKER_UNMINIFIED_FLAG = `${(function LOCKER_UNMINIFIED_FLAG() { + return LOCKER_UNMINIFIED_FLAG.name; + })()}`.includes('LOCKER_UNMINIFIED_FLAG'); + // Indicate whether debug support is available. + const LOCKER_DEBUGGABLE_FLAG = LOCKER_UNMINIFIED_FLAG && IS_NOT_IN_SHADOW_REALM; + const ERR_ILLEGAL_PROPERTY_ACCESS = 'Illegal property access.'; + // BigInt is not supported in Safari 13.1. + // https://caniuse.com/bigint + const FLAGS_REG_EXP = IS_IN_SHADOW_REALM ? /\w*$/ : undefined; + // Minification safe references to the private `BoundaryProxyHandler` + // 'apply' and 'construct' trap variant's property names. + let MINIFICATION_SAFE_TRAP_PROPERTY_NAMES: string[] | undefined; + const SUPPORTS_BIG_INT = typeof BigInt === 'function'; + const { isArray: isArrayOrThrowForRevoked } = ArrayCtor; + const { + includes: ArrayProtoIncludes, + indexOf: ArrayProtoIndexOf, + slice: ArrayProtoSlice, + } = ArrayCtor.prototype; + const { isView: ArrayBufferIsView } = ArrayBufferCtor; + const BigIntProtoValueOf = SUPPORTS_BIG_INT ? BigInt.prototype.valueOf : undefined; + const { valueOf: BooleanProtoValueOf } = Boolean.prototype; + const { toString: ErrorProtoToString } = ErrorCtor.prototype; + const { bind: FunctionProtoBind, toString: FunctionProtoToString } = Function.prototype; + const { stringify: JSONStringify } = JSON; + const { isInteger: NumberIsInteger } = NumberCtor; + const { valueOf: NumberProtoValueOf } = NumberCtor.prototype; + const { revocable: ProxyRevocable } = ProxyCtor; + const { prototype: RegExpProto } = RegExpCtor; + const { + exec: RegExpProtoExec, + test: RegExpProtoTest, + toString: RegExProtoToString, + } = RegExpProto; + // Edge 15 does not support RegExp.prototype.flags. + // https://caniuse.com/mdn-javascript_builtins_regexp_flags + const RegExpProtoFlagsGetter: (() => string) | undefined = IS_IN_SHADOW_REALM + ? ReflectApply(ObjectProtoLookupGetter, RegExpProto, ['flags']) ?? + function flags(this: RegExp) { + const string = ReflectApply(RegExProtoToString, this, []); + return ReflectApply(RegExpProtoExec, FLAGS_REG_EXP!, [string])![0] as string; + } + : undefined; + const RegExpProtoSourceGetter: () => string = ReflectApply( + ObjectProtoLookupGetter, + RegExpProto, + ['source'] + ); + const { + replace: StringProtoReplace, + slice: StringProtoSlice, + valueOf: StringProtoValueOf, + } = StringCtor.prototype; + const { toString: SymbolProtoToString, valueOf: SymbolProtoValueOf } = SymbolCtor.prototype; + const BigInt64ArrayProto = globalThisRef.BigInt64Array?.prototype; + const BigUint64ArrayProto = globalThisRef.BigUint64Array?.prototype; + const { prototype: Float32ArrayProto } = Float32Array; + const { prototype: Float64ArrayProto } = Float64Array; + const { prototype: Int8ArrayProto } = Int8Array; + const { prototype: Int16ArrayProto } = Int16Array; + const { prototype: Int32ArrayProto } = Int32Array; + const { prototype: Uint8ArrayProto } = Uint8Array; + const { prototype: Uint16ArrayProto } = Uint16Array; + const { prototype: Uint32ArrayProto } = Uint32Array; + // eslint-disable-next-line no-proto + const TypedArrayProto = (Uint8ArrayProto as any).__proto__; + const TypedArrayProtoLengthGetter: () => number = ReflectApply( + ObjectProtoLookupGetter, + TypedArrayProto, + ['length'] + ); + const { prototype: WeakMapProto } = WeakMapCtor; + const { + delete: WeakMapProtoDelete, + has: WeakMapProtoHas, + set: WeakMapProtoSet, + [SymbolToStringTag]: WeakMapProtoSymbolToStringTag, + } = WeakMapProto as any; + const { prototype: WeakSetProto } = WeakSetCtor; + const { + add: WeakSetProtoAdd, + has: WeakSetProtoHas, + delete: WeakSetProtoDelete, + [SymbolToStringTag]: WeakSetProtoSymbolToStringTag, + } = WeakSetProto as any; + const consoleObject = + IS_NOT_IN_SHADOW_REALM && typeof console === 'object' && console !== null + ? console + : undefined; + const consoleInfo = consoleObject?.info; + const localEval = IS_IN_SHADOW_REALM ? eval : undefined; + + // Install flags to ensure things are installed once per realm. + let installedErrorPrepareStackTraceFlag = false; + let installedPropertyDescriptorMethodWrappersFlag = false; + + // eslint-disable-next-line no-shadow + const enum PreventExtensionsResult { + None, + Extensible = 1 << 0, + False = 1 << 1, + True = 1 << 2, + } + // eslint-disable-next-line no-shadow + const enum ProxyHandlerTraps { + None, + Apply = 1 << 0, + Construct = 1 << 1, + DefineProperty = 1 << 2, + DeleteProperty = 1 << 3, + Get = 1 << 4, + GetOwnPropertyDescriptor = 1 << 5, + GetPrototypeOf = 1 << 6, + Has = 1 << 7, + IsExtensible = 1 << 8, + OwnKeys = 1 << 9, + PreventExtensions = 1 << 10, + Set = 1 << 11, + SetPrototypeOf = 1 << 12, + } + // eslint-disable-next-line no-shadow + const enum TargetIntegrityTraits { + None, + IsNotExtensible = 1 << 0, + IsSealed = 1 << 1, + IsFrozen = 1 << 2, + Revoked = 1 << 3, + } + // eslint-disable-next-line no-shadow + const enum TargetTraits { + None, + IsArray = 1 << 0, + IsArrayBufferView = 1 << 1, + IsFunction = 1 << 2, + IsArrowFunction = 1 << 3, + IsObject = 1 << 4, + IsTypedArray = 1 << 5, + Revoked = 1 << 6, + } + + function alwaysFalse() { + return false; + } + + const installErrorPrepareStackTrace = LOCKER_UNMINIFIED_FLAG + ? () => { + if (installedErrorPrepareStackTraceFlag) { + return; + } + installedErrorPrepareStackTraceFlag = true; + // Feature detect the V8 stack trace API. + // https://v8.dev/docs/stack-trace-api + const CallSite = ((): Function | undefined => { + try { + ErrorCtor.prepareStackTrace = (_error: Error, callSites: NodeJS.CallSite[]) => + callSites; + const callSites = new ErrorCtor().stack as string | NodeJS.CallSite[]; + ReflectDeleteProperty(ErrorCtor, 'prepareStackTrace'); + return isArrayOrThrowForRevoked(callSites) && callSites.length > 0 + ? callSites[0]?.constructor + : undefined; + // eslint-disable-next-line no-empty + } catch {} + return undefined; + })(); + if (typeof CallSite !== 'function') { + return; + } + const { + getEvalOrigin: CallSiteProtoGetEvalOrigin, + getFunctionName: CallSiteProtoGetFunctionName, + toString: CallSiteProtoToString, + } = CallSite.prototype; + // A regexp to detect call sites containing LOCKER_IDENTIFIER_MARKER. + const lockerFunctionNameMarkerRegExp = new RegExpCtor( + `${ + // Escape regexp special characters in LOCKER_IDENTIFIER_MARKER. + ReflectApply(StringProtoReplace, LOCKER_IDENTIFIER_MARKER, [ + /[\\^$.*+?()[\]{}|]/g, + '\\$&', + ]) as string + // Function name references in call sites also contain + // the name of the class they belong to, + // e.g. myClassName.myFunctionName. + }(?=\\.|$)` + ); + const formatStackTrace = function formatStackTrace( + error: Error, + callSites: NodeJS.CallSite[] + ): string { + // Based on V8's default stack trace formatting: + // https://chromium.googlesource.com/v8/v8.git/+/refs/heads/main/src/execution/messages.cc#371 + let stackTrace = ''; + try { + stackTrace = ReflectApply(ErrorProtoToString, error, []) as string; + } catch { + stackTrace = '<error>'; + } + let consecutive = false; + for (let i = 0, { length } = callSites; i < length; i += 1) { + const callSite = callSites[i]; + const funcName: string | undefined = ReflectApply( + CallSiteProtoGetFunctionName, + callSite, + [] + ); + let isMarked = false; + if ( + typeof funcName === 'string' && + funcName !== 'eval' && + (ReflectApply(RegExpProtoTest, lockerFunctionNameMarkerRegExp, [ + funcName, + ]) as boolean) + ) { + isMarked = true; + } + if (!isMarked) { + const evalOrigin: string | undefined = ReflectApply( + CallSiteProtoGetEvalOrigin, + callSite, + [] + ); + if ( + typeof evalOrigin === 'string' && + (ReflectApply(RegExpProtoTest, lockerFunctionNameMarkerRegExp, [ + evalOrigin, + ]) as boolean) + ) { + isMarked = true; + } + } + // Only write a single LWS entry per consecutive LWS stacks. + if (isMarked) { + if (!consecutive) { + consecutive = true; + stackTrace += '\n at LWS'; + } + continue; + } else { + consecutive = false; + } + try { + stackTrace += `\n at ${ + ReflectApply(CallSiteProtoToString, callSite, []) as string + }`; + // eslint-disable-next-line no-empty + } catch {} + } + return stackTrace; + }; + try { + // Error.prepareStackTrace cannot be a bound or proxy wrapped + // function, so to obscure its source we wrap the call to + // formatStackTrace(). + ErrorCtor.prepareStackTrace = function prepareStackTrace( + error: Error, + callSites: NodeJS.CallSite[] + ) { + return formatStackTrace(error, callSites); + }; + // eslint-disable-next-line no-empty + } catch {} + try { + const { stackTraceLimit } = ErrorCtor; + if ( + typeof stackTraceLimit !== 'number' || + stackTraceLimit < LOCKER_STACK_TRACE_LIMIT + ) { + ErrorCtor.stackTraceLimit = LOCKER_STACK_TRACE_LIMIT; + } + // eslint-disable-next-line no-empty + } catch {} + } + : (noop as CallableInstallErrorPrepareStackTrace); + + function noop() { + // No-operation. + } + + const serializeBigIntObject = IS_IN_SHADOW_REALM + ? (bigIntObject: BigInt): bigint => + // Section 21.2.3 Properties of the BigInt Prototype Object + // https://tc39.es/ecma262/#thisbigintvalue + // Step 2: If Type(value) is Object and value has a [[BigIntData]] internal slot, then + // a. Assert: Type(value.[[BigIntData]]) is BigInt. + ReflectApply(BigIntProtoValueOf!, bigIntObject, []) + : (noop as () => undefined); + + const serializeBooleanObject = IS_IN_SHADOW_REALM + ? (booleanObject: Boolean): boolean => + // Section 20.3.3 Properties of the Boolean Prototype Object + // https://tc39.es/ecma262/#thisbooleanvalue + // Step 2: If Type(value) is Object and value has a [[BooleanData]] internal slot, then + // a. Let b be value.[[BooleanData]]. + // b. Assert: Type(b) is Boolean. + ReflectApply(BooleanProtoValueOf, booleanObject, []) + : (noop as () => undefined); + + const serializeNumberObject = IS_IN_SHADOW_REALM + ? (numberObject: Number): number => + // 21.1.3 Properties of the Number Prototype Object + // https://tc39.es/ecma262/#thisnumbervalue + // Step 2: If Type(value) is Object and value has a [[NumberData]] internal slot, then + // a. Let n be value.[[NumberData]]. + // b. Assert: Type(n) is Number. + ReflectApply(NumberProtoValueOf, numberObject, []) + : (noop as () => undefined); + + const serializeRegExp = IS_IN_SHADOW_REALM + ? (value: any): string | undefined => { + // 22.2.5.12 get RegExp.prototype.source + // https://tc39.es/ecma262/#sec-get-regexp.prototype.source + // Step 3: If R does not have an [[OriginalSource]] internal slot, then + // a. If SameValue(R, %RegExp.prototype%) is true, return "(?:)". + // b. Otherwise, throw a TypeError exception. + if (value !== RegExpProto) { + const source: string = ReflectApply(RegExpProtoSourceGetter, value, []); + return JSONStringify({ + __proto__: null, + flags: ReflectApply(RegExpProtoFlagsGetter!, value, []) as string, + source, + }); + } + return undefined; + } + : (noop as () => undefined); + + const serializeStringObject = IS_IN_SHADOW_REALM + ? (stringObject: String): string => + // 22.1.3 Properties of the String Prototype Object + // https://tc39.es/ecma262/#thisstringvalue + // Step 2: If Type(value) is Object and value has a [[StringData]] internal slot, then + // a. Let s be value.[[StringData]]. + // b. Assert: Type(s) is String. + ReflectApply(StringProtoValueOf, stringObject, []) + : (noop as () => undefined); + + const serializeSymbolObject = IS_IN_SHADOW_REALM + ? (symbolObject: Symbol): symbol => + // 20.4.3 Properties of the Symbol Prototype Object + // https://tc39.es/ecma262/#thissymbolvalue + // Step 2: If Type(value) is Object and value has a [[SymbolData]] internal slot, then + // a. Let s be value.[[SymbolData]]. + // b. Assert: Type(s) is Symbol. + ReflectApply(SymbolProtoValueOf, symbolObject, []) + : (noop as () => undefined); + + const serializeTargetByBrand = IS_IN_SHADOW_REALM + ? (target: ProxyTarget): SerializedValue | undefined => { + const brand: string = ReflectApply(ObjectProtoToString, target, []); + switch (brand) { + // The brand checks below represent boxed primitives of + // `ESGlobalKeys` in packages/near-membrane-base/src/intrinsics.ts + // which are not remapped or reflective. + case '[object Boolean]': + return serializeBooleanObject(target as any); + case '[object Number]': + return serializeNumberObject(target as any); + case '[object RegExp]': + return serializeRegExp(target as any); + case '[object String]': + return serializeStringObject(target as any); + case '[object Object]': + try { + // Symbol.prototype[@@toStringTag] is defined by default so + // must have been removed. + // https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag + return serializeSymbolObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + if (SUPPORTS_BIG_INT) { + // BigInt.prototype[@@toStringTag] is defined by default so + // must have been removed. + // https://tc39.es/ecma262/#sec-bigint.prototype-@@tostringtag + try { + return serializeBigIntObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + } + // eslint-disable-next-line no-fallthrough + default: + return undefined; + } + } + : (noop as () => undefined); + + const serializeTargetByTrialAndError = IS_IN_SHADOW_REALM + ? (target: ProxyTarget): SerializedValue | undefined => { + // The serialization attempts below represent boxed primitives of + // `ESGlobalKeys` in packages/near-membrane-base/src/intrinsics.ts + // which are not remapped or reflective. + try { + // Symbol.prototype[@@toStringTag] is defined by default so + // attempted before others. + // https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag + return serializeSymbolObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + if (SUPPORTS_BIG_INT) { + // BigInt.prototype[@@toStringTag] is defined by default so + // attempted before others. + // https://tc39.es/ecma262/#sec-bigint.prototype-@@tostringtag + try { + return serializeBigIntObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + } + try { + return serializeBooleanObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + try { + return serializeNumberObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + try { + return serializeRegExp(target as any); + // eslint-disable-next-line no-empty + } catch {} + try { + return serializeStringObject(target as any); + // eslint-disable-next-line no-empty + } catch {} + return undefined; + } + : (noop as () => undefined); + + function toSafeTemplateStringValue(value: any): string { + if (typeof value === 'string') { + return value; + } + try { + if (typeof value === 'object' && value !== null) { + const result: string = ReflectApply(ObjectProtoToString, value, []); + return result === '[object Symbol]' + ? ReflectApply(SymbolProtoToString, value, []) + : result; + } + if (typeof value === 'function') { + return ReflectApply(FunctionProtoToString, value, []); + } + // Attempt to coerce `value` to a string with the String() constructor. + // Section 22.1.1.1 String ( value ) + // https://tc39.es/ecma262/#sec-string-constructor-string-value + return StringCtor(value); + // eslint-disable-next-line no-empty + } catch {} + return '[Object Unknown]'; + } + + // eslint-disable-next-line @typescript-eslint/no-shadow, no-shadow + function toSafeWeakMap<T extends WeakMap<any, any>>(weakMap: T): T { + ReflectSetPrototypeOf(weakMap, null); + weakMap.delete = WeakMapProtoDelete; + weakMap.has = WeakMapProtoHas; + weakMap.set = WeakMapProtoSet; + (weakMap as any)[SymbolToStringTag] = WeakMapProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakMap, WeakMapProto); + return weakMap; + } + + function toSafeWeakSet<T extends WeakSet<any>>(weakSet: T): T { + ReflectSetPrototypeOf(weakSet, null); + weakSet.add = WeakSetProtoAdd; + weakSet.delete = WeakSetProtoDelete; + weakSet.has = WeakSetProtoHas; + (weakSet as any)[SymbolToStringTag] = WeakSetProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakSet, WeakSetProto); + return weakSet; + } + + return function createHooksCallback( + color: string, + foreignCallableHooksCallback: HooksCallback, + options?: HooksOptions + ): HooksCallback { + if (IS_IN_SHADOW_REALM) { + options = undefined; + } + const { + distortionCallback, + liveTargetCallback, + revokedProxyCallback, + // eslint-disable-next-line prefer-object-spread + } = ObjectAssign({ __proto__: null }, options); + + const applyTrapNameRegistry = { + // Populated in the returned connector function below. + __proto__: null, + 0: undefined, + 1: undefined, + 2: undefined, + 3: undefined, + 4: undefined, + n: undefined, + } as unknown as Record<number | string, string>; + + const constructTrapNameRegistry = { + // Populated in the returned connector function below. + __proto__: null, + 0: undefined, + 1: undefined, + 2: undefined, + 3: undefined, + 4: undefined, + n: undefined, + } as unknown as Record<number | string, string>; + + const lazyPropertyDescriptorStateCache = toSafeWeakMap( + new WeakMapCtor<ProxyTarget, object>() + ); + + const proxyPointerCache = toSafeWeakMap(new WeakMapCtor<ProxyTarget, Pointer>()); + + let foreignCallablePushErrorTarget: CallablePushErrorTarget; + let foreignCallablePushTarget: CallablePushTarget; + let foreignCallableApply: CallableApply; + let foreignCallableConstruct: CallableConstruct; + let foreignCallableDefineProperty: CallableDefineProperty; + let foreignCallableDeleteProperty: CallableDeleteProperty; + let foreignCallableGet: CallableGet; + let foreignCallableGetOwnPropertyDescriptor: CallableGetOwnPropertyDescriptor; + let foreignCallableGetPrototypeOf: CallableGetPrototypeOf; + let foreignCallableHas: CallableHas; + let foreignCallableIsExtensible: CallableIsExtensible; + let foreignCallableOwnKeys: CallableOwnKeys; + let foreignCallablePreventExtensions: CallablePreventExtensions; + let foreignCallableSet: CallableSet; + let foreignCallableSetPrototypeOf: CallableSetPrototypeOf; + let foreignCallableDebugInfo: CallableDebugInfo; + let foreignCallableGetPropertyValue: CallableGetPropertyValue; + let foreignCallableGetLazyPropertyDescriptorStateByTarget: CallableGetLazyPropertyDescriptorStateByTarget; + let foreignCallableGetTargetIntegrityTraits: CallableGetTargetIntegrityTraits; + let foreignCallableGetToStringTagOfTarget: CallableGetToStringTagOfTarget; + let foreignCallableInstallErrorPrepareStackTrace: CallableInstallErrorPrepareStackTrace; + let foreignCallableIsTargetLive: CallableIsTargetLive; + let foreignCallableIsTargetRevoked: CallableIsTargetRevoked; + let foreignCallableSerializeTarget: CallableSerializeTarget; + let foreignCallableSetLazyPropertyDescriptorStateByTarget: CallableSetLazyPropertyDescriptorStateByTarget; + let foreignCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors: CallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors; + let foreignCallableBatchGetPrototypeOfWhenHasNoOwnProperty: CallableBatchGetPrototypeOfWhenHasNoOwnProperty; + let foreignCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor: CallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor; + + let fastForeignTargetPointers: WeakSet<Pointer>; + let foreignPointerBigInt64ArrayProto: Pointer; + let foreignPointerBigUint64ArrayProto: Pointer; + let foreignPointerFloat32ArrayProto: Pointer; + let foreignPointerFloat64ArrayProto: Pointer; + let foreignPointerInt8ArrayProto: Pointer; + let foreignPointerInt16ArrayProto: Pointer; + let foreignPointerInt32ArrayProto: Pointer; + let foreignPointerObjectProto: Pointer; + let foreignPointerTypedArrayProto: Pointer; + let foreignPointerUint8ArrayProto: Pointer; + let foreignPointerUint16ArrayProto: Pointer; + let foreignPointerUint32ArrayProto: Pointer; + let selectedTarget: undefined | ProxyTarget; + + let lastProxyTrapCalled = ProxyHandlerTraps.None; + let handshakePropertyFlag = false; + let useFastForeignTargetPath = IS_IN_SHADOW_REALM; + let useFastForeignTargetPathForTypedArrays = IS_IN_SHADOW_REALM; + + const activateLazyOwnPropertyDefinition = IS_IN_SHADOW_REALM + ? (target: object, key: PropertyKey, state: object) => { + (state as any)[key] = false; + const foreignTargetPointer = getTransferablePointer(target); + let safeDesc; + try { + foreignCallableGetOwnPropertyDescriptor( + foreignTargetPointer, + key, + ( + _key, + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ) => { + safeDesc = createDescriptorFromMeta( + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ); + } + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (safeDesc) { + ReflectDefineProperty(target, key, safeDesc); + } else { + ReflectDeleteProperty(target, key); + } + } + : noop; + + let checkDebugMode = LOCKER_DEBUGGABLE_FLAG + ? () => { + try { + if (ObjectHasOwn(globalThisRef, LOCKER_DEBUG_MODE_SYMBOL!)) { + checkDebugMode = () => true; + installErrorPrepareStackTrace(); + foreignCallableInstallErrorPrepareStackTrace(); + } + } catch { + checkDebugMode = alwaysFalse; + } + return false; + } + : alwaysFalse; + + const clearFastForeignTargetPointers = IS_IN_SHADOW_REALM + ? () => { + fastForeignTargetPointers = toSafeWeakSet(new WeakSetCtor<Pointer>()); + } + : noop; + + function copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget( + foreignTargetPointer: Pointer, + shadowTarget: ShadowTarget + ): void { + let protoPointerOrNull; + try { + protoPointerOrNull = foreignCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors( + foreignTargetPointer, + (...descriptorTuples) => { + const descriptors: PropertyDescriptorMap = {}; + for (let i = 0, { length } = descriptorTuples; i < length; i += 7) { + const key = descriptorTuples[i] as PropertyKey; + (descriptors as any)[key] = createDescriptorFromMeta( + descriptorTuples[i + 1] as boolean | symbol, // configurable + descriptorTuples[i + 2] as boolean | symbol, // enumerable + descriptorTuples[i + 3] as boolean | symbol, // writable + descriptorTuples[i + 4] as PointerOrPrimitive, // valuePointer + descriptorTuples[i + 5] as PointerOrPrimitive, // getterPointer + descriptorTuples[i + 6] as PointerOrPrimitive // setterPointer + ); + } + // Use `ObjectDefineProperties()` instead of individual + // `ReflectDefineProperty()` calls for better performance. + ObjectDefineProperties(shadowTarget, descriptors); + } + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let proto: any; + if (typeof protoPointerOrNull === 'function') { + protoPointerOrNull(); + proto = selectedTarget; + selectedTarget = undefined; + } else { + proto = null; + } + ReflectSetPrototypeOf(shadowTarget, proto); + } + + function createApplyOrConstructTrapForZeroOrMoreArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap + ? applyTrapNameRegistry + : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + if (length !== 0) { + return (this as any)[ + arityToApplyOrConstructTrapNameRegistry[length] ?? + arityToApplyOrConstructTrapNameRegistry.n + ](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableApplyOrConstruct( + foreignTargetPointer, + // Inline getTransferableValue(). + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createApplyOrConstructTrapForOneOrMoreArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap + ? applyTrapNameRegistry + : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrapForOneOrMoreArgs( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + if (length !== 1) { + return (this as any)[ + arityToApplyOrConstructTrapNameRegistry[length] ?? + arityToApplyOrConstructTrapNameRegistry.n + ](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive: PointerOrPrimitive; + try { + const { 0: arg0 } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct( + foreignTargetPointer, + // Inline getTransferableValue(). + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget, + // Inline getTransferableValue(). + (typeof arg0 === 'object' && arg0 !== null) || typeof arg0 === 'function' + ? getTransferablePointer(arg0) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' + ? undefined + : arg0 + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createApplyOrConstructTrapForTwoOrMoreArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap + ? applyTrapNameRegistry + : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + if (length !== 2) { + return (this as any)[ + arityToApplyOrConstructTrapNameRegistry[length] ?? + arityToApplyOrConstructTrapNameRegistry.n + ](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive: PointerOrPrimitive; + try { + const { 0: arg0, 1: arg1 } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct( + foreignTargetPointer, + // Inline getTransferableValue(). + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget, + // Inline getTransferableValue(). + (typeof arg0 === 'object' && arg0 !== null) || typeof arg0 === 'function' + ? getTransferablePointer(arg0) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' + ? undefined + : arg0, + // Inline getTransferableValue(). + (typeof arg1 === 'object' && arg1 !== null) || typeof arg1 === 'function' + ? getTransferablePointer(arg1) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' + ? undefined + : arg1 + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createApplyOrConstructTrapForThreeOrMoreArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap + ? applyTrapNameRegistry + : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + if (length !== 3) { + return (this as any)[ + arityToApplyOrConstructTrapNameRegistry[length] ?? + arityToApplyOrConstructTrapNameRegistry.n + ](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive: PointerOrPrimitive; + try { + const { 0: arg0, 1: arg1, 2: arg2 } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct( + foreignTargetPointer, + // Inline getTransferableValue(). + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget, + // Inline getTransferableValue(). + (typeof arg0 === 'object' && arg0 !== null) || typeof arg0 === 'function' + ? getTransferablePointer(arg0) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' + ? undefined + : arg0, + // Inline getTransferableValue(). + (typeof arg1 === 'object' && arg1 !== null) || typeof arg1 === 'function' + ? getTransferablePointer(arg1) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' + ? undefined + : arg1, + // Inline getTransferableValue(). + (typeof arg2 === 'object' && arg2 !== null) || typeof arg2 === 'function' + ? getTransferablePointer(arg2) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg2 === 'undefined' + ? undefined + : arg2 + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createApplyOrConstructTrapForFourOrMoreArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap + ? applyTrapNameRegistry + : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + if (length !== 4) { + return (this as any)[ + arityToApplyOrConstructTrapNameRegistry[length] ?? + arityToApplyOrConstructTrapNameRegistry.n + ](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive: PointerOrPrimitive; + try { + const { 0: arg0, 1: arg1, 2: arg2, 3: arg3 } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct( + foreignTargetPointer, + // Inline getTransferableValue(). + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget, + // Inline getTransferableValue(). + (typeof arg0 === 'object' && arg0 !== null) || typeof arg0 === 'function' + ? getTransferablePointer(arg0) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' + ? undefined + : arg0, + // Inline getTransferableValue(). + (typeof arg1 === 'object' && arg1 !== null) || typeof arg1 === 'function' + ? getTransferablePointer(arg1) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' + ? undefined + : arg1, + // Inline getTransferableValue(). + (typeof arg2 === 'object' && arg2 !== null) || typeof arg2 === 'function' + ? getTransferablePointer(arg2) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg2 === 'undefined' + ? undefined + : arg2, + // Inline getTransferableValue(). + (typeof arg3 === 'object' && arg3 !== null) || typeof arg3 === 'function' + ? getTransferablePointer(arg3) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg3 === 'undefined' + ? undefined + : arg3 + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createApplyOrConstructTrapForFiveOrMoreArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const arityToApplyOrConstructTrapNameRegistry = isApplyTrap + ? applyTrapNameRegistry + : constructTrapNameRegistry; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrapForTwoOrMoreArgs( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + if (length !== 5) { + return (this as any)[ + arityToApplyOrConstructTrapNameRegistry[length] ?? + arityToApplyOrConstructTrapNameRegistry.n + ](_shadowTarget, thisArgOrArgs, argsOrNewTarget); + } + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let pointerOrPrimitive: PointerOrPrimitive; + try { + const { 0: arg0, 1: arg1, 2: arg2, 3: arg3, 4: arg4 } = args; + pointerOrPrimitive = foreignCallableApplyOrConstruct( + foreignTargetPointer, + // Inline getTransferableValue(). + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget, + // Inline getTransferableValue(). + (typeof arg0 === 'object' && arg0 !== null) || typeof arg0 === 'function' + ? getTransferablePointer(arg0) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg0 === 'undefined' + ? undefined + : arg0, + // Inline getTransferableValue(). + (typeof arg1 === 'object' && arg1 !== null) || typeof arg1 === 'function' + ? getTransferablePointer(arg1) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg1 === 'undefined' + ? undefined + : arg1, + // Inline getTransferableValue(). + (typeof arg2 === 'object' && arg2 !== null) || typeof arg2 === 'function' + ? getTransferablePointer(arg2) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg2 === 'undefined' + ? undefined + : arg2, + // Inline getTransferableValue(). + (typeof arg3 === 'object' && arg3 !== null) || typeof arg3 === 'function' + ? getTransferablePointer(arg3) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg3 === 'undefined' + ? undefined + : arg3, + // Inline getTransferableValue(). + (typeof arg4 === 'object' && arg4 !== null) || typeof arg4 === 'function' + ? getTransferablePointer(arg4) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg4 === 'undefined' + ? undefined + : arg4 + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createApplyOrConstructTrapForAnyNumberOfArgs(proxyTrapEnum: ProxyHandlerTraps) { + const isApplyTrap = proxyTrapEnum & ProxyHandlerTraps.Apply; + const foreignCallableApplyOrConstruct = isApplyTrap + ? foreignCallableApply + : foreignCallableConstruct; + return function applyOrConstructTrapForAnyNumberOfArgs( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + thisArgOrArgs: any, + argsOrNewTarget: any + ) { + lastProxyTrapCalled = proxyTrapEnum; + + // @ts-ignore: Prevent private property access error. + const { foreignTargetPointer } = this; + const args = isApplyTrap ? argsOrNewTarget : thisArgOrArgs; + const { length } = args; + const thisArgOrNewTarget = isApplyTrap ? thisArgOrArgs : argsOrNewTarget; + let combinedOffset = 2; + const combinedArgs = new ArrayCtor(length + combinedOffset); + combinedArgs[0] = foreignTargetPointer; + let pointerOrPrimitive: PointerOrPrimitive; + try { + combinedArgs[1] = + (typeof thisArgOrNewTarget === 'object' && thisArgOrNewTarget !== null) || + typeof thisArgOrNewTarget === 'function' + ? getTransferablePointer(thisArgOrNewTarget) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof thisArgOrNewTarget === 'undefined' + ? undefined + : thisArgOrNewTarget; + for (let i = 0; i < length; i += 1) { + const arg = args[i]; + // Inlining `getTransferableValue()`. + combinedArgs[combinedOffset++] = + (typeof arg === 'object' && arg !== null) || typeof arg === 'function' + ? getTransferablePointer(arg) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof arg === 'undefined' + ? undefined + : arg; + } + pointerOrPrimitive = ReflectApply( + foreignCallableApplyOrConstruct, + undefined, + combinedArgs + ) as PointerOrPrimitive; + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + return result; + }; + } + + function createDescriptorFromMeta( + configurable: boolean | symbol, + enumerable: boolean | symbol, + writable: boolean | symbol, + valuePointerOrPrimitive: PointerOrPrimitive, + getterPointerOrPrimitive: PointerOrPrimitive, + setterPointerOrPrimitive: PointerOrPrimitive + ): PropertyDescriptor { + const safeDesc = { __proto__: null } as PropertyDescriptor; + if (configurable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.configurable = configurable as boolean; + } + if (enumerable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.enumerable = enumerable as boolean; + } + if (writable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.writable = writable as boolean; + } + if (getterPointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof getterPointerOrPrimitive === 'function') { + getterPointerOrPrimitive(); + safeDesc.get = selectedTarget as Getter; + selectedTarget = undefined; + } else { + safeDesc.get = undefined; + } + } + if (setterPointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof setterPointerOrPrimitive === 'function') { + setterPointerOrPrimitive(); + safeDesc.set = selectedTarget as Setter; + selectedTarget = undefined; + } else { + safeDesc.set = undefined; + } + } + if (valuePointerOrPrimitive !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + if (typeof valuePointerOrPrimitive === 'function') { + valuePointerOrPrimitive(); + safeDesc.value = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.value = valuePointerOrPrimitive; + } + } + return safeDesc; + } + + function createPointer(originalTarget: ProxyTarget | undefined): () => void { + const pointer = (): void => { + // assert: selectedTarget is undefined + selectedTarget = originalTarget; + }; + if (DEV_MODE) { + // In case debugging is needed, the following lines can help: + pointer['[[OriginalTarget]]'] = originalTarget; + pointer['[[Color]]'] = color; + } + return pointer; + } + + const disableFastForeignTargetPointers = IS_IN_SHADOW_REALM + ? () => { + useFastForeignTargetPath = false; + useFastForeignTargetPathForTypedArrays = false; + clearFastForeignTargetPointers(); + } + : noop; + + const getLazyPropertyDescriptorStateByTarget = IS_IN_SHADOW_REALM + ? (target: ProxyTarget): object | undefined => { + let state: any = lazyPropertyDescriptorStateCache.get(target); + if (state === undefined) { + const statePointerOrUndefined = + foreignCallableGetLazyPropertyDescriptorStateByTarget( + getTransferablePointer(target) + ); + if (typeof statePointerOrUndefined === 'function') { + statePointerOrUndefined(); + state = selectedTarget; + selectedTarget = undefined; + if (state) { + lazyPropertyDescriptorStateCache.set(target, state); + } + } + } + return state; + } + : noop; + + const isForeignPointerOfObjectProto = IS_IN_SHADOW_REALM + ? // eslint-disable-next-line no-return-assign + (foreignTargetPointer: Pointer): boolean => + foreignTargetPointer === + (foreignPointerObjectProto === undefined + ? (foreignPointerObjectProto = getTransferablePointer(ObjectProto)) + : foreignPointerObjectProto) + : alwaysFalse; + + const isForeignPointerOfTypedArrayProto = IS_IN_SHADOW_REALM + ? // eslint-disable-next-line no-return-assign + (foreignTargetPointer: Pointer): boolean => + foreignTargetPointer === + (foreignPointerFloat32ArrayProto === undefined + ? (foreignPointerFloat32ArrayProto = + getTransferablePointer(Float32ArrayProto)) + : foreignPointerFloat32ArrayProto) || + foreignTargetPointer === + (foreignPointerFloat64ArrayProto === undefined + ? (foreignPointerFloat64ArrayProto = + getTransferablePointer(Float64ArrayProto)) + : foreignPointerFloat64ArrayProto) || + foreignTargetPointer === + (foreignPointerInt8ArrayProto === undefined + ? (foreignPointerInt8ArrayProto = getTransferablePointer(Int8ArrayProto)) + : foreignPointerInt8ArrayProto) || + foreignTargetPointer === + (foreignPointerInt16ArrayProto === undefined + ? (foreignPointerInt16ArrayProto = + getTransferablePointer(Int16ArrayProto)) + : foreignPointerInt16ArrayProto) || + foreignTargetPointer === + (foreignPointerInt32ArrayProto === undefined + ? (foreignPointerInt32ArrayProto = + getTransferablePointer(Int32ArrayProto)) + : foreignPointerInt32ArrayProto) || + foreignTargetPointer === + (foreignPointerUint8ArrayProto === undefined + ? (foreignPointerUint8ArrayProto = + getTransferablePointer(Uint8ArrayProto)) + : foreignPointerUint8ArrayProto) || + foreignTargetPointer === + (foreignPointerUint16ArrayProto === undefined + ? (foreignPointerUint16ArrayProto = + getTransferablePointer(Uint16ArrayProto)) + : foreignPointerUint16ArrayProto) || + foreignTargetPointer === + (foreignPointerUint32ArrayProto === undefined + ? (foreignPointerUint32ArrayProto = + getTransferablePointer(Uint32ArrayProto)) + : foreignPointerUint32ArrayProto) || + foreignTargetPointer === + (foreignPointerTypedArrayProto === undefined + ? (foreignPointerTypedArrayProto = + getTransferablePointer(TypedArrayProto)) + : foreignPointerTypedArrayProto) || + foreignTargetPointer === + (foreignPointerBigInt64ArrayProto === undefined + ? (foreignPointerBigInt64ArrayProto = BigInt64ArrayProto + ? getTransferablePointer(BigInt64ArrayProto) + : noop) + : foreignPointerBigInt64ArrayProto) || + foreignTargetPointer === + (foreignPointerBigUint64ArrayProto === undefined + ? (foreignPointerBigUint64ArrayProto = BigUint64ArrayProto + ? getTransferablePointer(BigUint64ArrayProto) + : noop) + : foreignPointerBigUint64ArrayProto) + : alwaysFalse; + + function getTransferablePointer( + originalTarget: ProxyTarget, + foreignCallablePusher = foreignCallablePushTarget + ): Pointer { + let proxyPointer = proxyPointerCache.get(originalTarget); + if (proxyPointer) { + return proxyPointer; + } + let targetFunctionArity = 0; + let targetFunctionName = ''; + let targetTypedArrayLength = 0; + if (revokedProxyCallback && revokedProxyCallback(originalTarget)) { + proxyPointer = foreignCallablePusher( + createPointer(originalTarget), + TargetTraits.Revoked, + targetFunctionArity, + targetFunctionName, + targetTypedArrayLength + ); + proxyPointerCache.set(originalTarget, proxyPointer); + return proxyPointer; + } + let distortionTarget: ProxyTarget; + let targetTraits = TargetTraits.IsObject; + if (distortionCallback) { + distortionTarget = distortionCallback(originalTarget); + // If a distortion entry is found, it must be a valid proxy target. + if ( + distortionTarget !== originalTarget && + typeof distortionTarget !== typeof originalTarget + ) { + throw new TypeErrorCtor( + `Invalid distortion ${toSafeTemplateStringValue(originalTarget)}.` + ); + } + } else { + distortionTarget = originalTarget; + } + let isPossiblyRevoked = true; + if (typeof distortionTarget === 'function') { + isPossiblyRevoked = false; + targetFunctionArity = 0; + targetTraits = TargetTraits.IsFunction; + try { + // Detect arrow functions. + if (!('prototype' in distortionTarget)) { + targetTraits |= TargetTraits.IsArrowFunction; + } + const safeLengthDesc = ReflectGetOwnPropertyDescriptor( + originalTarget, + 'length' + ); + if (safeLengthDesc) { + ReflectSetPrototypeOf(safeLengthDesc, null); + const { value: safeLengthDescValue } = safeLengthDesc; + if (typeof safeLengthDescValue === 'number') { + targetFunctionArity = safeLengthDescValue; + } + } + const safeNameDesc = DEV_MODE + ? ReflectGetOwnPropertyDescriptor(originalTarget, 'name') + : undefined; + if (safeNameDesc) { + ReflectSetPrototypeOf(safeNameDesc, null); + const { value: safeNameDescValue } = safeNameDesc; + if (typeof safeNameDescValue === 'string') { + targetFunctionName = safeNameDescValue; + } + } + } catch { + isPossiblyRevoked = true; + } + } else if (ArrayBufferIsView(distortionTarget)) { + isPossiblyRevoked = false; + targetTraits = TargetTraits.IsArrayBufferView; + try { + targetTypedArrayLength = ReflectApply( + TypedArrayProtoLengthGetter, + distortionTarget, + [] + ) as number; + targetTraits |= TargetTraits.IsTypedArray; + // eslint-disable-next-line no-empty + } catch { + // Could be a DataView object or a revoked proxy. + isPossiblyRevoked = true; + } + } + if (isPossiblyRevoked) { + try { + if (isArrayOrThrowForRevoked(distortionTarget)) { + targetTraits = TargetTraits.IsArray; + } + } catch { + targetTraits = TargetTraits.Revoked; + } + } + proxyPointer = foreignCallablePusher( + createPointer(distortionTarget), + targetTraits, + targetFunctionArity, + targetFunctionName, + targetTypedArrayLength + ); + proxyPointerCache.set(originalTarget, proxyPointer); + return proxyPointer; + } + + const installPropertyDescriptorMethodWrappers = IS_IN_SHADOW_REALM + ? (unforgeableGlobalThisKeys?: PropertyKey[]) => { + if (installedPropertyDescriptorMethodWrappersFlag) { + return; + } + installedPropertyDescriptorMethodWrappersFlag = true; + // We wrap property descriptor methods to activate lazy + // descriptors and/or workaround browser bugs. The following + // methods are wrapped: + // Object.getOwnPropertyDescriptors() + // Object.getOwnPropertyDescriptor() + // Reflect.defineProperty() + // Reflect.getOwnPropertyDescriptor() + // Object.prototype.__defineGetter__() + // Object.prototype.__defineSetter__() + // Object.prototype.__lookupGetter__() + // Object.prototype.__lookupSetter__() + // + // Chromium based browsers have a bug that nulls the result + // of `window` getters in detached iframes when the property + // descriptor of `window.window` is retrieved. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1305302 + // + // Methods may be poisoned when they interact with the `window` + // object and retrieve property descriptors, like 'window', + // that contain the `window` object itself. The following + // built-in methods are susceptible to this issue: + // console.log(window); + // Object.getOwnPropertyDescriptors(window); + // Object.getOwnPropertyDescriptor(window, 'window'); + // Reflect.getOwnPropertyDescriptor(window, 'window'); + // window.__lookupGetter__('window'); + // window.__lookupSetter__('window'); + // + // We side step issues with `console` by mapping it to the + // primary realm's `console`. Since we're already wrapping + // property descriptor methods to activate lazy descriptors + // we use the wrapper to workaround the `window` getter + // nulling bug. + const shouldFixChromeBug = + isArrayOrThrowForRevoked(unforgeableGlobalThisKeys) && + unforgeableGlobalThisKeys.length > 0; + + // Lazily populated by `getUnforgeableGlobalThisGetter()`; + const keyToGlobalThisGetterRegistry = shouldFixChromeBug + ? ({ __proto__: null } as unknown as Record<PropertyKey, GlobalThisGetter>) + : undefined; + + const getFixedDescriptor = shouldFixChromeBug + ? (target: any, key: PropertyKey): PropertyDescriptor | undefined => + ReflectApply(ArrayProtoIncludes, unforgeableGlobalThisKeys, [key]) + ? { + configurable: false, + enumerable: ReflectApply( + ObjectProtoPropertyIsEnumerable, + target, + [key] + ), + // eslint-disable-next-line @typescript-eslint/no-use-before-define + get: getUnforgeableGlobalThisGetter!(key), + set: undefined, + } + : ReflectGetOwnPropertyDescriptor(target, key) + : undefined; + + const getUnforgeableGlobalThisGetter = shouldFixChromeBug + ? (key: PropertyKey): GlobalThisGetter => { + let globalThisGetter: GlobalThisGetter | undefined = + keyToGlobalThisGetterRegistry![key]; + if (globalThisGetter === undefined) { + // We can't access the original getter to mask + // with `proxyMaskFunction()`, so instead we wrap + // `unboundGlobalThisGetter` in bound function + // to obscure the getter source as "[native code]". + globalThisGetter = ReflectApply( + FunctionProtoBind, + // eslint-disable-next-line @typescript-eslint/no-use-before-define + unboundGlobalThisGetter, + [] + ) as GlobalThisGetter; + // Preserve identity continuity of getters. + keyToGlobalThisGetterRegistry![key] = globalThisGetter; + } + return globalThisGetter; + } + : undefined; + + const lookupFixedGetter = shouldFixChromeBug + ? (target: any, key: PropertyKey): Getter | undefined => + ReflectApply(ArrayProtoIncludes, unforgeableGlobalThisKeys, [key]) + ? getUnforgeableGlobalThisGetter!(key) + : ReflectApply(ObjectProtoLookupGetter, target, [key]) + : undefined; + + const lookupFixedSetter = shouldFixChromeBug + ? (target: any, key: PropertyKey): Setter | undefined => + ReflectApply(ArrayProtoIncludes, unforgeableGlobalThisKeys, [key]) + ? undefined + : ReflectApply(ObjectProtoLookupSetter, target, [key]) + : undefined; + + const unboundGlobalThisGetter = shouldFixChromeBug + ? ((() => globalThisRef) as GlobalThisGetter) + : undefined; + + const wrapDefineAccessOrProperty = (originalFunc: Function) => { + const { length: originalFuncLength } = originalFunc; + // `__defineGetter__()` and `__defineSetter__()` have + // function lengths of 2 while `Reflect.defineProperty()` + // has a function length of 3. + const useThisArgAsTarget = originalFuncLength === 2; + return new ProxyCtor(originalFunc, { + apply(_originalFunc: Function, thisArg: any, args: any[]) { + if (args.length >= originalFuncLength) { + const target = useThisArgAsTarget ? thisArg : args[0]; + if ( + (typeof target === 'object' && target !== null) || + typeof target === 'function' + ) { + const key = useThisArgAsTarget ? args[0] : args[1]; + const state = getLazyPropertyDescriptorStateByTarget(target); + if ((state as any)?.[key]) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + target[key]; + } + } + } + return ReflectApply(originalFunc, thisArg, args); + }, + }); + }; + + const wrapLookupAccessor = ( + originalFunc: typeof ObjectProtoLookupGetter, + lookupFixedAccessor?: typeof lookupFixedGetter | typeof lookupFixedSetter + ) => + new ProxyCtor(originalFunc, { + apply(_originalFunc: Function, thisArg: any, args: [key: PropertyKey]) { + if ( + args.length && + ((typeof thisArg === 'object' && thisArg !== null) || + typeof thisArg === 'function') + ) { + const { 0: key } = args; + const state = getLazyPropertyDescriptorStateByTarget(thisArg); + if ((state as any)?.[key]) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + thisArg[key]; + } + if (shouldFixChromeBug && thisArg === globalThisRef) { + return lookupFixedAccessor!(thisArg, key); + } + } + return ReflectApply(originalFunc, thisArg, args); + }, + }) as typeof Reflect.getOwnPropertyDescriptor; + + const wrapGetOwnPropertyDescriptor = ( + originalFunc: typeof Reflect.getOwnPropertyDescriptor + ) => + new ProxyCtor(originalFunc, { + apply( + _originalFunc: Function, + thisArg: any, + args: [target: object, key: PropertyKey] + ) { + if (args.length > 1) { + const { 0: target, 1: key } = args; + if ( + (typeof target === 'object' && target !== null) || + typeof target === 'function' + ) { + const state = getLazyPropertyDescriptorStateByTarget(target); + if ((state as any)?.[key]) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + (target as any)[key]; + } + if (shouldFixChromeBug && target === globalThisRef) { + return getFixedDescriptor!(target, key); + } + } + } + return ReflectApply(originalFunc, thisArg, args); + }, + }) as typeof Reflect.getOwnPropertyDescriptor; + + const wrapGetOwnPropertyDescriptors = ( + originalFunc: typeof Object.getOwnPropertyDescriptors + ) => + new ProxyCtor(originalFunc, { + apply( + _originalFunc: Function, + thisArg: any, + args: Parameters<typeof Object.getOwnPropertyDescriptors> + ) { + const target: ProxyTarget = args.length + ? (args[0] as any) + : undefined; + if ( + !( + (typeof target === 'object' && target !== null) || + typeof target === 'function' + ) + ) { + // Defer to native method to throw exception. + return ReflectApply(originalFunc, thisArg, args); + } + const state = getLazyPropertyDescriptorStateByTarget(target); + const isFixingChromeBug = + target === globalThisRef && shouldFixChromeBug; + const unsafeDescs: PropertyDescriptorMap = isFixingChromeBug + ? // Create an empty property descriptor map + // to populate with curated descriptors. + {} + : // Since this is not a global object it is + // safe to use the native method. + ReflectApply(originalFunc, thisArg, args); + if (!isFixingChromeBug && state === undefined) { + // Exit early if the target is not a global + // object and there are no lazy descriptors. + return unsafeDescs; + } + const ownKeys = ReflectOwnKeys( + isFixingChromeBug ? target : unsafeDescs + ); + for (let i = 0, { length } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + const isLazyProp = !!(state as any)?.[ownKey]; + if (isLazyProp) { + // Activate the descriptor by triggering + // its getter. + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + (target as any)[ownKey]; + } + if (isLazyProp || isFixingChromeBug) { + const unsafeDesc = isFixingChromeBug + ? getFixedDescriptor!(target, ownKey) + : ReflectGetOwnPropertyDescriptor(target, ownKey); + // Update the descriptor map entry. + if (unsafeDesc) { + unsafeDescs[ownKey] = unsafeDesc; + } else if (!isFixingChromeBug) { + ReflectDeleteProperty(unsafeDescs, ownKey); + } + } + } + return unsafeDescs; + }, + }) as typeof Object.getOwnPropertyDescriptors; + try { + ReflectRef.defineProperty = wrapDefineAccessOrProperty( + ReflectDefineProperty + ) as typeof Reflect.defineProperty; + // eslint-disable-next-line no-empty + } catch {} + try { + ReflectRef.getOwnPropertyDescriptor = wrapGetOwnPropertyDescriptor( + ReflectGetOwnPropertyDescriptor + ); + // eslint-disable-next-line no-empty + } catch {} + try { + ObjectCtor.getOwnPropertyDescriptor = wrapGetOwnPropertyDescriptor( + ObjectGetOwnPropertyDescriptor + ); + // eslint-disable-next-line no-empty + } catch {} + try { + ObjectCtor.getOwnPropertyDescriptors = wrapGetOwnPropertyDescriptors( + ObjectGetOwnPropertyDescriptors + ); + // eslint-disable-next-line no-empty + } catch {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-restricted-properties, no-underscore-dangle + (ObjectProto as any).__defineGetter__ = + wrapDefineAccessOrProperty(ObjectProtoDefineGetter); + // eslint-disable-next-line no-empty + } catch {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-restricted-properties, no-underscore-dangle + (ObjectProto as any).__defineSetter__ = + wrapDefineAccessOrProperty(ObjectProtoDefineSetter); + // eslint-disable-next-line no-empty + } catch {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle + (ObjectProto as any).__lookupGetter__ = wrapLookupAccessor( + ObjectProtoLookupGetter, + lookupFixedGetter + ); + // eslint-disable-next-line no-empty + } catch {} + try { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle + (ObjectProto as any).__lookupSetter__ = wrapLookupAccessor( + ObjectProtoLookupSetter, + lookupFixedSetter + ); + // eslint-disable-next-line no-empty + } catch {} + } + : noop; + + function lookupForeignDescriptor( + foreignTargetPointer: Pointer, + shadowTarget: ShadowTarget, + key: PropertyKey + ): ForeignPropertyDescriptor | undefined { + let protoPointerOrNull; + let safeDesc: ForeignPropertyDescriptor | undefined; + try { + protoPointerOrNull = + foreignCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor( + foreignTargetPointer, + key, + ( + _key, + configurable, + enumerable, + writable, + valuePointerOrPrimitive, + getterPointerOrPrimitive, + setterPointerOrPrimitive + ) => { + safeDesc = { + __proto__: null, + foreign: true, + } as PropertyDescriptor; + if (configurable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.configurable = configurable as boolean; + } + if (enumerable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.enumerable = enumerable as boolean; + } + if (writable !== LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL) { + safeDesc.writable = writable as boolean; + } + if ( + getterPointerOrPrimitive !== + LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ) { + if (typeof getterPointerOrPrimitive === 'function') { + getterPointerOrPrimitive(); + safeDesc.get = selectedTarget as Getter; + selectedTarget = undefined; + } else { + safeDesc.get = undefined; + } + } + if ( + setterPointerOrPrimitive !== + LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ) { + if (typeof setterPointerOrPrimitive === 'function') { + setterPointerOrPrimitive(); + safeDesc.set = selectedTarget as Setter; + selectedTarget = undefined; + } else { + safeDesc.set = undefined; + } + } + if ( + valuePointerOrPrimitive !== + LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ) { + if (typeof valuePointerOrPrimitive === 'function') { + valuePointerOrPrimitive(); + safeDesc.value = selectedTarget; + selectedTarget = undefined; + } else { + safeDesc.value = valuePointerOrPrimitive; + } + } + if (configurable === false) { + // Update the descriptor to non-configurable on + // the shadow target. + ReflectDefineProperty(shadowTarget, key, safeDesc); + } + } + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (safeDesc === undefined) { + // Avoiding calling the has trap for any proto chain operation, + // instead we implement the regular logic here in this trap. + let currentObject: any; + if (typeof protoPointerOrNull === 'function') { + protoPointerOrNull(); + currentObject = selectedTarget; + selectedTarget = undefined; + } else { + currentObject = null; + } + while (currentObject) { + safeDesc = ReflectGetOwnPropertyDescriptor(currentObject, key); + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + break; + } + currentObject = ReflectGetPrototypeOf(currentObject); + } + if (safeDesc) { + const { get: getter, set: setter, value: localValue } = safeDesc; + const possibleProxy = getter ?? setter ?? localValue; + safeDesc.foreign = + ((typeof possibleProxy === 'object' && possibleProxy !== null) || + typeof possibleProxy === 'function') && + proxyPointerCache.get(possibleProxy) !== undefined; + } + } + return safeDesc; + } + + function passthruForeignTraversedSet( + foreignTargetPointer: Pointer, + shadowTarget: ShadowTarget, + key: PropertyKey, + value: any, + receiver: any + ): boolean { + const safeDesc = lookupForeignDescriptor(foreignTargetPointer, shadowTarget, key); + // Following the specification steps for + // OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ). + // https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor + if (safeDesc) { + if ('get' in safeDesc || 'set' in safeDesc) { + const { set: setter } = safeDesc; + if (setter) { + if (safeDesc.foreign) { + foreignCallableApply( + getTransferablePointer(setter), + // Inline getTransferableValue(). + (typeof receiver === 'object' && receiver !== null) || + typeof receiver === 'function' + ? getTransferablePointer(receiver) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof receiver === 'undefined' + ? undefined + : receiver, + // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' + ? undefined + : value + ); + } else { + // Even though the setter function exists, we can't + // use `ReflectSet()` because there might be a + // distortion for that setter function, in which + // case we must resolve the local setter and call + // it instead. + ReflectApply(setter, receiver, [value]); + } + // If there is a setter, it either throw or we can assume + // the value was set. + return true; + } + return false; + } + if (safeDesc.writable === false) { + return false; + } + } + // Exit early if receiver is not object like. + if ( + !( + (typeof receiver === 'object' && receiver !== null) || + typeof receiver === 'function' + ) + ) { + return false; + } + const safeReceiverDesc = ReflectGetOwnPropertyDescriptor(receiver, key); + if (safeReceiverDesc) { + ReflectSetPrototypeOf(safeReceiverDesc, null); + // Exit early for accessor descriptors or non-writable data + // descriptors. + if ( + 'get' in safeReceiverDesc || + 'set' in safeReceiverDesc || + safeReceiverDesc.writable === false + ) { + return false; + } + // Setting the descriptor with only a value entry should not + // affect existing descriptor traits. + ReflectDefineProperty(receiver, key, { + __proto__: null, + value, + } as PropertyDescriptor); + return true; + } + // `ReflectDefineProperty()` and `ReflectSet()` both are expected + // to return `false` when attempting to add a new property if the + // receiver is not extensible. + return ReflectDefineProperty(receiver, key, { + __proto__: null, + configurable: true, + enumerable: true, + value, + writable: true, + } as PropertyDescriptor); + } + + function pushErrorAcrossBoundary(error: any): any { + if (LOCKER_DEBUGGABLE_FLAG) { + checkDebugMode(); + } + // Inline getTransferableValue(). + if ((typeof error === 'object' && error !== null) || typeof error === 'function') { + const foreignErrorPointer = getTransferablePointer( + error, + foreignCallablePushErrorTarget + ); + foreignErrorPointer(); + } + return error; + } + + function pushTarget( + foreignTargetPointer: () => void, + foreignTargetTraits: TargetTraits, + foreignTargetFunctionArity: number, + foreignTargetFunctionName: string, + foreignTargetTypedArrayLength: number + ): Pointer { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + const { proxy } = new BoundaryProxyHandler( + foreignTargetPointer, + foreignTargetTraits, + foreignTargetFunctionArity, + foreignTargetFunctionName, + foreignTargetTypedArrayLength + ); + proxyPointerCache.set(proxy, foreignTargetPointer); + return createPointer(proxy); + } + + const setLazyPropertyDescriptorStateByTarget = IS_IN_SHADOW_REALM + ? (target: ProxyTarget, state: object) => { + lazyPropertyDescriptorStateCache.set(target, state); + foreignCallableSetLazyPropertyDescriptorStateByTarget( + getTransferablePointer(target), + getTransferablePointer(state) + ); + } + : noop; + + class BoundaryProxyHandler implements ProxyHandler<ShadowTarget> { + // public fields + apply: ProxyHandler<ShadowTarget>['apply'] | undefined; + + construct: ProxyHandler<ShadowTarget>['construct'] | undefined; + + defineProperty: ProxyHandler<ShadowTarget>['defineProperty']; + + deleteProperty: ProxyHandler<ShadowTarget>['deleteProperty']; + + get: ProxyHandler<ShadowTarget>['get']; + + getOwnPropertyDescriptor: ProxyHandler<ShadowTarget>['getOwnPropertyDescriptor']; + + getPrototypeOf: ProxyHandler<ShadowTarget>['getPrototypeOf']; + + has: ProxyHandler<ShadowTarget>['has']; + + isExtensible: ProxyHandler<ShadowTarget>['isExtensible']; + + ownKeys: ProxyHandler<ShadowTarget>['ownKeys']; + + preventExtensions: ProxyHandler<ShadowTarget>['preventExtensions']; + + revoke: () => void; + + set: ProxyHandler<ShadowTarget>['set']; + + setPrototypeOf: ProxyHandler<ShadowTarget>['setPrototypeOf']; + + private serialize: () => Primitive; + + private staticToStringTag: string; + + // The membrane color help developers identify which side of the + // membrane they are debugging. + // @ts-ignore: Prevent 'has no initializer and is not definitely assigned in the constructor' error. + private readonly color: string; + + private readonly foreignTargetPointer: Pointer; + + private readonly foreignTargetTraits: TargetTraits; + + private readonly foreignTargetTypedArrayLength: number; + + private readonly nonConfigurableDescriptorCallback: CallableNonConfigurableDescriptorCallback; + + readonly proxy: ShadowTarget; + + private readonly shadowTarget: ProxyTarget; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForZeroOrMoreArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForOneOrMoreArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForTwoOrMoreArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForThreeOrMoreArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForFourOrMoreArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForFiveOrMoreArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly applyTrapForAnyNumberOfArgs: ProxyHandler<ShadowTarget>['apply']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForZeroOrMoreArgs: ProxyHandler<ShadowTarget>['construct']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForOneOrMoreArgs: ProxyHandler<ShadowTarget>['construct']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForTwoOrMoreArgs: ProxyHandler<ShadowTarget>['construct']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForThreeOrMoreArgs: ProxyHandler<ShadowTarget>['construct']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForFourOrMoreArgs: ProxyHandler<ShadowTarget>['construct']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForFiveOrMoreArgs: ProxyHandler<ShadowTarget>['construct']; + + // @ts-ignore: Prevent 'is declared but its value is never read' error. + private readonly constructTrapForAnyNumberOfArgs: ProxyHandler<ShadowTarget>['construct']; + + constructor( + foreignTargetPointer: Pointer, + foreignTargetTraits: TargetTraits, + foreignTargetFunctionArity: number, + foreignTargetFunctionName: string, + foreignTargetTypedArrayLength: number + ) { + let shadowTarget: ShadowTarget; + const isForeignTargetArray = foreignTargetTraits & TargetTraits.IsArray; + const isForeignTargetFunction = foreignTargetTraits & TargetTraits.IsFunction; + if (isForeignTargetFunction) { + // This shadow target is never invoked. It's needed to avoid + // proxy trap invariants. Because it's not invoked the code + // does not need to be instrumented for code coverage. + // + // istanbul ignore next + shadowTarget = + foreignTargetTraits & TargetTraits.IsArrowFunction + ? () => {} + : function () {}; + if (DEV_MODE && foreignTargetFunctionName.length) { + // This is only really needed for debugging, + // it helps to identify the proxy by name + ReflectDefineProperty(shadowTarget, 'name', { + __proto__: null, + value: foreignTargetFunctionName, + } as PropertyDescriptor); + } + } else if (isForeignTargetArray) { + shadowTarget = []; + } else { + shadowTarget = {}; + } + const { proxy, revoke } = ProxyRevocable(shadowTarget, this); + this.foreignTargetPointer = foreignTargetPointer; + this.foreignTargetTraits = foreignTargetTraits; + this.foreignTargetTypedArrayLength = foreignTargetTypedArrayLength; + // Define in the BoundaryProxyHandler constructor so it is bound + // to the BoundaryProxyHandler instance. + this.nonConfigurableDescriptorCallback = ( + key, + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ) => { + // Update the descriptor to non-configurable on the shadow + // target. + ReflectDefineProperty( + this.shadowTarget, + key, + createDescriptorFromMeta( + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ) + ); + }; + this.proxy = proxy; + this.revoke = revoke; + this.serialize = noop; + this.shadowTarget = shadowTarget; + this.staticToStringTag = 'Object'; + // Define traps. + if (isForeignTargetFunction) { + this.apply = (this as any)[ + applyTrapNameRegistry[foreignTargetFunctionArity] ?? applyTrapNameRegistry.n + ]; + this.construct = (this as any)[ + constructTrapNameRegistry[foreignTargetFunctionArity] ?? + constructTrapNameRegistry.n + ]; + } + this.defineProperty = BoundaryProxyHandler.defaultDefinePropertyTrap; + this.deleteProperty = BoundaryProxyHandler.defaultDeletePropertyTrap; + this.isExtensible = BoundaryProxyHandler.defaultIsExtensibleTrap; + this.getOwnPropertyDescriptor = + BoundaryProxyHandler.defaultGetOwnPropertyDescriptorTrap; + this.getPrototypeOf = BoundaryProxyHandler.defaultGetPrototypeOfTrap; + this.get = + foreignTargetTraits & TargetTraits.IsTypedArray + ? BoundaryProxyHandler.hybridGetTrapForTypedArray + : BoundaryProxyHandler.defaultGetTrap; + this.has = BoundaryProxyHandler.defaultHasTrap; + this.ownKeys = BoundaryProxyHandler.defaultOwnKeysTrap; + this.preventExtensions = BoundaryProxyHandler.defaultPreventExtensionsTrap; + this.setPrototypeOf = BoundaryProxyHandler.defaultSetPrototypeOfTrap; + this.set = BoundaryProxyHandler.defaultSetTrap; + if (foreignTargetTraits & TargetTraits.Revoked) { + this.revoke(); + } else if (IS_IN_SHADOW_REALM) { + if ( + isForeignTargetArray || + foreignTargetTraits & TargetTraits.IsArrayBufferView + ) { + this.makeProxyLive(); + } + } else { + if (foreignTargetTraits & TargetTraits.IsObject) { + // Lazily define serialize method. + let cachedSerializedValue: SerializedValue | undefined | symbol = + LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + this.serialize = () => { + if ( + cachedSerializedValue === + LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ) { + cachedSerializedValue = foreignCallableSerializeTarget( + this.foreignTargetPointer + ); + } + return cachedSerializedValue; + }; + } + } + } + + // Internal red/shadow realm side utilities: + + private makeProxyLive = IS_IN_SHADOW_REALM + ? function (this: BoundaryProxyHandler): void { + // Replace pending traps with live traps that can work with the + // target without taking snapshots. + this.deleteProperty = BoundaryProxyHandler.passthruDeletePropertyTrap; + this.defineProperty = BoundaryProxyHandler.passthruDefinePropertyTrap; + this.preventExtensions = BoundaryProxyHandler.passthruPreventExtensionsTrap; + this.set = BoundaryProxyHandler.passthruSetTrap; + this.setPrototypeOf = BoundaryProxyHandler.passthruSetPrototypeOfTrap; + } + : noop; + + private makeProxyStatic = IS_IN_SHADOW_REALM + ? function (this: BoundaryProxyHandler): void { + // Reset all traps except apply and construct for static proxies + // since the proxy target is the shadow target and all operations + // are going to be applied to it rather than the real target. + this.defineProperty = BoundaryProxyHandler.staticDefinePropertyTrap; + this.deleteProperty = BoundaryProxyHandler.staticDeletePropertyTrap; + this.get = BoundaryProxyHandler.staticGetTrap; + this.getOwnPropertyDescriptor = + BoundaryProxyHandler.staticGetOwnPropertyDescriptorTrap; + this.getPrototypeOf = BoundaryProxyHandler.staticGetPrototypeOfTrap; + this.has = BoundaryProxyHandler.staticHasTrap; + this.isExtensible = BoundaryProxyHandler.staticIsExtensibleTrap; + this.ownKeys = BoundaryProxyHandler.staticOwnKeysTrap; + this.preventExtensions = BoundaryProxyHandler.staticPreventExtensionsTrap; + this.set = BoundaryProxyHandler.staticSetTrap; + this.setPrototypeOf = BoundaryProxyHandler.staticSetPrototypeOfTrap; + + const { foreignTargetPointer, foreignTargetTraits, shadowTarget } = this; + if (useFastForeignTargetPath) { + fastForeignTargetPointers!.delete(foreignTargetPointer); + } + // We don't wrap `foreignCallableGetTargetIntegrityTraits()` + // in a try-catch because it cannot throw. + const targetIntegrityTraits = + foreignCallableGetTargetIntegrityTraits(foreignTargetPointer); + if (targetIntegrityTraits & TargetIntegrityTraits.Revoked) { + // the target is a revoked proxy, in which case we revoke + // this proxy as well. + this.revoke(); + return; + } + // A proxy can revoke itself when traps are triggered and break + // the membrane, therefore we need protection. + try { + copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget( + foreignTargetPointer, + shadowTarget + ); + } catch { + // We don't wrap `foreignCallableIsTargetRevoked()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetRevoked(foreignTargetPointer)) { + this.revoke(); + return; + } + } + if ( + foreignTargetTraits & TargetTraits.IsObject && + !(SymbolToStringTag in shadowTarget) + ) { + let toStringTag = 'Object'; + try { + toStringTag = + foreignCallableGetToStringTagOfTarget(foreignTargetPointer); + // eslint-disable-next-line no-empty + } catch {} + this.staticToStringTag = toStringTag; + } + // Preserve the semantics of the target. + if (targetIntegrityTraits & TargetIntegrityTraits.IsFrozen) { + ObjectFreeze(shadowTarget); + } else { + if (targetIntegrityTraits & TargetIntegrityTraits.IsSealed) { + ObjectSeal(shadowTarget); + } else if ( + targetIntegrityTraits & TargetIntegrityTraits.IsNotExtensible + ) { + ReflectPreventExtensions(shadowTarget); + } + if (LOCKER_UNMINIFIED_FLAG) { + // We don't wrap `foreignCallableDebugInfo()` in a try-catch + // because it cannot throw. + foreignCallableDebugInfo( + 'Mutations on the membrane of an object originating ' + + 'outside of the sandbox will not be reflected on ' + + 'the object itself:', + foreignTargetPointer + ); + } + } + } + : noop; + + // Logic implementation of all traps. + + // Hybrid traps: + // (traps that operate on their shadowTarget, proxy, and foreignTargetPointer): + + private static hybridGetTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey, + receiver: any + ): ReturnType<typeof Reflect.get> { + const { foreignTargetPointer, foreignTargetTraits, proxy, shadowTarget } = + this; + let safeDesc: ForeignPropertyDescriptor | undefined; + let result: any; + if ( + useFastForeignTargetPath && + fastForeignTargetPointers!.has(foreignTargetPointer) + ) { + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGetPropertyValue( + foreignTargetPointer, + key + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + safeDesc = lookupForeignDescriptor( + foreignTargetPointer, + shadowTarget, + key + ); + if (safeDesc) { + const { get: getter, value: localValue } = safeDesc; + if (getter) { + if (safeDesc.foreign) { + const foreignGetterPointer = getTransferablePointer(getter); + const transferableReceiver = + proxy === receiver + ? foreignTargetPointer + : // Inline getTransferableValue(). + (typeof receiver === 'object' && receiver !== null) || + typeof receiver === 'function' + ? getTransferablePointer(receiver) + : receiver; + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableApply( + foreignGetterPointer, + transferableReceiver + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + // Even though the getter function exists, + // we can't use `ReflectGet()` because there + // might be a distortion for that getter function, + // in which case we must resolve the local getter + // and call it instead. + result = ReflectApply(getter, receiver, []); + } + } else { + result = localValue; + } + } else { + const transferableReceiver = + proxy === receiver + ? foreignTargetPointer + : // Inline getTransferableValue(). + (typeof receiver === 'object' && receiver !== null) || + typeof receiver === 'function' + ? getTransferablePointer(receiver) + : receiver; + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGet( + foreignTargetPointer, + foreignTargetTraits, + key, + transferableReceiver + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } + } + if ( + safeDesc === undefined && + result === undefined && + key === SymbolToStringTag && + foreignTargetTraits & TargetTraits.IsObject + ) { + let toStringTag; + try { + toStringTag = + foreignCallableGetToStringTagOfTarget(foreignTargetPointer); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + // The default language toStringTag is "Object". If we + // receive "Object" we return `undefined` to let the + // language resolve it naturally without projecting a + // value. + if (toStringTag !== 'Object') { + result = toStringTag; + } + } + return result; + } + : (noop as typeof Reflect.get); + + private static hybridGetTrapForTypedArray = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey, + receiver: any + ): ReturnType<typeof Reflect.get> { + const { + foreignTargetPointer, + foreignTargetTypedArrayLength, + proxy, + shadowTarget, + } = this; + let useFastPath = useFastForeignTargetPathForTypedArrays; + if (!useFastPath && typeof key === 'string') { + const possibleIndex = +key; + useFastPath = + possibleIndex > -1 && + possibleIndex < foreignTargetTypedArrayLength && + NumberIsInteger(possibleIndex); + } + let result: any; + if (useFastPath) { + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGetPropertyValue( + foreignTargetPointer, + key + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + const safeDesc = lookupForeignDescriptor( + foreignTargetPointer, + shadowTarget, + key + ); + if (safeDesc) { + const { get: getter, value: localValue } = safeDesc; + if (getter) { + if (safeDesc.foreign) { + const foreignGetterPointer = getTransferablePointer(getter); + const transferableReceiver = + proxy === receiver + ? foreignTargetPointer + : // Inline getTransferableValue(). + (typeof receiver === 'object' && receiver !== null) || + typeof receiver === 'function' + ? getTransferablePointer(receiver) + : receiver; + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableApply( + foreignGetterPointer, + transferableReceiver + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + } else { + // Even though the getter function exists, + // we can't use `ReflectGet()` because there + // might be a distortion for that getter function, + // in which case we must resolve the local getter + // and call it instead. + result = ReflectApply(getter, receiver, []); + } + } else { + result = localValue; + } + } + } + return result; + } + : (noop as typeof Reflect.get); + + private static hybridHasTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey + ): ReturnType<typeof Reflect.has> { + let trueOrProtoPointerOrNull; + try { + trueOrProtoPointerOrNull = + foreignCallableBatchGetPrototypeOfWhenHasNoOwnProperty( + this.foreignTargetPointer, + key + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result = false; + if (trueOrProtoPointerOrNull === true) { + result = true; + } else { + // Avoiding calling the has trap for any proto chain operation, + // instead we implement the regular logic here in this trap. + let currentObject: any; + if (typeof trueOrProtoPointerOrNull === 'function') { + trueOrProtoPointerOrNull(); + currentObject = selectedTarget; + selectedTarget = undefined; + } else { + currentObject = null; + } + while (currentObject) { + if (ObjectHasOwn(currentObject, key)) { + result = true; + break; + } + currentObject = ReflectGetPrototypeOf(currentObject); + } + } + return result; + } + : (alwaysFalse as typeof Reflect.has); + + // Passthru traps: + + private static passthruDefinePropertyTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey, + unsafePartialDesc: PropertyDescriptor + ): ReturnType<typeof Reflect.defineProperty> { + lastProxyTrapCalled = ProxyHandlerTraps.DefineProperty; + const { foreignTargetPointer, nonConfigurableDescriptorCallback } = this; + const safePartialDesc = unsafePartialDesc; + ReflectSetPrototypeOf(safePartialDesc, null); + const { get: getter, set: setter, value } = safePartialDesc; + const valuePointerOrPrimitive = + 'value' in safePartialDesc + ? // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' + ? undefined + : value + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + const getterPointerOrUndefinedSymbol = + 'get' in safePartialDesc + ? // Inline getTransferableValue(). + typeof getter === 'function' + ? getTransferablePointer(getter) + : getter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + const setterPointerOrUndefinedSymbol = + 'set' in safePartialDesc + ? // Inline getTransferableValue(). + typeof setter === 'function' + ? getTransferablePointer(setter) + : setter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + let result = false; + try { + result = foreignCallableDefineProperty( + foreignTargetPointer, + key, + 'configurable' in safePartialDesc + ? !!safePartialDesc.configurable + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'enumerable' in safePartialDesc + ? !!safePartialDesc.enumerable + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'writable' in safePartialDesc + ? !!safePartialDesc.writable + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + valuePointerOrPrimitive, + getterPointerOrUndefinedSymbol, + setterPointerOrUndefinedSymbol, + nonConfigurableDescriptorCallback + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if ( + useFastForeignTargetPath && + result && + (typeof getterPointerOrUndefinedSymbol === 'function' || + typeof setterPointerOrUndefinedSymbol === 'function') + ) { + fastForeignTargetPointers!.delete(foreignTargetPointer); + } + return result; + } + + private static passthruDeletePropertyTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey + ): ReturnType<typeof Reflect.deleteProperty> { + lastProxyTrapCalled = ProxyHandlerTraps.DeleteProperty; + let result = false; + try { + result = foreignCallableDeleteProperty(this.foreignTargetPointer, key); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + return result; + } + + private static passthruGetTrap = IS_NOT_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey, + receiver: any + ): ReturnType<typeof Reflect.get> { + // Only allow accessing handshake property values if the + // "has" trap has been triggered immediately BEFORE and + // the property does NOT exist. + handshakePropertyFlag &&= lastProxyTrapCalled === ProxyHandlerTraps.Has; + lastProxyTrapCalled = ProxyHandlerTraps.Get; + const isNearMembraneSymbol = key === LOCKER_NEAR_MEMBRANE_SYMBOL; + const isNearMembraneSerializedValueSymbol = + key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL; + if (handshakePropertyFlag) { + // Exit without performing a [[Get]] for handshake + // properties because we know that when the + // `handshakePropertyFlag` is ON that there are NO + // shadowed values. + if (isNearMembraneSymbol) { + return true; + } + if (isNearMembraneSerializedValueSymbol) { + return this.serialize(); + } + } + const { foreignTargetPointer, foreignTargetTraits, proxy } = this; + if (typeof receiver === 'undefined') { + receiver = proxy; + } + const transferableReceiver = + proxy === receiver + ? LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + : // Inline getTransferableValue(). + (typeof receiver === 'object' && receiver !== null) || + typeof receiver === 'function' + ? getTransferablePointer(receiver) + : receiver; + let pointerOrPrimitive: PointerOrPrimitive; + try { + pointerOrPrimitive = foreignCallableGet( + foreignTargetPointer, + foreignTargetTraits, + key, + transferableReceiver + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let result: any; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + result = selectedTarget; + selectedTarget = undefined; + } else { + result = pointerOrPrimitive; + } + // Getting forged values of handshake properties is not allowed. + if ( + result !== undefined && + (isNearMembraneSymbol || isNearMembraneSerializedValueSymbol) + ) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + return result; + } + : (noop as typeof Reflect.get); + + private static passthruGetPrototypeOfTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget + ): ReturnType<typeof Reflect.getPrototypeOf> { + lastProxyTrapCalled = ProxyHandlerTraps.GetPrototypeOf; + let protoPointerOrNull; + try { + protoPointerOrNull = foreignCallableGetPrototypeOf(this.foreignTargetPointer); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + let proto: any; + if (typeof protoPointerOrNull === 'function') { + protoPointerOrNull(); + proto = selectedTarget; + selectedTarget = undefined; + } else { + proto = null; + } + return proto as object | null; + } + + private static passthruHasTrap = IS_NOT_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey + ): ReturnType<typeof Reflect.has> { + lastProxyTrapCalled = ProxyHandlerTraps.Has; + let result; + try { + result = foreignCallableHas(this.foreignTargetPointer, key); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + const isNearMembraneSymbol = key === LOCKER_NEAR_MEMBRANE_SYMBOL; + const isNearMembraneSerializedValueSymbol = + key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL; + if (result) { + handshakePropertyFlag = false; + // Checking the existence of forged handshake properties + // is not allowed. + if (isNearMembraneSymbol || isNearMembraneSerializedValueSymbol) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + } else { + // The `handshakePropertyFlag` is ON if the handshake + // property does NOT exist on the object or its [[Prototype]]. + handshakePropertyFlag = + isNearMembraneSymbol || isNearMembraneSerializedValueSymbol; + } + return result; + } + : (alwaysFalse as typeof Reflect.has); + + private static passthruIsExtensibleTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget + ): ReturnType<typeof Reflect.isExtensible> { + lastProxyTrapCalled = ProxyHandlerTraps.IsExtensible; + const { shadowTarget } = this; + let result = false; + // Check if already locked. + if (ReflectIsExtensible(shadowTarget)) { + const { foreignTargetPointer } = this; + try { + result = foreignCallableIsExtensible(foreignTargetPointer); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (!result) { + copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget( + foreignTargetPointer, + shadowTarget + ); + ReflectPreventExtensions(shadowTarget); + } + } + return result; + } + + private static passthruOwnKeysTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget + ): ReturnType<typeof Reflect.ownKeys> { + lastProxyTrapCalled = ProxyHandlerTraps.OwnKeys; + let ownKeys: ReturnType<typeof Reflect.ownKeys> | undefined; + try { + foreignCallableOwnKeys(this.foreignTargetPointer, (...args) => { + ownKeys = args; + }); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + return ownKeys || []; + } + + private static passthruGetOwnPropertyDescriptorTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey + ): ReturnType<typeof Reflect.getOwnPropertyDescriptor> { + lastProxyTrapCalled = ProxyHandlerTraps.GetOwnPropertyDescriptor; + const { foreignTargetPointer, shadowTarget } = this; + let safeDesc: PropertyDescriptor | undefined; + try { + foreignCallableGetOwnPropertyDescriptor( + foreignTargetPointer, + key, + ( + _key, + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ) => { + safeDesc = createDescriptorFromMeta( + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ); + if (safeDesc.configurable === false) { + // Update the descriptor to non-configurable on + // the shadow target. + ReflectDefineProperty(shadowTarget, key, safeDesc); + } + } + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + // Getting forged descriptors of handshake properties is not allowed. + if ( + IS_NOT_IN_SHADOW_REALM && + safeDesc && + (key === LOCKER_NEAR_MEMBRANE_SYMBOL || + key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL) + ) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + return safeDesc; + } + + private static passthruPreventExtensionsTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget + ): ReturnType<typeof Reflect.preventExtensions> { + lastProxyTrapCalled = ProxyHandlerTraps.PreventExtensions; + const { foreignTargetPointer, shadowTarget } = this; + let result = true; + if (ReflectIsExtensible(shadowTarget)) { + let resultEnum = PreventExtensionsResult.None; + try { + resultEnum = foreignCallablePreventExtensions(foreignTargetPointer); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + // If the target is a proxy it might reject the + // preventExtension call, in which case we should not + // attempt to lock down the shadow target. + if (!(resultEnum & PreventExtensionsResult.Extensible)) { + copyForeignOwnPropertyDescriptorsAndPrototypeToShadowTarget( + foreignTargetPointer, + shadowTarget + ); + ReflectPreventExtensions(shadowTarget); + } + result = !(resultEnum & PreventExtensionsResult.False); + } + return result; + } + + private static passthruSetPrototypeOfTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + proto: object | null + ): ReturnType<typeof Reflect.setPrototypeOf> { + lastProxyTrapCalled = ProxyHandlerTraps.SetPrototypeOf; + const { foreignTargetPointer } = this; + const transferableProto = proto ? getTransferablePointer(proto) : proto; + let result = false; + try { + result = foreignCallableSetPrototypeOf(foreignTargetPointer, transferableProto); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + if (useFastForeignTargetPath && result) { + fastForeignTargetPointers!.delete(foreignTargetPointer); + } + return result; + } + + private static passthruSetTrap( + this: BoundaryProxyHandler, + _shadowTarget: ShadowTarget, + key: PropertyKey, + value: any, + receiver: any + ): boolean { + lastProxyTrapCalled = ProxyHandlerTraps.Set; + const { foreignTargetPointer, proxy, shadowTarget } = this; + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof value === 'undefined') { + value = undefined; + } + if (typeof receiver === 'undefined') { + receiver = proxy; + } + // Setting forged values of handshake properties is not allowed. + if ( + IS_NOT_IN_SHADOW_REALM && + (key === LOCKER_NEAR_MEMBRANE_SYMBOL || + key === LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL) + ) { + throw new TypeErrorCtor(ERR_ILLEGAL_PROPERTY_ACCESS); + } + const isFastPath = proxy === receiver; + let result = false; + try { + result = isFastPath + ? foreignCallableSet( + foreignTargetPointer, + key, + // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : value + ) + : passthruForeignTraversedSet( + foreignTargetPointer, + shadowTarget, + key, + value, + receiver + ); + } catch (error: any) { + const errorToThrow = selectedTarget ?? error; + selectedTarget = undefined; + throw errorToThrow; + } + return result; + } + + // Pending traps: + + private static pendingDefinePropertyTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + shadowTarget: ShadowTarget, + key: PropertyKey, + unsafePartialDesc: PropertyDescriptor + ): ReturnType<typeof Reflect.defineProperty> { + const { foreignTargetPointer, foreignTargetTraits } = this; + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(foreignTargetPointer, foreignTargetTraits)) { + this.makeProxyLive(); + } else { + if (useFastForeignTargetPath) { + if (isForeignPointerOfObjectProto(foreignTargetPointer)) { + disableFastForeignTargetPointers(); + } else if (isForeignPointerOfTypedArrayProto(foreignTargetPointer)) { + useFastForeignTargetPathForTypedArrays = false; + } + } + this.makeProxyStatic(); + } + return this.defineProperty!( + shadowTarget, + key as string | symbol, + unsafePartialDesc + ); + } + : (alwaysFalse as typeof Reflect.defineProperty); + + private static pendingDeletePropertyTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + shadowTarget: ShadowTarget, + key: PropertyKey + ): ReturnType<typeof Reflect.deleteProperty> { + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if ( + foreignCallableIsTargetLive( + this.foreignTargetPointer, + this.foreignTargetTraits + ) + ) { + this.makeProxyLive(); + } else { + this.makeProxyStatic(); + } + return this.deleteProperty!(shadowTarget, key as string | symbol); + } + : (alwaysFalse as typeof Reflect.deleteProperty); + + private static pendingPreventExtensionsTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + shadowTarget: ShadowTarget + ): ReturnType<typeof Reflect.preventExtensions> { + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if ( + foreignCallableIsTargetLive( + this.foreignTargetPointer, + this.foreignTargetTraits + ) + ) { + this.makeProxyLive(); + } else { + this.makeProxyStatic(); + } + return this.preventExtensions!(shadowTarget); + } + : (alwaysFalse as typeof Reflect.preventExtensions); + + private static pendingSetPrototypeOfTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + shadowTarget: ShadowTarget, + proto: object | null + ): ReturnType<typeof Reflect.setPrototypeOf> { + const { foreignTargetPointer, foreignTargetTraits } = this; + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(foreignTargetPointer, foreignTargetTraits)) { + this.makeProxyLive(); + } else { + if (useFastForeignTargetPath) { + if (isForeignPointerOfObjectProto(foreignTargetPointer)) { + disableFastForeignTargetPointers(); + } else if (isForeignPointerOfTypedArrayProto(foreignTargetPointer)) { + useFastForeignTargetPathForTypedArrays = false; + } + } + this.makeProxyStatic(); + } + return this.setPrototypeOf!(shadowTarget, proto); + } + : (alwaysFalse as typeof Reflect.setPrototypeOf); + + private static pendingSetTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + shadowTarget: ShadowTarget, + key: PropertyKey, + value: any, + receiver: any + ): ReturnType<typeof Reflect.set> { + const { foreignTargetPointer, foreignTargetTraits } = this; + // We don't wrap `foreignCallableIsTargetLive()` in a + // try-catch because it cannot throw. + if (foreignCallableIsTargetLive(foreignTargetPointer, foreignTargetTraits)) { + this.makeProxyLive(); + } else { + if (useFastForeignTargetPath) { + if (isForeignPointerOfObjectProto(foreignTargetPointer)) { + disableFastForeignTargetPointers(); + } else if (isForeignPointerOfTypedArrayProto(foreignTargetPointer)) { + useFastForeignTargetPathForTypedArrays = false; + } + } + this.makeProxyStatic(); + } + return this.set!(shadowTarget, key as string | symbol, value, receiver); + } + : (alwaysFalse as typeof Reflect.set); + + // Static traps: + + private static staticDefinePropertyTrap = IS_IN_SHADOW_REALM + ? ReflectDefineProperty + : (alwaysFalse as typeof Reflect.defineProperty); + + private static staticDeletePropertyTrap = IS_IN_SHADOW_REALM + ? ReflectDeleteProperty + : (alwaysFalse as typeof Reflect.deleteProperty); + + private static staticGetOwnPropertyDescriptorTrap = IS_IN_SHADOW_REALM + ? ReflectGetOwnPropertyDescriptor + : (noop as typeof Reflect.getOwnPropertyDescriptor); + + private static staticGetPrototypeOfTrap = IS_IN_SHADOW_REALM + ? ReflectGetPrototypeOf + : ((() => null) as typeof Reflect.getPrototypeOf); + + private static staticGetTrap = IS_IN_SHADOW_REALM + ? function ( + this: BoundaryProxyHandler, + shadowTarget: ShadowTarget, + key: PropertyKey, + receiver: any + ): ReturnType<typeof Reflect.get> { + const { foreignTargetTraits, staticToStringTag } = this; + const result = ReflectGet(shadowTarget, key, receiver); + if ( + result === undefined && + key === SymbolToStringTag && + foreignTargetTraits & TargetTraits.IsObject && + // The default language toStringTag is "Object". If we + // receive "Object" we return `undefined` to let the + // language resolve it naturally without projecting a + // value. + staticToStringTag !== 'Object' && + !(key in shadowTarget) + ) { + return staticToStringTag; + } + return result; + } + : (noop as typeof Reflect.get); + + private static staticHasTrap = IS_IN_SHADOW_REALM + ? ReflectHas + : (alwaysFalse as typeof Reflect.has); + + private static staticIsExtensibleTrap = IS_IN_SHADOW_REALM + ? ReflectIsExtensible + : (alwaysFalse as typeof Reflect.isExtensible); + + private static staticOwnKeysTrap = IS_IN_SHADOW_REALM + ? ReflectOwnKeys + : ((() => []) as typeof Reflect.ownKeys); + + private static staticPreventExtensionsTrap = IS_IN_SHADOW_REALM + ? ReflectPreventExtensions + : (alwaysFalse as typeof Reflect.preventExtensions); + + private static staticSetPrototypeOfTrap = IS_IN_SHADOW_REALM + ? ReflectSetPrototypeOf + : (alwaysFalse as typeof Reflect.setPrototypeOf); + + private static staticSetTrap = IS_IN_SHADOW_REALM + ? ReflectSet + : (alwaysFalse as typeof Reflect.set); + + // Default traps: + + // Pending traps are needed for the shadow realm side of the membrane + // to avoid leaking mutation operations on the primary realm side. + private static defaultDefinePropertyTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.pendingDefinePropertyTrap + : BoundaryProxyHandler.passthruDefinePropertyTrap; + + private static defaultDeletePropertyTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.pendingDeletePropertyTrap + : BoundaryProxyHandler.passthruDeletePropertyTrap; + + private static defaultGetOwnPropertyDescriptorTrap = + BoundaryProxyHandler.passthruGetOwnPropertyDescriptorTrap; + + private static defaultGetPrototypeOfTrap = + BoundaryProxyHandler.passthruGetPrototypeOfTrap; + + private static defaultGetTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.hybridGetTrap + : BoundaryProxyHandler.passthruGetTrap; + + private static defaultHasTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.hybridHasTrap + : BoundaryProxyHandler.passthruHasTrap; + + private static defaultIsExtensibleTrap = BoundaryProxyHandler.passthruIsExtensibleTrap; + + private static defaultOwnKeysTrap = BoundaryProxyHandler.passthruOwnKeysTrap; + + private static defaultPreventExtensionsTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.pendingPreventExtensionsTrap + : BoundaryProxyHandler.passthruPreventExtensionsTrap; + + private static defaultSetTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.pendingSetTrap + : BoundaryProxyHandler.passthruSetTrap; + + private static defaultSetPrototypeOfTrap = IS_IN_SHADOW_REALM + ? BoundaryProxyHandler.pendingSetPrototypeOfTrap + : BoundaryProxyHandler.passthruSetPrototypeOfTrap; + } + + if (IS_IN_SHADOW_REALM) { + // Initialize `fastForeignTargetPointers` weak map. + clearFastForeignTargetPointers(); + } + // Export callable hooks to a foreign realm. + foreignCallableHooksCallback( + // globalThisPointer + // When crossing, should be mapped to the foreign globalThis + createPointer(globalThisRef), + // getSelectedTarget + IS_NOT_IN_SHADOW_REALM + ? (): any => { + const result = selectedTarget; + selectedTarget = undefined; + return result; + } + : (noop as GetSelectedTarget), + // getTransferableValue + (value: any): PointerOrPrimitive => { + if ((typeof value === 'object' && value !== null) || typeof value === 'function') { + return getTransferablePointer(value); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + return typeof value === 'undefined' ? undefined : value; + }, + // callableGetPropertyValuePointer: this callable function allows + // the foreign realm to access a linkable pointer for a property value. + // In order to do that, the foreign side must provide a pointer and + // a key access the value in order to produce a pointer + (targetPointer: Pointer, key: PropertyKey) => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + const value = (target as any)?.[key]; + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + return createPointer(typeof value === 'undefined' ? undefined : value); + }, + // callableEvaluate + IS_IN_SHADOW_REALM + ? (sourceText: string): PointerOrPrimitive => { + let result: PointerOrPrimitive; + try { + result = localEval!(sourceText); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + return (typeof result === 'object' && result !== null) || + typeof result === 'function' + ? getTransferablePointer(result) + : result; + } + : (noop as CallableEvaluate), + // callableLinkPointers: this callable function allows the foreign + // realm to define a linkage between two values across the membrane. + (targetPointer: Pointer, newPointer: Pointer) => { + targetPointer(); + const target = selectedTarget; + selectedTarget = undefined; + if ( + (typeof target === 'object' && target !== null) || + typeof target === 'function' + ) { + proxyPointerCache.set(target, newPointer); + } + }, + // callablePushErrorTarget + LOCKER_DEBUGGABLE_FLAG + ? ( + foreignTargetPointer: () => void, + foreignTargetTraits: TargetTraits, + foreignTargetFunctionArity: number, + foreignTargetFunctionName: string, + foreignTargetTypedArrayLength: number + ): Pointer => { + const pointer = pushTarget( + foreignTargetPointer, + foreignTargetTraits, + foreignTargetFunctionArity, + foreignTargetFunctionName, + foreignTargetTypedArrayLength + ); + const pointerWrapper = () => { + checkDebugMode(); + return pointer(); + }; + if (DEV_MODE) { + pointerWrapper['[[OriginalTarget]]'] = (pointer as any)[ + '[[OriginalTarget]]' + ]; + pointerWrapper['[[Color]]'] = (pointer as any)['[[Color]]']; + } + return pointerWrapper; + } + : pushTarget, + // callablePushTarget: This function can be used by a foreign realm + // to install a proxy into this realm that correspond to an object + // from the foreign realm. It returns a Pointer that can be used by + // the foreign realm to pass back a reference to this realm when + // passing arguments or returning from a foreign callable invocation. + // This function is extremely important to understand the mechanics + // of this membrane. + pushTarget, + // callableApply + ( + targetPointer: Pointer, + thisArgPointerOrUndefined: PointerOrPrimitive, + ...args: PointerOrPrimitive[] + ): PointerOrPrimitive => { + targetPointer(); + const func = selectedTarget as Function; + selectedTarget = undefined; + let thisArg: ProxyTarget | undefined; + if (typeof thisArgPointerOrUndefined === 'function') { + thisArgPointerOrUndefined(); + thisArg = selectedTarget; + selectedTarget = undefined; + } + for (let i = 0, { length } = args; i < length; i += 1) { + const pointerOrPrimitive = args[i]; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + args[i] = selectedTarget; + selectedTarget = undefined; + } + } + let result: any; + try { + result = ReflectApply(func, thisArg, args); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + return (typeof result === 'object' && result !== null) || + typeof result === 'function' + ? getTransferablePointer(result) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof result === 'undefined' + ? undefined + : result; + }, + // callableConstruct + ( + targetPointer: Pointer, + newTargetPointerOrUndefined: PointerOrPrimitive, + ...args: PointerOrPrimitive[] + ): PointerOrPrimitive => { + targetPointer(); + const constructor = selectedTarget as Function; + selectedTarget = undefined; + let newTarget: Function | undefined; + if (typeof newTargetPointerOrUndefined === 'function') { + newTargetPointerOrUndefined(); + newTarget = selectedTarget as Function | undefined; + selectedTarget = undefined; + } + for (let i = 0, { length } = args; i < length; i += 1) { + const pointerOrPrimitive = args[i]; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + args[i] = selectedTarget; + selectedTarget = undefined; + } + } + let result; + try { + result = ReflectConstruct(constructor, args, newTarget); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + return (typeof result === 'object' && result !== null) || + typeof result === 'function' + ? getTransferablePointer(result) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof result === 'undefined' + ? undefined + : result; + }, + // callableDefineProperty + ( + targetPointer: Pointer, + key: PropertyKey, + configurable: boolean | symbol, + enumerable: boolean | symbol, + writable: boolean | symbol, + valuePointer: PointerOrPrimitive, + getterPointer: PointerOrPrimitive, + setterPointer: PointerOrPrimitive, + foreignCallableNonConfigurableDescriptorCallback: CallableDescriptorCallback + ): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + const safePartialDesc = createDescriptorFromMeta( + configurable, + enumerable, + writable, + valuePointer, + getterPointer, + setterPointer + ); + let result = false; + try { + result = ReflectDefineProperty(target, key, safePartialDesc); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + if (result && configurable === false) { + let safeDesc; + try { + safeDesc = ReflectGetOwnPropertyDescriptor(target, key); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + if (safeDesc.configurable === false) { + const { get: getter, set: setter, value } = safeDesc; + foreignCallableNonConfigurableDescriptorCallback( + key, + false, // configurable + 'enumerable' in safeDesc + ? (safeDesc.enumerable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'writable' in safeDesc + ? (safeDesc.writable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'value' in safeDesc + ? // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : value + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'get' in safeDesc + ? // Inline getTransferableValue(). + typeof getter === 'function' + ? getTransferablePointer(getter) + : getter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'set' in safeDesc + ? // Inline getTransferableValue(). + typeof setter === 'function' + ? getTransferablePointer(setter) + : setter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ); + } + } + } + return result; + }, + // callableDeleteProperty + (targetPointer: Pointer, key: PropertyKey): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + try { + return ReflectDeleteProperty(target, key); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableGet + ( + targetPointer: Pointer, + targetTraits: TargetTraits, + key: PropertyKey, + receiverPointerOrPrimitive: PointerOrPrimitive + ): PointerOrPrimitive => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let receiver: any; + if (typeof receiverPointerOrPrimitive === 'function') { + receiverPointerOrPrimitive(); + receiver = selectedTarget; + selectedTarget = undefined; + } else { + receiver = + receiverPointerOrPrimitive === LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ? target + : receiverPointerOrPrimitive; + } + let result; + try { + result = ReflectGet(target, key, receiver); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Inline getTransferableValue(). + if ( + (typeof result === 'object' && result !== null) || + typeof result === 'function' + ) { + return getTransferablePointer(result); + } + if ( + result === undefined && + key === SymbolToStringTag && + targetTraits & TargetTraits.IsObject + ) { + try { + if (!(key in target)) { + // Section 19.1.3.6 Object.prototype.toString() + // https://tc39.github.io/ecma262/#sec-object.prototype.tostring + const brand: string = ReflectApply(ObjectProtoToString, target, []); + // The default language toStringTag is "Object". If + // we receive "[object Object]" we return `undefined` + // to let the language resolve it naturally without + // projecting a value. + if (brand !== '[object Object]') { + result = ReflectApply(StringProtoSlice, brand, [8, -1]) as string; + } + } + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + return typeof result === 'undefined' ? undefined : result; + }, + // callableGetOwnPropertyDescriptor + ( + targetPointer: Pointer, + key: PropertyKey, + foreignCallableDescriptorCallback: CallableDescriptorCallback + ): void => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let safeDesc; + try { + safeDesc = ReflectGetOwnPropertyDescriptor(target, key); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + const { get: getter, set: setter, value } = safeDesc; + foreignCallableDescriptorCallback( + key, + 'configurable' in safeDesc + ? (safeDesc.configurable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'enumerable' in safeDesc + ? (safeDesc.enumerable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'writable' in safeDesc + ? (safeDesc.writable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'value' in safeDesc + ? // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' + ? undefined + : value + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'get' in safeDesc + ? // Inline getTransferableValue(). + typeof getter === 'function' + ? getTransferablePointer(getter) + : getter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'set' in safeDesc + ? // Inline getTransferableValue(). + typeof setter === 'function' + ? getTransferablePointer(setter) + : setter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ); + } + }, + // callableGetPrototypeOf + (targetPointer: Pointer): PointerOrPrimitive => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let proto: object | null; + try { + proto = ReflectGetPrototypeOf(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }, + // callableHas + (targetPointer: Pointer, key: PropertyKey): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + try { + return key in target; + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableIsExtensible + (targetPointer: Pointer): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + try { + return ReflectIsExtensible(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableOwnKeys + ( + targetPointer: Pointer, + foreignCallableKeysCallback: (...args: ReturnType<typeof Reflect.ownKeys>) => void + ): void => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let ownKeys; + try { + ownKeys = ReflectOwnKeys(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + ReflectApply(foreignCallableKeysCallback, undefined, ownKeys); + }, + // callablePreventExtensions + (targetPointer: Pointer): PreventExtensionsResult => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let result = PreventExtensionsResult.False; + try { + if (ReflectPreventExtensions(target)) { + result = PreventExtensionsResult.True; + } else if (ReflectIsExtensible(target)) { + result |= PreventExtensionsResult.Extensible; + } + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + return result; + }, + // callableSet + ( + targetPointer: Pointer, + key: PropertyKey, + valuePointerOrPrimitive: PointerOrPrimitive + ): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let value: any; + if (typeof valuePointerOrPrimitive === 'function') { + valuePointerOrPrimitive(); + value = selectedTarget; + selectedTarget = undefined; + } else { + value = valuePointerOrPrimitive; + } + try { + return ReflectSet(target, key, value, target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableSetPrototypeOf + (targetPointer: Pointer, protoPointerOrNull: Pointer | null = null): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let proto: object | null; + if (typeof protoPointerOrNull === 'function') { + // Instead of calling `protoPointerOrNull()` directly we use + // `ReflectApply` to avoid a Maglev (https://v8.dev/blog/maglev) + // optimizing JIT bug in Chrome >= 117: + // https://bugs.chromium.org/p/chromium/issues/detail?id=1494060 + ReflectApply(protoPointerOrNull, undefined, []); + proto = selectedTarget!; + selectedTarget = undefined; + } else { + proto = null; + } + try { + return ReflectSetPrototypeOf(target, proto); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableDebugInfo + LOCKER_DEBUGGABLE_FLAG + ? (...args: Parameters<typeof console.info>) => { + if (checkDebugMode()) { + for (let i = 0, { length } = args; i < length; i += 1) { + const pointerOrPrimitive: PointerOrPrimitive = args[i]; + if (typeof pointerOrPrimitive === 'function') { + pointerOrPrimitive(); + args[i] = selectedTarget; + selectedTarget = undefined; + } + } + try { + ReflectApply(consoleInfo!, consoleObject, args); + // eslint-disable-next-line no-empty + } catch {} + } + } + : (noop as CallableDebugInfo), + // callableDefineProperties + IS_IN_SHADOW_REALM + ? ( + targetPointer: Pointer, + ...descriptorTuples: [...Parameters<CallableDescriptorCallback>] + ): void => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + for (let i = 0, { length } = descriptorTuples; i < length; i += 7) { + // We don't use `ObjectDefineProperties()` here because it + // will throw an exception if it fails to define one of its + // properties. + ReflectDefineProperty( + target, + descriptorTuples[i] as PropertyKey, + createDescriptorFromMeta( + descriptorTuples[i + 1] as boolean | symbol, // configurable + descriptorTuples[i + 2] as boolean | symbol, // enumerable + descriptorTuples[i + 3] as boolean | symbol, // writable + descriptorTuples[i + 4] as PointerOrPrimitive, // valuePointer + descriptorTuples[i + 5] as PointerOrPrimitive, // getterPointer + descriptorTuples[i + 6] as PointerOrPrimitive // setterPointer + ) + ); + } + } + : (noop as CallableDefineProperties), + // callableGetLazyPropertyDescriptorStateByTarget + IS_NOT_IN_SHADOW_REALM + ? (targetPointer: Pointer) => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + // We don't wrap the weak map `get()` call in a try-catch + // because we know `target` is an object. + const state = proxyTargetToLazyPropertyDescriptorStateMap.get(target); + return state ? getTransferablePointer(state) : state; + } + : (noop as CallableGetLazyPropertyDescriptorStateByTarget), + // callableGetPropertyValue + IS_NOT_IN_SHADOW_REALM + ? (targetPointer: Pointer, key: PropertyKey): PointerOrPrimitive => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let value: any; + try { + value = (target as any)[key]; + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + return (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : value; + } + : (noop as unknown as CallableGetPropertyValue), + // callableGetTargetIntegrityTraits + IS_NOT_IN_SHADOW_REALM + ? (targetPointer: Pointer): TargetIntegrityTraits => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + // A target may be a proxy that is revoked or throws in its + // "isExtensible" trap. + try { + if (!ReflectIsExtensible(target)) { + if (ObjectIsFrozen(target)) { + return ( + TargetIntegrityTraits.IsFrozen & + TargetIntegrityTraits.IsSealed & + TargetIntegrityTraits.IsNotExtensible + ); + } + if (ObjectIsSealed(target)) { + return ( + TargetIntegrityTraits.IsSealed & + TargetIntegrityTraits.IsNotExtensible + ); + } + return TargetIntegrityTraits.IsNotExtensible; + } + } catch { + try { + isArrayOrThrowForRevoked(target); + } catch { + return TargetIntegrityTraits.Revoked; + } + } + return TargetIntegrityTraits.None; + } + : ((() => TargetIntegrityTraits.None) as CallableGetTargetIntegrityTraits), + // callableGetToStringTagOfTarget + (targetPointer: Pointer): string => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + try { + // Section 19.1.3.6 Object.prototype.toString() + // https://tc39.github.io/ecma262/#sec-object.prototype.tostring + const brand = ReflectApply(ObjectProtoToString, target, []); + return brand === '[object Object]' + ? 'Object' + : ReflectApply(StringProtoSlice, brand, [8, -1]); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + }, + // callableInstallErrorPrepareStackTrace + installErrorPrepareStackTrace, + // callableInstallLazyPropertyDescriptors + IS_IN_SHADOW_REALM + ? ( + targetPointer: Pointer, + ...ownKeysAndUnforgeableGlobalThisKeys: PropertyKey[] + ) => { + const sliceIndex: number = ReflectApply( + ArrayProtoIndexOf, + ownKeysAndUnforgeableGlobalThisKeys, + [LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL] + ); + let ownKeys: PropertyKey[]; + let unforgeableGlobalThisKeys: PropertyKey[] | undefined; + if (sliceIndex === -1) { + ownKeys = ownKeysAndUnforgeableGlobalThisKeys; + } else { + ownKeys = ReflectApply( + ArrayProtoSlice, + ownKeysAndUnforgeableGlobalThisKeys, + [0, sliceIndex] + ) as PropertyKey[]; + unforgeableGlobalThisKeys = ReflectApply( + ArrayProtoSlice, + ownKeysAndUnforgeableGlobalThisKeys, + [sliceIndex + 1] + ) as PropertyKey[]; + } + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let state = getLazyPropertyDescriptorStateByTarget(target); + if (state === undefined) { + state = { __proto__: null }; + setLazyPropertyDescriptorStateByTarget(target, state); + } + for (let i = 0, { length } = ownKeys; i < length; i += 1) { + const ownKey = ownKeys[i]; + (state as any)[ownKey] = true; + ReflectDefineProperty( + target, + ownKey, + // The role of this descriptor is to serve as a + // bouncer. When either a getter or a setter is + // invoked the descriptor will be replaced with + // the descriptor from the foreign side and the + // get/set operation will carry on from there. + { + __proto__: null, + // We DO explicitly set configurability in the + // off chance that the property doesn't exist. + configurable: true, + // We DON'T explicitly set enumerability to + // defer to the enumerability of the existing + // property. In the off chance the property + // doesn't exist the property will be defined + // as non-enumerable. + get(): any { + activateLazyOwnPropertyDefinition(target, ownKey, state!); + return (target as any)[ownKey]; + }, + set(value: any) { + activateLazyOwnPropertyDefinition(target, ownKey, state!); + ReflectSet(target, ownKey, value); + }, + } as PropertyDescriptor + ); + } + installPropertyDescriptorMethodWrappers(unforgeableGlobalThisKeys); + } + : (noop as CallableInstallLazyPropertyDescriptors), + // callableIsTargetLive + IS_NOT_IN_SHADOW_REALM && liveTargetCallback + ? (targetPointer: Pointer, targetTraits: TargetTraits): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + if (target !== ObjectProto && target !== RegExpProto) { + try { + return liveTargetCallback(target, targetTraits); + // eslint-disable-next-line no-empty + } catch {} + } + return false; + } + : (alwaysFalse as CallableIsTargetLive), + // callableIsTargetRevoked + IS_NOT_IN_SHADOW_REALM + ? (targetPointer: Pointer): boolean => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + try { + isArrayOrThrowForRevoked(target); + return false; + // eslint-disable-next-line no-empty + } catch {} + return true; + } + : (alwaysFalse as CallableIsTargetRevoked), + // callableSerializeTarget + IS_IN_SHADOW_REALM + ? (targetPointer: Pointer): SerializedValue | undefined => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + try { + return SymbolToStringTag in target + ? serializeTargetByTrialAndError(target) + : // Fast path. + serializeTargetByBrand(target); + // eslint-disable-next-line no-empty + } catch {} + return undefined; + } + : (noop as CallableSerializeTarget), + // callableSetLazyPropertyDescriptorStateByTarget + IS_NOT_IN_SHADOW_REALM + ? (targetPointer: Pointer, statePointer: Pointer) => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + statePointer(); + const state = selectedTarget!; + selectedTarget = undefined; + // We don't wrap the weak map `set()` call in a try-catch + // because we know `target` is an object. + proxyTargetToLazyPropertyDescriptorStateMap.set(target, state); + } + : (noop as CallableSetLazyPropertyDescriptorStateByTarget), + // callableTrackAsFastTarget + IS_IN_SHADOW_REALM + ? (targetPointer: Pointer) => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + if (useFastForeignTargetPath) { + fastForeignTargetPointers.add(getTransferablePointer(target)); + } + } + : (noop as CallableTrackAsFastTarget), + // callableBatchGetPrototypeOfAndGetOwnPropertyDescriptors + ( + targetPointer: Pointer, + foreignCallableDescriptorsCallback: CallableDescriptorsCallback + ): PointerOrPrimitive => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let unsafeDescs; + try { + unsafeDescs = ObjectGetOwnPropertyDescriptors(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + const ownKeys = ReflectOwnKeys(unsafeDescs); + const { length } = ownKeys; + const descriptorTuples = new ArrayCtor( + length * 7 + ) as Parameters<CallableDescriptorCallback>; + for (let i = 0, j = 0; i < length; i += 1, j += 7) { + const ownKey = ownKeys[i]; + const safeDesc = (unsafeDescs as any)[ownKey]; + ReflectSetPrototypeOf(safeDesc, null); + const { get: getter, set: setter, value } = safeDesc; + descriptorTuples[j] = ownKey; + descriptorTuples[j + 1] = + 'configurable' in safeDesc + ? (safeDesc.configurable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 2] = + 'enumerable' in safeDesc + ? (safeDesc.enumerable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 3] = + 'writable' in safeDesc + ? (safeDesc.writable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 4] = + 'value' in safeDesc + ? // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : value + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 5] = + 'get' in safeDesc + ? // Inline getTransferableValue(). + typeof getter === 'function' + ? getTransferablePointer(getter) + : getter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + descriptorTuples[j + 6] = + 'set' in safeDesc + ? // Inline getTransferableValue(). + typeof setter === 'function' + ? getTransferablePointer(setter) + : setter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL; + } + ReflectApply( + foreignCallableDescriptorsCallback, + undefined, + descriptorTuples as Parameters<CallableDescriptorsCallback> + ); + let proto; + try { + proto = ReflectGetPrototypeOf(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }, + // callableBatchGetPrototypeOfWhenHasNoOwnProperty + (targetPointer: Pointer, key: PropertyKey): PointerOrPrimitive => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let proto; + try { + if (ObjectHasOwn(target, key)) { + return true; + } + proto = ReflectGetPrototypeOf(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + }, + // callableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor + ( + targetPointer: Pointer, + key: PropertyKey, + foreignCallableDescriptorCallback: CallableDescriptorCallback + ): PointerOrPrimitive => { + targetPointer(); + const target = selectedTarget!; + selectedTarget = undefined; + let safeDesc; + try { + safeDesc = ReflectGetOwnPropertyDescriptor(target, key); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + if (safeDesc) { + ReflectSetPrototypeOf(safeDesc, null); + const { get: getter, set: setter, value } = safeDesc; + foreignCallableDescriptorCallback( + key, + 'configurable' in safeDesc + ? (safeDesc.configurable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'enumerable' in safeDesc + ? (safeDesc.enumerable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'writable' in safeDesc + ? (safeDesc.writable as boolean) + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'value' in safeDesc + ? // Inline getTransferableValue(). + (typeof value === 'object' && value !== null) || + typeof value === 'function' + ? getTransferablePointer(value) + : // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + typeof value === 'undefined' + ? undefined + : value + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'get' in safeDesc + ? // Inline getTransferableValue(). + typeof getter === 'function' + ? getTransferablePointer(getter) + : getter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL, + 'set' in safeDesc + ? // Inline getTransferableValue(). + typeof setter === 'function' + ? getTransferablePointer(setter) + : setter + : LOCKER_NEAR_MEMBRANE_UNDEFINED_VALUE_SYMBOL + ); + return undefined; + } + let proto; + try { + proto = ReflectGetPrototypeOf(target); + } catch (error: any) { + throw pushErrorAcrossBoundary(error); + } + // Intentionally ignoring `document.all`. + // https://developer.mozilla.org/en-US/docs/Web/API/Document/all + // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot + if (typeof proto === 'undefined') { + return null; + } + return proto ? getTransferablePointer(proto) : proto; + } + ); + let foreignCallablesHooked = false; + return (...hooks: Parameters<HooksCallback>) => { + if (foreignCallablesHooked) { + return; + } + foreignCallablesHooked = true; + ({ + // 0: globalThisPointer, + // 1: getSelectedTarget, + // 2: getTransferableValue, + // 3: callableGetPropertyValuePointer, + // 4: callableEvaluate, + // 5: callableLinkPointers, + 6: foreignCallablePushErrorTarget, + 7: foreignCallablePushTarget, + 8: foreignCallableApply, + 9: foreignCallableConstruct, + 10: foreignCallableDefineProperty, + 11: foreignCallableDeleteProperty, + 12: foreignCallableGet, + 13: foreignCallableGetOwnPropertyDescriptor, + 14: foreignCallableGetPrototypeOf, + 15: foreignCallableHas, + 16: foreignCallableIsExtensible, + 17: foreignCallableOwnKeys, + 18: foreignCallablePreventExtensions, + 19: foreignCallableSet, + 20: foreignCallableSetPrototypeOf, + 21: foreignCallableDebugInfo, + // 22: callableDefineProperties, + 23: foreignCallableGetLazyPropertyDescriptorStateByTarget, + 24: foreignCallableGetPropertyValue, + 25: foreignCallableGetTargetIntegrityTraits, + 26: foreignCallableGetToStringTagOfTarget, + 27: foreignCallableInstallErrorPrepareStackTrace, + // 28: callableInstallLazyPropertyDescriptors, + 29: foreignCallableIsTargetLive, + 30: foreignCallableIsTargetRevoked, + 31: foreignCallableSerializeTarget, + 32: foreignCallableSetLazyPropertyDescriptorStateByTarget, + // 33: callableTrackAsFastTarget, + 34: foreignCallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + 35: foreignCallableBatchGetPrototypeOfWhenHasNoOwnProperty, + 36: foreignCallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor, + } = hooks); + const applyTrapForZeroOrMoreArgs = createApplyOrConstructTrapForZeroOrMoreArgs( + ProxyHandlerTraps.Apply + ); + const applyTrapForOneOrMoreArgs = createApplyOrConstructTrapForOneOrMoreArgs( + ProxyHandlerTraps.Apply + ); + const applyTrapForTwoOrMoreArgs = createApplyOrConstructTrapForTwoOrMoreArgs( + ProxyHandlerTraps.Apply + ); + const applyTrapForThreeOrMoreArgs = createApplyOrConstructTrapForThreeOrMoreArgs( + ProxyHandlerTraps.Apply + ); + const applyTrapForFourOrMoreArgs = createApplyOrConstructTrapForFourOrMoreArgs( + ProxyHandlerTraps.Apply + ); + const applyTrapForFiveOrMoreArgs = createApplyOrConstructTrapForFiveOrMoreArgs( + ProxyHandlerTraps.Apply + ); + const applyTrapForAnyNumberOfArgs = createApplyOrConstructTrapForAnyNumberOfArgs( + ProxyHandlerTraps.Apply + ); + const constructTrapForZeroOrMoreArgs = createApplyOrConstructTrapForZeroOrMoreArgs( + ProxyHandlerTraps.Construct + ); + const constructTrapForOneOrMoreArgs = createApplyOrConstructTrapForOneOrMoreArgs( + ProxyHandlerTraps.Construct + ); + const constructTrapForTwoOrMoreArgs = createApplyOrConstructTrapForTwoOrMoreArgs( + ProxyHandlerTraps.Construct + ); + const constructTrapForThreeOrMoreArgs = createApplyOrConstructTrapForThreeOrMoreArgs( + ProxyHandlerTraps.Construct + ); + const constructTrapForFourOrMoreArgs = createApplyOrConstructTrapForFourOrMoreArgs( + ProxyHandlerTraps.Construct + ); + const constructTrapForFiveOrMoreArgs = createApplyOrConstructTrapForFiveOrMoreArgs( + ProxyHandlerTraps.Construct + ); + const constructTrapForAnyNumberOfArgs = createApplyOrConstructTrapForAnyNumberOfArgs( + ProxyHandlerTraps.Construct + ); + if (MINIFICATION_SAFE_TRAP_PROPERTY_NAMES === undefined) { + // A minification safe way to get the 'apply' and 'construct' + // trap property names. + MINIFICATION_SAFE_TRAP_PROPERTY_NAMES = ObjectKeys({ + applyTrapForZeroOrMoreArgs, + applyTrapForOneOrMoreArgs, + applyTrapForTwoOrMoreArgs, + applyTrapForThreeOrMoreArgs, + applyTrapForFourOrMoreArgs, + applyTrapForFiveOrMoreArgs, + applyTrapForAnyNumberOfArgs, + constructTrapForZeroOrMoreArgs, + constructTrapForOneOrMoreArgs, + constructTrapForTwoOrMoreArgs, + constructTrapForThreeOrMoreArgs, + constructTrapForFourOrMoreArgs, + constructTrapForFiveOrMoreArgs, + constructTrapForAnyNumberOfArgs, + }); + } + applyTrapNameRegistry[0] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[0]; + applyTrapNameRegistry[1] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[1]; + applyTrapNameRegistry[2] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[2]; + applyTrapNameRegistry[3] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[3]; + applyTrapNameRegistry[4] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[4]; + applyTrapNameRegistry[5] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[5]; + applyTrapNameRegistry.n = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[6]; + constructTrapNameRegistry[0] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[7]; + constructTrapNameRegistry[1] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[8]; + constructTrapNameRegistry[2] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[9]; + constructTrapNameRegistry[3] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[10]; + constructTrapNameRegistry[4] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[11]; + constructTrapNameRegistry[5] = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[12]; + constructTrapNameRegistry.n = MINIFICATION_SAFE_TRAP_PROPERTY_NAMES[13]; + + const { prototype: BoundaryProxyHandlerProto } = BoundaryProxyHandler; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry[0]] = + applyTrapForZeroOrMoreArgs; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry[1]] = + applyTrapForOneOrMoreArgs; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry[2]] = + applyTrapForTwoOrMoreArgs; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry[3]] = + applyTrapForThreeOrMoreArgs; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry[4]] = + applyTrapForFourOrMoreArgs; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry[5]] = + applyTrapForFiveOrMoreArgs; + (BoundaryProxyHandlerProto as any)[applyTrapNameRegistry.n] = + applyTrapForAnyNumberOfArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry[0]] = + constructTrapForZeroOrMoreArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry[1]] = + constructTrapForOneOrMoreArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry[2]] = + constructTrapForTwoOrMoreArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry[3]] = + constructTrapForThreeOrMoreArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry[4]] = + constructTrapForFourOrMoreArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry[5]] = + constructTrapForFiveOrMoreArgs; + (BoundaryProxyHandlerProto as any)[constructTrapNameRegistry.n] = + constructTrapForAnyNumberOfArgs; + if (DEV_MODE) { + // @ts-ignore: Prevent read-only property error. + BoundaryProxyHandlerProto.color = color; + } + ReflectSetPrototypeOf(BoundaryProxyHandlerProto, null); + }; + }; + /* eslint-enable prefer-object-spread */ +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | import type { + Getter, + NearMembraneSerializedValue as SerializedValue, + ProxyTarget, +} from '@locker/near-membrane-shared'; + +export interface Activity { + stop(data?: DataType): void; + error(data?: DataType): void; +} +export type CallableApply = ( + targetPointer: Pointer, + thisArgPointerOrUndefined: PointerOrPrimitive, + ...args: PointerOrPrimitive[] +) => PointerOrPrimitive; +export type CallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors = ( + targetPointer: Pointer, + foreignCallableDescriptorsCallback: CallableDescriptorsCallback +) => PointerOrPrimitive; +export type CallableBatchGetPrototypeOfWhenHasNoOwnProperty = ( + targetPointer: Pointer, + key: PropertyKey +) => PointerOrPrimitive; +export type CallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor = ( + targetPointer: Pointer, + key: PropertyKey, + foreignCallableDescriptorCallback: CallableDescriptorCallback +) => PointerOrPrimitive; +export type CallableConstruct = ( + targetPointer: Pointer, + newTargetPointer: PointerOrPrimitive, + ...args: PointerOrPrimitive[] +) => PointerOrPrimitive; +export type CallableDebugInfo = (...args: Parameters<typeof console.info>) => void; +export type CallableDefineProperties = ( + targetPointer: Pointer, + ...descriptorTuples: [...Parameters<CallableDescriptorCallback>] +) => void; +export type CallableDefineProperty = ( + targetPointer: Pointer, + key: PropertyKey, + configurable: boolean | symbol, + enumerable: boolean | symbol, + writable: boolean | symbol, + valuePointer: PointerOrPrimitive, + getterPointer: PointerOrPrimitive, + setterPointer: PointerOrPrimitive, + foreignCallableNonConfigurableDescriptorCallback: CallableNonConfigurableDescriptorCallback +) => boolean; +export type CallableDeleteProperty = (targetPointer: Pointer, key: PropertyKey) => boolean; +export type CallableDescriptorCallback = ( + key: PropertyKey, + configurable: boolean | symbol, + enumerable: boolean | symbol, + writable: boolean | symbol, + valuePointer: PointerOrPrimitive, + getterPointer: PointerOrPrimitive, + setterPointer: PointerOrPrimitive +) => void; +export type CallableDescriptorsCallback = ( + ...descriptorTuples: [...Parameters<CallableDescriptorCallback>] +) => void; +export type CallableEvaluate = (sourceText: string) => PointerOrPrimitive; +export type CallableGet = ( + targetPointer: Pointer, + targetTraits: number, + key: PropertyKey, + receiverPointerOrPrimitive: PointerOrPrimitive +) => PointerOrPrimitive; +export type CallableGetPropertyValue = ( + targetPointer: Pointer, + key: PropertyKey +) => PointerOrPrimitive; +export type CallableGetLazyPropertyDescriptorStateByTarget = ( + targetPointer: Pointer +) => PointerOrPrimitive; +export type CallableGetOwnPropertyDescriptor = ( + targetPointer: Pointer, + key: PropertyKey, + foreignCallableDescriptorCallback: CallableDescriptorCallback +) => void; +export type CallableGetPropertyValuePointer = (targetPointer: Pointer, key: PropertyKey) => Pointer; +export type CallableGetPrototypeOf = (targetPointer: Pointer) => PointerOrPrimitive; +export type CallableGetTargetIntegrityTraits = (targetPointer: Pointer) => number; +export type CallableGetToStringTagOfTarget = (targetPointer: Pointer) => string; +export type CallableHas = (targetPointer: Pointer, key: PropertyKey) => boolean; +export type CallableInstallErrorPrepareStackTrace = () => void; +export type CallableInstallLazyPropertyDescriptors = ( + targetPointer: Pointer, + ...ownKeysAndUnforgeableGlobalThisKeys: PropertyKey[] +) => void; +export type CallableIsExtensible = (targetPointer: Pointer) => boolean; +export type CallableIsTargetLive = (targetPointer: Pointer, targetTraits: number) => boolean; +export type CallableIsTargetRevoked = (targetPointer: Pointer) => boolean; +export type CallableLinkPointers = (targetPointer: Pointer, foreignTargetPointer: Pointer) => void; +export type CallableNonConfigurableDescriptorCallback = CallableDescriptorCallback; +export type CallableOwnKeys = ( + targetPointer: Pointer, + foreignCallableKeysCallback: (...args: ReturnType<typeof Reflect.ownKeys>) => void +) => void; +export type CallablePreventExtensions = (targetPointer: Pointer) => number; +export type CallablePushErrorTarget = CallablePushTarget; +export type CallablePushTarget = ( + foreignTargetPointer: () => void, + foreignTargetTraits: number, + foreignTargetFunctionArity: number, + foreignTargetFunctionName: string, + foreignTargetTypedArrayLength: number +) => Pointer; +export type CallableSerializeTarget = (targetPointer: Pointer) => SerializedValue | undefined; +export type CallableSetLazyPropertyDescriptorStateByTarget = ( + targetPointer: Pointer, + statePointer: Pointer +) => void; +export type CallableSet = ( + targetPointer: Pointer, + key: PropertyKey, + valuePointerOrPrimitive: PointerOrPrimitive, + receiverPointerOrPrimitive: PointerOrPrimitive +) => boolean; +export type CallableSetPrototypeOf = ( + targetPointer: Pointer, + protoPointerOrNull: Pointer | null +) => boolean; +export type CallableTrackAsFastTarget = (targetPointer: Pointer) => void; +export type Connector = ( + color: string, + foreignCallableHooksCallback: HooksCallback, + options?: HooksOptions | undefined +) => HooksCallback; +export type DataType = boolean | object | number | string; +export type DistortionCallback = (target: ProxyTarget) => ProxyTarget; +export interface ForeignPropertyDescriptor extends PropertyDescriptor { + foreign?: boolean; +} +export type GetSelectedTarget = Getter; +export type GetTransferableValue = (value: any) => PointerOrPrimitive; +export type GlobalThisGetter = () => typeof globalThis; +export type HooksCallback = ( + globalThisPointer: Pointer, + getSelectedTarget: GetSelectedTarget, + getTransferableValue: GetTransferableValue, + callableGetPropertyValuePointer: CallableGetPropertyValuePointer, + callableEvaluate: CallableEvaluate, + callableLinkPointers: CallableLinkPointers, + callablePushErrorTarget: CallablePushErrorTarget, + callablePushTarget: CallablePushTarget, + callableApply: CallableApply, + callableConstruct: CallableConstruct, + callableDefineProperty: CallableDefineProperty, + callableDeleteProperty: CallableDeleteProperty, + callableGet: CallableGet, + callableGetOwnPropertyDescriptor: CallableGetOwnPropertyDescriptor, + callableGetPrototypeOf: CallableGetPrototypeOf, + callableHas: CallableHas, + callableIsExtensible: CallableIsExtensible, + callableOwnKeys: CallableOwnKeys, + callablePreventExtensions: CallablePreventExtensions, + callableSet: CallableSet, + callableSetPrototypeOf: CallableSetPrototypeOf, + callableDebugInfo: CallableDebugInfo, + callableDefineProperties: CallableDefineProperties, + callableGetLazyPropertyDescriptorStateByTarget: CallableGetLazyPropertyDescriptorStateByTarget, + callableGetPropertyValue: CallableGetPropertyValue, + callableGetTargetIntegrityTraits: CallableGetTargetIntegrityTraits, + callableGetToStringTagOfTarget: CallableGetToStringTagOfTarget, + callableInstallErrorPrepareStackTrace: CallableInstallErrorPrepareStackTrace, + callableInstallLazyPropertyDescriptors: CallableInstallLazyPropertyDescriptors, + callableIsTargetLive: CallableIsTargetLive, + callableIsTargetRevoked: CallableIsTargetRevoked, + callableSerializeTarget: CallableSerializeTarget, + callableSetLazyPropertyDescriptorStateByTarget: CallableSetLazyPropertyDescriptorStateByTarget, + callableTrackAsFastTarget: CallableTrackAsFastTarget, + callableBatchGetPrototypeOfAndGetOwnPropertyDescriptors: CallableBatchGetPrototypeOfAndGetOwnPropertyDescriptors, + callableBatchGetPrototypeOfWhenHasNoOwnProperty: CallableBatchGetPrototypeOfWhenHasNoOwnProperty, + callableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor: CallableBatchGetPrototypeOfWhenHasNoOwnPropertyDescriptor +) => void; +export interface HooksOptions { + distortionCallback?: DistortionCallback; + instrumentation?: Instrumentation; + liveTargetCallback?: LiveTargetCallback; + revokedProxyCallback?: RevokedProxyCallback; +} +export interface Instrumentation { + startActivity(activityName: string, data?: DataType): Activity; + log(data?: DataType): void; + error(data?: DataType): void; +} +export type LiveTargetCallback = (target: ProxyTarget, targetTraits: number) => boolean; +export type Pointer = CallableFunction; +export type PointerOrPrimitive = Pointer | Primitive; +export type Primitive = bigint | boolean | null | number | string | symbol | undefined | void; +export type RevokedProxyCallback = (target: ProxyTarget) => boolean; +export type SignSourceCallback = (sourceText: string) => string; +export type { SerializedValue }; +export type ShadowTarget = ProxyTarget; +export interface VirtualEnvironmentOptions { + blueConnector: Connector; + redConnector: Connector; + distortionCallback?: DistortionCallback; + instrumentation?: Instrumentation; + liveTargetCallback?: LiveTargetCallback; + revokedProxyCallback?: RevokedProxyCallback; + signSourceCallback?: SignSourceCallback; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 | + + + + + + + + + + +37x + + +37x +37x +37x +37x +37x +37x +37x +37x + + +37x + + +37x + + +37x + + +37x + + +37x + + +37x + + +37x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +37x +37x +1x +1x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | import { LOCKER_UNMINIFIED_FLAG, SymbolFor, ArrayIsArray, ReflectDefineProperty, isNearMembraneProxy, ReflectApply, ArrayProtoPush, ObjectProtoToString, ObjectKeys, TO_STRING_BRAND_SYMBOL, ArrayProtoIncludes, ArrayProtoUnshift, TO_STRING_BRAND_STRING, ArrayProtoFilter, NumberIsInteger, ReflectOwnKeys, ArrayProtoMap, StringCtor, MathMin, NumberIsNaN, NumberCtor, CHAR_ELLIPSIS, StringProtoSlice, getNearMembraneProxySerializedValue, TO_STRING_BRAND_NUMBER, TO_STRING_BRAND_BOOLEAN, TO_STRING_BRAND_BIG_INT, ArrayProtoIndexOf, ArrayProtoSplice, isObject, NumberIsFinite, JSONStringify } from '@locker/near-membrane-shared'; +import { rootWindow } from '@locker/near-membrane-shared-dom'; + +// This package is bundled by third-parties that have their own build time +// replacement logic. Instead of customizing each build system to be aware +// of this package we implement a two phase debug mode by performing small +// runtime checks to determine phase one, our code is unminified, and +// phase two, the user opted-in to custom devtools formatters. Phase one +// is used for light weight initialization time debug while phase two is +// reserved for post initialization runtime. +// istanbul ignore else: not avoidable via tests +if (LOCKER_UNMINIFIED_FLAG) { + // We passed the phase one gate so we know our code is unminified and we can + // install Locker's custom devtools formatter. + let lockerDebugModeSymbolFlag = true; + const LOCKER_DEBUG_MODE_SYMBOL = SymbolFor('@@lockerDebugMode'); + const MAX_ARRAY_DISPLAY = 100; + const MAX_OBJECT_DISPLAY = 5; + const MAX_STRING_DISPLAY = 100; + const MID_STRING_DISPLAY = MAX_STRING_DISPLAY / 2; + const headerCSSText = 'display: inline-block; margin-bottom: 3px; margin-left: -3px; word-break: break-all; word-wrap: wrap;'; + const bodyItemStyleObject = { + style: 'margin-left:15px; margin-bottom: 3px;' + }; + const bodyStyleObject = { + style: 'display: inline-block; margin-left:12px; word-break: break-all; word-wrap: wrap;' + }; + const keyEnumerableStringStyleObject = { + style: 'color: #9d288c; font-weight: bold' + }; + const keyNonEnumerableOrSymbolStyleObject = { + style: 'color: #b17ab0' + }; + const primitiveBlueColorStyleObject = { + style: 'color: #16239f' + }; + const primitiveGreenColorStyleObject = { + style: 'color: #236d25' + }; + const primitiveGreyColorStyleObject = { + style: 'color: #606367' + }; + const primitiveOrangeColorStyleObject = { + style: 'color: #b82619' + }; + // istanbul ignore next: currently unreachable via tests + const formatValue = function formatValue(value) { + if (value === null || value === undefined) { + return ['span', primitiveGreyColorStyleObject, `${value}`]; + } + if (typeof value === 'boolean') { + return ['span', primitiveBlueColorStyleObject, value]; + } + if (typeof value === 'number') { + return NumberIsFinite(value) ? ['span', primitiveBlueColorStyleObject, value] : ['span', primitiveBlueColorStyleObject, `${value >= 0 ? '' : '-'}Infinity`]; + } + if (typeof value === 'bigint') { + return ['span', primitiveGreenColorStyleObject, `${value}n`]; + } + if (typeof value === 'string') { + let string = value; + const { + length + } = string; + if (length > MAX_STRING_DISPLAY) { + const firstChunk = ReflectApply(StringProtoSlice, string, [0, MID_STRING_DISPLAY]); + const lastChunk = ReflectApply(StringProtoSlice, string, [length - MID_STRING_DISPLAY - 1, length]); + string = firstChunk + CHAR_ELLIPSIS + lastChunk; + } + // @TODO: Default to using single quotes on main header and double + // quotes on body. + return ['span', primitiveOrangeColorStyleObject, JSONStringify(string)]; + } + if (ArrayIsArray(value)) { + return ['span', {}, `Array(${value.length})`]; + } + if (isObject(value)) { + return ['span', {}, `{${CHAR_ELLIPSIS}}`]; + } + // Symbol will be coerced to a string. + return ['span', primitiveOrangeColorStyleObject, StringCtor(value)]; + }; + // istanbul ignore next: currently unreachable via tests + const formatHeader = function formatHeader(object, config) { + const isChildElement = config == null ? void 0 : config.isChildElement; + const formattedHeader = []; + let formattedHeaderOffset = 0; + if (isChildElement) { + formattedHeader[formattedHeaderOffset++] = ['span', keyEnumerableStringStyleObject, config.childKey]; + formattedHeader[formattedHeaderOffset++] = ['span', {}, ': ']; + } + const brand = ReflectApply(ObjectProtoToString, object, []); + let keys = ObjectKeys(object); + if (brand === TO_STRING_BRAND_SYMBOL) { + if (!ReflectApply(ArrayProtoIncludes, keys, ['description'])) { + ReflectApply(ArrayProtoUnshift, keys, ['description']); + } + } else if (brand === TO_STRING_BRAND_STRING) { + const { + length + } = object; + keys = ReflectApply(ArrayProtoFilter, keys, [key => { + const possibleIndex = typeof key === 'string' ? +key : -1; + return possibleIndex < 0 || possibleIndex >= length || !NumberIsInteger(possibleIndex); + }]); + } + const ownKeysRaw = ReflectOwnKeys(object); + const ownKeys = ReflectApply(ArrayProtoMap, ownKeysRaw, [StringCtor]); + const { + length: ownKeysLength + } = ownKeys; + if (ArrayIsArray(object)) { + formattedHeader[formattedHeaderOffset++] = ['span', {}, `(${object.length}) [`]; + for (let i = 0, length = MathMin(ownKeysLength, MAX_ARRAY_DISPLAY); i < length; i += 1) { + const ownKeyRaw = ownKeysRaw[i]; + const ownKey = ownKeys[i]; + const value = object[ownKeyRaw]; + if (ownKey !== 'length') { + if (!NumberIsNaN(NumberCtor(ownKey))) { + formattedHeader[formattedHeaderOffset++] = ['span', {}, i ? ', ' : '']; + formattedHeader[formattedHeaderOffset++] = formatValue(value); + } else { + formattedHeader[formattedHeaderOffset++] = ['span', {}, i ? ', ' : '']; + formattedHeader[formattedHeaderOffset++] = ['span', primitiveGreyColorStyleObject, StringCtor(ownKey)]; + formattedHeader[formattedHeaderOffset++] = ['span', {}, ': ']; + formattedHeader[formattedHeaderOffset++] = formatValue(value); + } + } + } + if (ownKeysLength > MAX_ARRAY_DISPLAY) { + formattedHeader[formattedHeaderOffset++] = ['span', null, ['span', {}, `, ${CHAR_ELLIPSIS}`]]; + } + formattedHeader[formattedHeaderOffset++] = ['span', {}, ']']; + return formattedHeader; + } + let boxedHeaderEntry; + let headerOpening = '{'; + // eslint-disable-next-line default-case + switch (brand) { + case TO_STRING_BRAND_BIG_INT: + case TO_STRING_BRAND_BOOLEAN: + case TO_STRING_BRAND_NUMBER: + case TO_STRING_BRAND_STRING: + case TO_STRING_BRAND_SYMBOL: + { + let colorStyleObject = primitiveBlueColorStyleObject; + if (brand === TO_STRING_BRAND_BIG_INT) { + colorStyleObject = primitiveGreenColorStyleObject; + } else if (brand === TO_STRING_BRAND_SYMBOL) { + colorStyleObject = primitiveOrangeColorStyleObject; + } + headerOpening = `${ReflectApply(StringProtoSlice, brand, [8, -1])} {`; + boxedHeaderEntry = ['span', colorStyleObject, `${StringCtor(getNearMembraneProxySerializedValue(object))}`]; + break; + } + } + formattedHeader[formattedHeaderOffset++] = ['span', {}, headerOpening]; + if (boxedHeaderEntry) { + formattedHeader[formattedHeaderOffset++] = boxedHeaderEntry; + if (ownKeysLength) { + formattedHeader[formattedHeaderOffset++] = ['span', {}, ', ']; + } + } + for (let i = 0, length = MathMin(ownKeysLength, MAX_OBJECT_DISPLAY); i < length; i += 1) { + const ownKeyRaw = ownKeysRaw[i]; + const ownKey = ownKeys[i]; + const value = object[ownKeyRaw]; + formattedHeader[formattedHeaderOffset++] = ['span', {}, i ? ', ' : '']; + formattedHeader[formattedHeaderOffset++] = ['span', primitiveGreyColorStyleObject, ownKey]; + formattedHeader[formattedHeaderOffset++] = ['span', {}, ': ']; + formattedHeader[formattedHeaderOffset++] = formatValue(value); + } + if (ownKeysLength > MAX_OBJECT_DISPLAY) { + formattedHeader[formattedHeaderOffset++] = ['span', null, ['span', {}, `, ${CHAR_ELLIPSIS}`]]; + } + formattedHeader[formattedHeaderOffset++] = ['span', {}, '}']; + return formattedHeader; + }; + // istanbul ignore next: currently unreachable via tests + const formatBody = function formatBody(object) { + // @TODO: Arrays are broken into groups of 100. + const ownKeysRaw = ReflectOwnKeys(object); + const ownKeys = ReflectApply(ArrayProtoMap, ownKeysRaw, [StringCtor]); + // Put 'length' at the end of array. + const isArray = ArrayIsArray(object); + if (isArray) { + const lengthIndex = ReflectApply(ArrayProtoIndexOf, ownKeys, ['length']); + const lengthKeyRaw = ReflectApply(ArrayProtoSplice, ownKeysRaw, [lengthIndex, 1])[0]; + ReflectApply(ArrayProtoPush, ownKeysRaw, [lengthKeyRaw]); + const lengthKey = ReflectApply(ArrayProtoSplice, ownKeys, [lengthIndex, 1])[0]; + ReflectApply(ArrayProtoPush, ownKeys, [lengthKey]); + } + const formattedBody = []; + let formattedBodyOffset = 0; + for (let i = 0, { + length + } = ownKeys; i < length; i += 1) { + const ownKeyRaw = ownKeysRaw[i]; + const ownKey = ownKeys[i]; + const value = object[ownKeyRaw]; + if (isObject(value)) { + formattedBody[formattedBodyOffset++] = ['div', {}, ['object', { + object: value, + config: { + childKey: StringCtor(ownKey), + isChildElement: true + } + }]]; + } else { + let currentKeyStyle = keyEnumerableStringStyleObject; + if (isArray && ownKey === 'length') { + currentKeyStyle = keyNonEnumerableOrSymbolStyleObject; + } + formattedBody[formattedBodyOffset++] = ['div', bodyItemStyleObject, ['span', currentKeyStyle, ownKey], ['span', {}, ': '], formatValue(value)]; + } + } + return formattedBody; + }; + let { + devtoolsFormatters + } = rootWindow; + if (!ArrayIsArray(devtoolsFormatters)) { + devtoolsFormatters = []; + ReflectDefineProperty(rootWindow, 'devtoolsFormatters', { + __proto__: null, + configurable: true, + value: devtoolsFormatters, + writable: true + }); + } + // Append our custom formatter to the array of devtools formatters. + // istanbul ignore next: currently unreachable via tests + devtoolsFormatters[devtoolsFormatters.length] = { + // istanbul ignore next: currently unreachable via tests + header(object, config) { + if (lockerDebugModeSymbolFlag) { + // We passed the second phase gate so we know that the user has + // opted-in to custom devtools formatters. Close the gate and + // define the @@lockerDebugMode symbol on window. + lockerDebugModeSymbolFlag = false; + ReflectDefineProperty(rootWindow, LOCKER_DEBUG_MODE_SYMBOL, { + __proto__: null, + configurable: true, + value: true, + writable: true + }); + } + if (!isNearMembraneProxy(object)) { + return null; + } + const headerDiv = ['div', { + style: `${headerCSSText}${config != null && config.isChildElement ? '' : 'font-style: italic;'}` + }]; + ReflectApply(ArrayProtoPush, headerDiv, formatHeader(object, config)); + return ['div', {}, headerDiv]; + }, + // istanbul ignore next: currently unreachable via tests + hasBody() { + return true; + }, + // istanbul ignore next: currently unreachable via tests + body(object) { + const bodyDiv = ['div', bodyStyleObject]; + ReflectApply(ArrayProtoPush, bodyDiv, formatBody(object)); + return bodyDiv; + } + }; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
custom-devtools-formatter.mjs.js | +
+
+ |
+ 100% | +20/20 | +100% | +2/2 | +100% | +0/0 | +100% | +20/20 | +
index.mjs.js | +
+
+ |
+ 96.51% | +83/86 | +85.71% | +30/35 | +100% | +7/7 | +96.47% | +82/85 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 | + + + +37x + + + + +37x + + + +265x + + + +265x +265x + + +264x + + +1x + +264x +226x + + + +38x +38x +38x +38x + + + + + + + + + +38x +38x + + +257x +257x +257x +257x + +257x +271711x +271711x +1028x + +270683x + +257x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +191x +191x +191x +191x + +191x +191x + + + + + + + +37x +37x +37x +37x + + +227x + + +227x +227x +227x +227x +227x +227x + + +229x +1x + +228x +228x +1x + + + + + + + + + + + + +227x + + +227x +227x +227x +227x +227x +227x +36x +36x + + + +227x + + + + + +227x +227x + +1x + + + + + + +227x + + + +227x + + + + + +227x + + + + +227x +227x +227x + + + + + +227x +191x +191x +191x +191x + + + +227x + + + + + +227x + + + + +226x + +226x +226x +226x +226x + +1x + + + + + +1x + +227x + + +12302x + + + | import './custom-devtools-formatter.mjs.js'; +import { getFilteredGlobalOwnKeys, createBlueConnector, VirtualEnvironment, createRedConnector, linkIntrinsics, assignFilteredGlobalDescriptorsFromPropertyDescriptorMap } from '@locker/near-membrane-base'; +import { toSafeWeakMap, ReflectGetPrototypeOf, ReflectOwnKeys, SetCtor, ReflectApply, SetProtoHas, ReflectDeleteProperty, toSafeWeakSet, WeakSetCtor, WeakMapCtor, TypeErrorCtor, ObjectAssign, isObject } from '@locker/near-membrane-shared'; +import { rootWindow, IS_CHROMIUM_BROWSER, HTMLIFrameElementProtoContentWindowGetter, DocumentProtoOpen, DocumentProtoClose, IS_OLD_CHROMIUM_BROWSER, ElementProtoRemove, DocumentProtoCreateElement, DocumentProtoBodyGetter, NodeProtoLastChildGetter, HTMLElementProtoStyleGetter, ElementProtoSetAttribute, NodeProtoAppendChild } from '@locker/near-membrane-shared-dom'; +const blueDocumentToRecordMap = toSafeWeakMap(new WeakMap()); +// Chromium based browsers have a bug that nulls the result of `window` +// getters in detached iframes when the property descriptor of `window.window` +// is retrieved. +// https://bugs.chromium.org/p/chromium/issues/detail?id=1305302 +const unforgeablePoisonedWindowKeys = IS_CHROMIUM_BROWSER ? ['window'] : undefined; +function getCachedGlobalObjectReferences(globalObject) { + const { + window + } = globalObject; + let record; + let document; + // Suppress errors thrown on cross-origin opaque windows. + try { + ({ + document + } = globalObject); + record = blueDocumentToRecordMap.get(document); + // eslint-disable-next-line no-empty + } catch (_unused) { + return undefined; + } + if (record) { + return record; + } + // Cache references to object values that can't be replaced + // window -> Window -> WindowProperties -> EventTarget + const WindowProto = ReflectGetPrototypeOf(window); + const WindowPropertiesProto = ReflectGetPrototypeOf(WindowProto); + const EventTargetProto = ReflectGetPrototypeOf(WindowPropertiesProto); + record = { + document, + DocumentProto: ReflectGetPrototypeOf(document), + window, + WindowProto: ReflectGetPrototypeOf(window), + WindowPropertiesProto: ReflectGetPrototypeOf(WindowProto), + EventTargetProto, + // Some simulated browser environments, e.g. those using JSDOM, may lack an EventTargetProto. + EventTargetProtoOwnKeys: EventTargetProto ? ReflectOwnKeys(EventTargetProto) : [] + }; + blueDocumentToRecordMap.set(document, record); + return record; +} +function filterWindowKeys(keys) { + const excludedKeys = new SetCtor(['document', 'location', 'top', 'window']); + const result = []; + let resultOffset = 0; + for (let i = 0, { + length + } = keys; i < length; i += 1) { + const key = keys[i]; + if (ReflectApply(SetProtoHas, excludedKeys, [key])) { + continue; + } + result[resultOffset++] = key; + } + return result; +} +/** + * global descriptors are a combination of 3 set of descriptors: + * - first, the key of the red descriptors define the descriptors + * provided by the browser when creating a brand new window. + * - second, once we know the base keys, we get the actual descriptors + * from the blueDescriptors, since those are the one we want to provide + * access to via the membrane. + * - third, the user of this library can provide endowments, which define + * global descriptors that should be installed into the sandbox on top + * of the base descriptors. + * + * Note: The main reason for using redDescriptors as the base keys instead + * of blueDescriptor is because there is no guarantee that this library is + * the first one to be evaluated in the host app, which means it has no ways + * to determine what is a real DOM API vs app specific globals. + * + * Quirk: The only quirk here is for the case in which this library runs + * after some other code that patches some of the DOM APIs. This means + * the installed proxy in the sandbox will point to the patched global + * API in the blue realm, rather than the original, because we don't have + * a way to access the original anymore. This should not be a deal-breaker + * if the patched API behaves according to the spec. + * + * The result of this method is a descriptor map that contains everything + * that will be installed (via the membrane) as global descriptors in + * the red realm. + */ +function removeWindowDescriptors(unsafeDescs) { + // Remove unforgeable descriptors that cannot be installed. + ReflectDeleteProperty(unsafeDescs, 'document'); + ReflectDeleteProperty(unsafeDescs, 'location'); + ReflectDeleteProperty(unsafeDescs, 'top'); + ReflectDeleteProperty(unsafeDescs, 'window'); + // Remove other browser specific unforgeables. + ReflectDeleteProperty(unsafeDescs, 'chrome'); + return unsafeDescs; +} +/** + * Initialization operation to capture and cache all unforgeable references + * and their respective descriptor maps before any other code runs, this + * usually help because this library runs before anything else that can poison + * the environment. + */ +getCachedGlobalObjectReferences(rootWindow); +const IFRAME_SANDBOX_ATTRIBUTE_VALUE = 'allow-same-origin allow-scripts'; +const revoked = toSafeWeakSet(new WeakSetCtor()); +const blueCreateHooksCallbackCache = toSafeWeakMap(new WeakMapCtor()); +function createDetachableIframe(doc) { + var _ReflectApply; + const iframe = ReflectApply(DocumentProtoCreateElement, doc, ['iframe']); + // It is impossible to test whether the NodeProtoLastChildGetter branch is + // reached in a normal Karma test environment. + const parent = (_ReflectApply = ReflectApply(DocumentProtoBodyGetter, doc, [])) != null ? _ReflectApply : /* istanbul ignore next */ReflectApply(NodeProtoLastChildGetter, doc, []); + const style = ReflectApply(HTMLElementProtoStyleGetter, iframe, []); + style.display = 'none'; + ReflectApply(ElementProtoSetAttribute, iframe, ['sandbox', IFRAME_SANDBOX_ATTRIBUTE_VALUE]); + ReflectApply(NodeProtoAppendChild, parent, [iframe]); + return iframe; +} +function createIframeVirtualEnvironment(globalObject, providedOptions) { + if (typeof globalObject !== 'object' || globalObject === null) { + throw new TypeErrorCtor('Missing global object virtualization target.'); + } + const blueRefs = getCachedGlobalObjectReferences(globalObject); + if (typeof blueRefs !== 'object' || blueRefs === null) { + throw new TypeErrorCtor('Invalid virtualization target.'); + } + const { + distortionCallback, + defaultPolicy, + endowments, + globalObjectShape, + instrumentation, + keepAlive = true, + liveTargetCallback, + maxPerfMode = false, + signSourceCallback + // eslint-disable-next-line prefer-object-spread + } = ObjectAssign({ + __proto__: null + }, providedOptions); + const iframe = createDetachableIframe(blueRefs.document); + const redWindow = ReflectApply(HTMLIFrameElementProtoContentWindowGetter, iframe, []); + const shouldUseDefaultGlobalOwnKeys = typeof globalObjectShape !== 'object' || globalObjectShape === null; + const defaultGlobalOwnKeys = filterWindowKeys(getFilteredGlobalOwnKeys(redWindow, maxPerfMode)); + let blueConnector = blueCreateHooksCallbackCache.get(blueRefs.document); + if (blueConnector === undefined) { + blueConnector = createBlueConnector(globalObject); + blueCreateHooksCallbackCache.set(blueRefs.document, blueConnector); + } + // Install default TrustedTypes policy in the virtual environment. + // @ts-ignore trustedTypes does not exist on GlobalObject + Iif (typeof redWindow.trustedTypes !== 'undefined' && isObject(defaultPolicy)) { + // @ts-ignore trustedTypes does not exist on GlobalObject + redWindow.trustedTypes.createPolicy('default', defaultPolicy); + } + const { + eval: redIndirectEval + } = redWindow; + const env = new VirtualEnvironment({ + blueConnector, + redConnector: createRedConnector(signSourceCallback ? sourceText => redIndirectEval(signSourceCallback(sourceText)) : redIndirectEval), + distortionCallback, + instrumentation, + liveTargetCallback, + revokedProxyCallback: keepAlive ? revokedProxyCallback : undefined, + signSourceCallback + }); + linkIntrinsics(env, globalObject); + // window + // window.document + // In browsers globalThis is === window. + Iif (typeof globalThis === 'undefined') { + // Support for globalThis was added in Chrome 71. + // However, environments like Android emulators are running Chrome 69. + env.link('window', 'document'); + } else { + // document is === window.document. + env.link('document'); + } + // window.__proto__ (aka Window.prototype) + // window.__proto__.__proto__ (aka WindowProperties.prototype) + // window.__proto__.__proto__.__proto__ (aka EventTarget.prototype) + env.link('__proto__', '__proto__', '__proto__'); + env.remapProto(blueRefs.document, blueRefs.DocumentProto); + env.lazyRemapProperties(blueRefs.window, shouldUseDefaultGlobalOwnKeys ? defaultGlobalOwnKeys : filterWindowKeys(getFilteredGlobalOwnKeys(globalObjectShape, maxPerfMode)), + // Chromium based browsers have a bug that nulls the result of `window` + // getters in detached iframes when the property descriptor of `window.window` + // is retrieved. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1305302 + keepAlive ? undefined : unforgeablePoisonedWindowKeys); + if (endowments) { + const filteredEndowments = {}; + assignFilteredGlobalDescriptorsFromPropertyDescriptorMap(filteredEndowments, endowments, maxPerfMode); + removeWindowDescriptors(filteredEndowments); + env.remapProperties(blueRefs.window, filteredEndowments); + } + // We intentionally skip remapping Window.prototype because there is nothing + // in it that needs to be remapped. + env.lazyRemapProperties(blueRefs.EventTargetProto, blueRefs.EventTargetProtoOwnKeys); + // We don't remap `blueRefs.WindowPropertiesProto` because it is "magical" + // in that it provides access to elements by id. + // + // Once we get the iframe info ready, and all mapped, we can proceed to + // detach the iframe only if `options.keepAlive` isn't true. + if (keepAlive) { + // @TODO: Temporary hack to preserve the document reference in Firefox. + // https://bugzilla.mozilla.org/show_bug.cgi?id=543435 + const { + document: redDocument + } = redWindow; + // Revoke the proxies of the redDocument and redWindow to prevent access. + revoked.add(redDocument); + revoked.add(redWindow); + ReflectApply(DocumentProtoOpen, redDocument, []); + ReflectApply(DocumentProtoClose, redDocument, []); + } else { + Iif (IS_OLD_CHROMIUM_BROWSER) { + // For Chromium < v86 browsers we evaluate the `window` object to + // kickstart the realm so that `window` persists when the iframe is + // removed from the document. + redIndirectEval('window'); + } + ReflectApply(ElementProtoRemove, iframe, []); + } + return env; +} +function revokedProxyCallback(value) { + return revoked.has(value); +} +export { createIframeVirtualEnvironment as default }; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
index.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +
node-realm.ts | +
+
+ |
+ 95.65% | +22/23 | +94.74% | +18/19 | +50% | +1/2 | +95.65% | +22/23 | +
types.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 | + + + + + + + + + | // eslint-disable-next-line no-restricted-exports +export { default } from './node-realm'; +export * from './types'; +export type { + Connector, + DistortionCallback, + Instrumentation, + LiveTargetCallback, +} from '@locker/near-membrane-base'; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 | + + + + + + + + + + + + + + + + + +4x + +4x + + + + + +24x +1x + + + + + + + + + +23x +23x +23x +4x +4x + +23x +23x +23x + + + + + + + + + + + +23x + + +23x +23x +2x + + +23x + + + + + + +23x +15x +15x + + + + +15x + +23x + + | import { runInNewContext } from 'node:vm';
+import {
+ assignFilteredGlobalDescriptorsFromPropertyDescriptorMap,
+ createBlueConnector,
+ createRedConnector,
+ getFilteredGlobalOwnKeys,
+ linkIntrinsics,
+ VirtualEnvironment,
+} from '@locker/near-membrane-base';
+import {
+ ObjectAssign,
+ toSafeWeakMap,
+ TypeErrorCtor,
+ WeakMapCtor,
+} from '@locker/near-membrane-shared';
+import type { Connector } from '@locker/near-membrane-base';
+import type { NodeEnvironmentOptions } from './types';
+
+const blueCreateHooksCallbackCache = toSafeWeakMap(new WeakMapCtor<typeof globalThis, Connector>());
+
+let defaultGlobalOwnKeys: PropertyKey[] | null = null;
+
+export default function createVirtualEnvironment(
+ globalObject: typeof globalThis,
+ providedOptions?: NodeEnvironmentOptions
+): VirtualEnvironment {
+ if (typeof globalObject !== 'object' || globalObject === null) {
+ throw new TypeErrorCtor('Missing global object virtualization target.');
+ }
+ const {
+ distortionCallback,
+ endowments,
+ globalObjectShape,
+ instrumentation,
+ liveTargetCallback,
+ maxPerfMode = false,
+ signSourceCallback,
+ } = ObjectAssign({ __proto__: null }, providedOptions) as NodeEnvironmentOptions;
+ let blueConnector = blueCreateHooksCallbackCache.get(globalObject) as Connector | undefined;
+ if (blueConnector === undefined) {
+ blueConnector = createBlueConnector(globalObject);
+ blueCreateHooksCallbackCache.set(globalObject, blueConnector);
+ }
+ const redGlobalObject = runInNewContext('globalThis');
+ const { eval: redIndirectEval } = redGlobalObject;
+ const env = new VirtualEnvironment({
+ blueConnector,
+ redConnector: createRedConnector(
+ signSourceCallback
+ ? (sourceText: string) => redIndirectEval(signSourceCallback(sourceText))
+ : redIndirectEval
+ ),
+ distortionCallback,
+ instrumentation,
+ liveTargetCallback,
+ signSourceCallback,
+ });
+ linkIntrinsics(env, globalObject);
+
+ const shouldUseDefaultGlobalOwnKeys =
+ typeof globalObjectShape !== 'object' || globalObjectShape === null;
+ if (shouldUseDefaultGlobalOwnKeys && defaultGlobalOwnKeys === null) {
+ defaultGlobalOwnKeys = getFilteredGlobalOwnKeys(redGlobalObject, maxPerfMode);
+ }
+
+ env.lazyRemapProperties(
+ globalObject,
+ shouldUseDefaultGlobalOwnKeys
+ ? (defaultGlobalOwnKeys as PropertyKey[])
+ : getFilteredGlobalOwnKeys(globalObjectShape, maxPerfMode)
+ );
+
+ if (endowments) {
+ const filteredEndowments = {};
+ assignFilteredGlobalDescriptorsFromPropertyDescriptorMap(
+ filteredEndowments,
+ endowments,
+ maxPerfMode
+ );
+ env.remapProperties(globalObject, filteredEndowments);
+ }
+ return env;
+}
+ |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 | + + + + + + + + + + + + + + + + | import type { + DistortionCallback, + Instrumentation, + LiveTargetCallback, + SignSourceCallback, +} from '@locker/near-membrane-base'; + +export interface NodeEnvironmentOptions { + distortionCallback?: DistortionCallback; + endowments?: PropertyDescriptorMap; + globalObjectShape?: object; + instrumentation?: Instrumentation; + liveTargetCallback?: LiveTargetCallback; + maxPerfMode?: boolean; + signSourceCallback?: SignSourceCallback; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
index.mjs.js | +
+
+ |
+ 100% | +21/21 | +77.78% | +7/9 | +100% | +2/2 | +100% | +21/21 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 | +44x + + + + + + + +44x + + + + + + +44x + + +7x +7x + +7x + + + + +44x + + + + + + +111x + + +44x + + + + + +44x + + + + +44x +44x + + + + +44x + + +44x +44x + + + +44x +44x +44x + + +44x + + +44x +44x + + | import { ArrayIsArray, ReflectApply, ArrayProtoFind, RegExpProtoTest, ObjectLookupOwnGetter } from '@locker/near-membrane-shared';
+const rootWindow = window;
+const {
+ // We don't cherry-pick the 'userAgent' property from `navigator` here
+ // to avoid triggering its getter.
+ navigator,
+ navigator: {
+ userAgentData
+ }
+} = rootWindow;
+// The user-agent client hints API is experimental and subject to change.
+// https://caniuse.com/mdn-api_navigator_useragentdata
+// istanbul ignore next: optional chaining and nullish coalescing results in an expansion that contains an unreachable "void 0" branch for every occurrence of the operator
+const brands = userAgentData == null ? void 0 : userAgentData.brands;
+// Note: Chromium identifies itself as Chrome in its user-agent string.
+// https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent
+const chromiumUserAgentRegExp = / (?:Headless)?Chrome\/\d+/;
+let userAgent;
+function getUserAgent() {
+ if (userAgent === undefined) {
+ userAgent = navigator.userAgent;
+ }
+ return userAgent;
+}
+const IS_CHROMIUM_BROWSER =
+// While experimental, `navigator.userAgentData.brands` may be defined as an
+// empty array in headless Chromium based browsers.
+ArrayIsArray(brands) && brands.length ?
+// Use user-agent client hints API if available to avoid deprecation
+// warnings.
+// https://developer.mozilla.org/en-US/docs/Web/API/User-Agent_Client_Hints_API
+// istanbul ignore next: this code is not reachable in the coverage run.
+ReflectApply(ArrayProtoFind, brands, [
+// prettier-ignore
+item => (item == null ? void 0 : item.brand) === 'Chromium']) !== undefined :
+// Fallback to a standard user-agent string sniff.
+ReflectApply(RegExpProtoTest, chromiumUserAgentRegExp, [getUserAgent()]);
+const IS_OLD_CHROMIUM_BROWSER = IS_CHROMIUM_BROWSER &&
+// Chromium added support for `navigator.userAgentData` in v90.
+// https://caniuse.com/mdn-api_navigator_useragentdata
+userAgentData === undefined;
+const {
+ prototype: DocumentProto
+} = Document;
+const {
+ close: DocumentProtoClose,
+ createElement: DocumentProtoCreateElement,
+ open: DocumentProtoOpen
+} = DocumentProto;
+const DocumentProtoBodyGetter = ObjectLookupOwnGetter(DocumentProto, 'body');
+
+// The DOMException constructor was exposed in Edge 12 but wasn't invocable
+// until Edge 79. As long as this is used for instanceof checks it should be fine.
+// https://developer.mozilla.org/en-US/docs/Web/API/DOMException#browser_compatibility
+const DOMExceptionCtor = DOMException;
+const {
+ DATA_CLONE_ERR: DATA_CLONE_ERROR_CODE
+} = DOMExceptionCtor;
+const DOMExceptionProtoCodeGetter = ObjectLookupOwnGetter(DOMExceptionCtor.prototype, 'code');
+const {
+ remove: ElementProtoRemove,
+ setAttribute: ElementProtoSetAttribute
+} = Element.prototype;
+const HTMLElementProtoStyleGetter = ObjectLookupOwnGetter(HTMLElement.prototype, 'style');
+const HTMLIFrameElementProtoContentWindowGetter = ObjectLookupOwnGetter(HTMLIFrameElement.prototype, 'contentWindow');
+const {
+ prototype: NodeProto
+} = Node;
+const {
+ appendChild: NodeProtoAppendChild
+} = NodeProto;
+const NodeProtoLastChildGetter = ObjectLookupOwnGetter(NodeProto, 'lastChild');
+export { DATA_CLONE_ERROR_CODE, DOMExceptionCtor, DOMExceptionProtoCodeGetter, DocumentProtoBodyGetter, DocumentProtoClose, DocumentProtoCreateElement, DocumentProtoOpen, ElementProtoRemove, ElementProtoSetAttribute, HTMLElementProtoStyleGetter, HTMLIFrameElementProtoContentWindowGetter, IS_CHROMIUM_BROWSER, IS_OLD_CHROMIUM_BROWSER, NodeProtoAppendChild, NodeProtoLastChildGetter, rootWindow };
+ |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
index.mjs.js | +
+
+ |
+ 96.71% | +294/304 | +72.64% | +77/106 | +92% | +23/25 | +96.69% | +292/302 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 | + + + + + + +62x +62x + + + + + +62x + + +62x + + + + +62x +62x + + + + +62x + +238x + + +442x + + +7x + +62x + + + + + +62x + + +62x +62x + + +62x + + + + + + + + + + + + + + + + + + + + + + + + +62x +62x + + + + + + + + + + + + + +62x + + +62x + +449x +449x +449x + + + + + + + + + + +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x +449x + +62x + + +62x +62x + + +62x + + +62x + + + + + + + + + + +62x +62x + + +62x + +62x + +62x +62x +62x + +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x +62x + + +62x +62x + + +62x + + + + + + + + + + +62x + + + +62x +62x + +63x +63x +63x +63x +63x +63x +63x +63x +63x +63x + + + + + + +63x +63x +63x +63x +63x + +62x + + + + +62x + + +62x +62x + + +62x + + +62x +62x +62x + + +62x + + + + +62x +62x +62x + + +62x + + + +62x +62x + + +62x + + +62x + + + + + +62x + +114x +114x +114x +114x +114x +114x +114x +114x + +62x + + +62x + + +62x + + + + +62x + +38x +38x +38x +38x +38x +38x +38x + + + +62x + + + + + + + + + + + +18x +18x +4x +1x + + + + + + + + +17x +17x +1x +1x + + + + + + +16x +16x +1x +1x + + + + + + +15x +15x +1x +1x + + + + + + +14x +14x +1x +1x + + + + + + +13x +13x +1x +1x + + + + + + + + + + +12x +12x +1x +1x + + + + + + + + +11x +11x +1x +1x + + + + + + + + + +10x +10x +1x +1x + + + + + + + + +9x +9x +1x +1x + + + + + + + + +8x +8x +1x + + + +7x +7x + + + + +7x +2x + + + + +5x + + + + +55x +1x + +54x +1x + + +53x + +1x + +1x + +4x + +1x + +1x + +1x + +44x +4x + +40x + + + +62x + + + +62x + +4x + + + + + +2x + +2x + + +15x + + + + +13x + +2x + +62x + + + + + + + +1x + +1x + + + +1x + +1x + + + +2x +2x +1x + + + + +1x + + +1x +1x + + +1x +1x + + +1x + + + + + + + + + + + + +1x + +1x + + + +1x + +1x + + + +2x +2x +1x + + +1x +1x + + +1x + + + + + + + + +10x + + +10x +10x + +10x + + + + + +19x +19x +19x + + + +19x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +8x +8x + + +8x + + + + + + +30x + +30x +5x + +5x + + +25x + + +1x + +1x + + + + +24x +24x +1x + +1x + + +23x + +23x + + + +11x +11x + + +7x + +7x + +11x + + + + + + + + + +3x + +3x +3x + + + +1x +1x + + + +1x +1x + +23x + +11x + +11x +11x + +11x + + + + + + + + + + + + + + + + + + + + + + + + + +12x + + + + + + +12x +12x + +8x + + +8x +8x +8x + + +8x +8x + +62x +62x + + + + + + + +62x +62x + + | const { + apply: ReflectApply, + defineProperty: ReflectDefineProperty, + deleteProperty: ReflectDeleteProperty, + getPrototypeOf: ReflectGetPrototypeOf, + ownKeys: ReflectOwnKeys, + setPrototypeOf: ReflectSetPrototypeOf +} = Reflect; +const ObjectCtor = Object; +const { + assign: ObjectAssign, + freeze: ObjectFreeze, + keys: ObjectKeys, + prototype: ObjectProto +} = ObjectCtor; +const { + hasOwn: OriginalObjectHasOwn +} = ObjectCtor; +const { + __lookupGetter__: ObjectProtoLookupGetter, + __lookupSetter__: ObjectProtoLookupSetter, + hasOwnProperty: ObjectProtoHasOwnProperty +} = ObjectProto; +const ObjectHasOwn = typeof OriginalObjectHasOwn === 'function' ? OriginalObjectHasOwn : /* istanbul ignore next: currently unreachable via tests */function ObjectHasOwn(object, key) { + return ReflectApply(ObjectProtoHasOwnProperty, object, [key]); +}; +const { + toString: ObjectProtoToString +} = ObjectProto; +function isObject(value) { + return typeof value === 'object' && value !== null; +} +function ObjectLookupOwnGetter(object, key) { + return object === null || object === undefined || !ObjectHasOwn(object, key) ? undefined : ReflectApply(ObjectProtoLookupGetter, object, [key]); +} +function ObjectLookupOwnSetter(object, key) { + return object === null || object === undefined || !ObjectHasOwn(object, key) ? undefined : ReflectApply(ObjectProtoLookupSetter, object, [key]); +} +const SymbolCtor = Symbol; +const { + for: SymbolFor, + iterator: SymbolIterator, + toStringTag: SymbolToStringTag, + unscopables: SymbolUnscopables +} = SymbolCtor; +const { + valueOf: SymbolProtoValueOf +} = SymbolCtor.prototype; +const ArrayCtor = Array; +const { + prototype: ArrayProto +} = ArrayCtor; +const { + at: ArrayProtoAt, + concat: ArrayProtoConcat, + copyWithin: ArrayProtoCopyWithin, + entries: ArrayProtoEntries, + every: ArrayProtoEvery, + fill: ArrayProtoFill, + findIndex: ArrayProtoFindIndex, + flat: ArrayProtoFlat, + flatMap: ArrayProtoFlatMap, + forEach: ArrayProtoForEach, + join: ArrayProtoJoin, + keys: ArrayProtoKeys, + lastIndexOf: ArrayProtoLastIndexOf, + pop: ArrayProtoPop, + reduce: ArrayProtoReduce, + reduceRight: ArrayProtoReduceRight, + reverse: ArrayProtoReverse, + slice: ArrayProtoSlice, + some: ArrayProtoSome, + toLocaleString: ArrayProtoToLocaleString, + toString: ArrayProtoToString, + values: ArrayProtoValues, + [SymbolIterator]: ArrayProtoSymbolIterator +} = ArrayProto; +const ArrayUnscopables = ObjectFreeze(ObjectAssign({ + __proto__: null +}, ArrayProto[SymbolUnscopables])); +const { + filter: ArrayProtoFilter, + find: ArrayProtoFind, + includes: ArrayProtoIncludes, + indexOf: ArrayProtoIndexOf, + map: ArrayProtoMap, + push: ArrayProtoPush, + shift: ArrayProtoShift, + splice: ArrayProtoSplice, + sort: ArrayProtoSort, + unshift: ArrayProtoUnshift +} = ArrayProto; +const { + isArray: ArrayIsArray +} = ArrayCtor; +function toSafeArray(array) { + ReflectSetPrototypeOf(array, null); + array.at = ArrayProtoAt; + array.concat = ArrayProtoConcat; + // *** DO NOT SET THE ARRAY CONSTRUCTOR PROPERTY *** + // https://bugs.chromium.org/p/v8/issues/detail?id=13202 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/lookup.cc;l=196-215?q=IsArraySpeciesLookupChainIntact + // + // In V8 setting the constructor property of an array, promise, regexp, or + // typed array triggers a de-opt because it could change an instance's + // @@species. This de-opt affects at least `Array#splice` and occurs even + // if the prototype of the array is change or nulled beforehand. Further, + // the de-opt persists after a page refresh. It is not until navigating to + // a different page that the performance of `Array#splice` is restored. + array.copyWithin = ArrayProtoCopyWithin; + array.entries = ArrayProtoEntries; + array.every = ArrayProtoEvery; + array.fill = ArrayProtoFill; + array.filter = ArrayProtoFilter; + array.find = ArrayProtoFind; + array.findIndex = ArrayProtoFindIndex; + array.flat = ArrayProtoFlat; + array.flatMap = ArrayProtoFlatMap; + array.forEach = ArrayProtoForEach; + array.includes = ArrayProtoIncludes; + array.indexOf = ArrayProtoIndexOf; + array.join = ArrayProtoJoin; + array.keys = ArrayProtoKeys; + array.lastIndexOf = ArrayProtoLastIndexOf; + array.map = ArrayProtoMap; + array.pop = ArrayProtoPop; + array.push = ArrayProtoPush; + array.reduce = ArrayProtoReduce; + array.reduceRight = ArrayProtoReduceRight; + array.reverse = ArrayProtoReverse; + array.shift = ArrayProtoShift; + array.slice = ArrayProtoSlice; + array.some = ArrayProtoSome; + array.sort = ArrayProtoSort; + array.splice = ArrayProtoSplice; + array.toLocaleString = ArrayProtoToLocaleString; + array.toString = ArrayProtoToString; + array.unshift = ArrayProtoUnshift; + array.values = ArrayProtoValues; + array[SymbolIterator] = ArrayProtoSymbolIterator; + array[SymbolUnscopables] = ArrayUnscopables; + ReflectSetPrototypeOf(array, ArrayProto); + return array; +} +const ArrayBufferProtoByteLengthGetter = ObjectLookupOwnGetter(ArrayBuffer.prototype, 'byteLength'); + +// https://caniuse.com/bigint +const SUPPORTS_BIG_INT = typeof BigInt === 'function'; +const BigIntProtoValueOf = SUPPORTS_BIG_INT ? BigInt.prototype.valueOf : /* istanbul ignore next: currently unreachable via tests */undefined; +const { + valueOf: BooleanProtoValueOf +} = Boolean.prototype; + +// Locker build constants. +const LOCKER_IDENTIFIER_MARKER = '$LWS'; +// This package is bundled by third-parties that have their own build time +// replacement logic. Instead of customizing each build system to be aware +// of this package we implement a two phase debug mode by performing small +// runtime checks to determine phase one, our code is unminified, and +// phase two, the user opted-in to custom devtools formatters. Phase one +// is used for light weight initialization time debug while phase two is +// reserved for post initialization runtime +const LOCKER_UNMINIFIED_FLAG = +// eslint-disable-next-line @typescript-eslint/naming-convention +/* istanbul ignore next */ +`${function LOCKER_UNMINIFIED_FLAG() { + return LOCKER_UNMINIFIED_FLAG.name; +}()}`.includes('LOCKER_UNMINIFIED_FLAG'); +// Character constants. +const CHAR_ELLIPSIS = '\u2026'; +// Error message constants. +const ERR_ILLEGAL_PROPERTY_ACCESS = 'Illegal property access.'; +// Near-membrane constants. +const LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL = SymbolFor('@@lockerNearMembraneSerializedValue'); +const LOCKER_NEAR_MEMBRANE_SYMBOL = SymbolFor('@@lockerNearMembrane'); +const SYMBOL_LIVE_OBJECT = SymbolFor('@@lockerLiveValue'); +// Object brand constants. +const TO_STRING_BRAND_ARRAY = '[object Array]'; +const TO_STRING_BRAND_ARRAY_BUFFER = '[object ArrayBuffer]'; +const TO_STRING_BRAND_BIG_INT = '[object BigInt]'; +const TO_STRING_BRAND_BOOLEAN = '[object Boolean]'; +const TO_STRING_BRAND_DATE = '[object Date]'; +const TO_STRING_BRAND_FUNCTION = '[object Function]'; +const TO_STRING_BRAND_MAP = '[object Map]'; +const TO_STRING_BRAND_NULL = '[object Null]'; +const TO_STRING_BRAND_NUMBER = '[object Number]'; +const TO_STRING_BRAND_OBJECT = '[object Object]'; +const TO_STRING_BRAND_REG_EXP = '[object RegExp]'; +const TO_STRING_BRAND_SET = '[object Set]'; +const TO_STRING_BRAND_STRING = '[object String]'; +const TO_STRING_BRAND_SYMBOL = '[object Symbol]'; +const TO_STRING_BRAND_UNDEFINED = '[object Undefined]'; +const TO_STRING_BRAND_WEAK_MAP = '[object WeakMap]'; +const TO_STRING_BRAND_WEAK_SET = '[object WeakSet]'; +const { + valueOf: DateProtoValueOf +} = Date.prototype; +const MapCtor = Map; +const { + prototype: MapProto +} = MapCtor; +const { + clear: MapProtoClear, + delete: MapProtoDelete, + forEach: MapProtoForEach, + get: MapProtoGet, + has: MapProtoHas, + keys: MapProtoKeys, + values: MapProtoValues, + [SymbolIterator]: MapProtoSymbolIterator, + [SymbolToStringTag]: MapProtoSymbolToStringTag +} = MapProto; +const { + entries: MapProtoEntries, + set: MapProtoSet +} = MapProto; +const MapProtoSizeGetter = ObjectLookupOwnGetter(MapProto, 'size'); +function toSafeMap(map) { + ReflectSetPrototypeOf(map, null); + map.clear = MapProtoClear; + map.delete = MapProtoDelete; + map.entries = MapProtoEntries; + map.forEach = MapProtoForEach; + map.get = MapProtoGet; + map.has = MapProtoHas; + map.keys = MapProtoKeys; + map.set = MapProtoSet; + ReflectDefineProperty(map, 'size', { + __proto__: null, + configurable: true, + enumerable: true, + get: MapProtoSizeGetter, + set: undefined + }); + map.values = MapProtoValues; + map[SymbolIterator] = MapProtoSymbolIterator; + map[SymbolToStringTag] = MapProtoSymbolToStringTag; + ReflectSetPrototypeOf(map, MapProto); + return map; +} +const NumberCtor = Number; +const { + isFinite: NumberIsFinite, + isInteger: NumberIsInteger, + isNaN: NumberIsNaN +} = NumberCtor; +const { + valueOf: NumberProtoValueOf +} = NumberCtor.prototype; +const RegExpCtor = RegExp; +const { + prototype: RegExpProto +} = RegExpCtor; +const { + test: RegExpProtoTest +} = RegExpProto; +const RegExpProtoSourceGetter = ObjectLookupOwnGetter(RegExpProto, 'source'); +const SetCtor = Set; +const { + prototype: SetProto +} = SetCtor; +const { + add: SetProtoAdd, + has: SetProtoHas, + values: SetProtoValues +} = SetProto; +const SetProtoSizeGetter = ObjectLookupOwnGetter(SetProto, 'size'); +const StringCtor = String; +const { + prototype: StringProto +} = StringCtor; +const { + slice: StringProtoSlice, + valueOf: StringProtoValueOf +} = StringProto; +const WeakMapCtor = WeakMap; +const { + prototype: WeakMapProto +} = WeakMapCtor; +const { + has: WeakMapProtoHas +} = WeakMapProto; +const { + delete: WeakMapProtoDelete, + get: WeakMapProtoGet, + set: WeakMapProtoSet, + [SymbolToStringTag]: WeakMapProtoSymbolToStringTag +} = WeakMapProto; +function toSafeWeakMap(weakMap) { + ReflectSetPrototypeOf(weakMap, null); + weakMap.delete = WeakMapProtoDelete; + weakMap.get = WeakMapProtoGet; + weakMap.has = WeakMapProtoHas; + weakMap.set = WeakMapProtoSet; + weakMap[SymbolToStringTag] = WeakMapProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakMap, WeakMapProto); + return weakMap; +} +const WeakSetCtor = WeakSet; +const { + prototype: WeakSetProto +} = WeakSetCtor; +const { + has: WeakSetProtoHas +} = WeakSetProto; +const { + add: WeakSetProtoAdd, + delete: WeakSetProtoDelete, + [SymbolToStringTag]: WeakSetProtoSymbolToStringTag +} = WeakSetProto; +function toSafeWeakSet(weakSet) { + ReflectSetPrototypeOf(weakSet, null); + weakSet.add = WeakSetProtoAdd; + weakSet.delete = WeakSetProtoDelete; + weakSet.has = WeakSetProtoHas; + weakSet[SymbolToStringTag] = WeakSetProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakSet, WeakSetProto); + return weakSet; +} +const { + toStringTag: TO_STRING_TAG_SYMBOL +} = Symbol; +function getBrandByTrialAndError(value) { + // Trail and error attempts are performed in order of most likely, + // e.g. those values that have a @@toStringTag defined by default, + // to least likely. + // + // Internally these brand checks rely on native methods that throw and catch + // an exception when they operate on values with unexpected internal slot + // entries. + // Section 25.1.5.1 get ArrayBuffer.prototype.byteLength + // https://tc39.es/ecma262/#sec-get-arraybuffer.prototype.bytelength + // Step 2: Perform RequireInternalSlot(O, [[ArrayBufferData]]). + try { + if ('byteLength' in value) { + ReflectApply(ArrayBufferProtoByteLengthGetter, value, []); + return TO_STRING_BRAND_ARRAY_BUFFER; + } + // eslint-disable-next-line no-empty + } catch (_unused) {} + // Section 21.4.4 Properties of the Date Prototype Object + // https://tc39.es/ecma262/#thistimevalue + // Step 1: If Type(value) is Object and value has a [[DateValue]] internal slot, then + // a. Return value.[[DateValue]]. + // Step 2: Throw a TypeError exception. + try { + if ('toLocaleDateString' in value) { + ReflectApply(DateProtoValueOf, value, []); + return TO_STRING_BRAND_DATE; + } + // eslint-disable-next-line no-empty + } catch (_unused2) {} + // Section 24.1.3.10 get Map.prototype.size + // https://tc39.es/ecma262/#sec-get-map.prototype.size + // Step 2: Perform ? RequireInternalSlot(M, [[MapData]]). + try { + if ('get' in value && 'size' in value) { + ReflectApply(MapProtoSizeGetter, value, []); + return TO_STRING_BRAND_MAP; + } + // eslint-disable-next-line no-empty + } catch (_unused3) {} + // Section 24.2.3.9 get Set.prototype.size + // https://tc39.es/ecma262/#sec-get-set.prototype.size + // Step 2: Perform ? RequireInternalSlot(S, [[SetData]]). + try { + if ('add' in value && 'size' in value) { + ReflectApply(SetProtoSizeGetter, value, []); + return TO_STRING_BRAND_SET; + } + // eslint-disable-next-line no-empty + } catch (_unused4) {} + // Section 24.3.3.4 WeakMap.prototype.has ( key ) + // https://tc39.es/ecma262/#sec-weakmap.prototype.has + // Step 2: Perform RequireInternalSlot(M, [[WeakMapData]]). + try { + if ('get' in value && !('size' in value)) { + ReflectApply(WeakMapProtoHas, value, []); + return TO_STRING_BRAND_WEAK_MAP; + } + // eslint-disable-next-line no-empty + } catch (_unused5) {} + // Section 24.4.3.4 WeakSet.prototype.has ( value ) + // https://tc39.es/ecma262/#sec-weakset.prototype.has + // Step 2: 2. Perform RequireInternalSlot(S, [[WeakSetData]]). + try { + if ('add' in value && !('size' in value)) { + ReflectApply(WeakSetProtoHas, value, []); + return TO_STRING_BRAND_WEAK_SET; + } + // eslint-disable-next-line no-empty + } catch (_unused6) {} + // The following checks are for the rare occurrence of object, i.e. boxed, + // primitive values or those objects without a default @@toStringTag. + // Section 21.1.3 Properties of the Number Prototype Object + // https://tc39.es/ecma262/#thisnumbervalue + // Step 2: If Type(value) is Object and value has a [[NumberData]] internal slot, then + // a. Let n be value.[[NumberData]]. + // b. Assert: Type(n) is Number. + try { + if ('toPrecision' in value) { + ReflectApply(NumberProtoValueOf, value, []); + return TO_STRING_BRAND_NUMBER; + } + // eslint-disable-next-line no-empty + } catch (_unused7) {} + // Section 20.4.3 Properties of the Symbol Prototype Object + // https://tc39.es/ecma262/#thissymbolvalue + // Step 2: If Type(value) is Object and value has a [[SymbolData]] internal slot, then + // a. Let s be value.[[SymbolData]]. + // b. Assert: Type(s) is Symbol. + try { + if ('description' in value) { + ReflectApply(SymbolProtoValueOf, value, []); + return TO_STRING_BRAND_SYMBOL; + } + // eslint-disable-next-line no-empty + } catch (_unused8) {} + // Perform heavier checks last. + // Section 22.2.6.13 get RegExp.prototype.source + // https://tc39.es/ecma262/#sec-get-regexp.prototype.source + // Step 3: If R does not have an [[OriginalSource]] internal slot, then + // a. If SameValue(R, %RegExp.prototype%) is true, return "(?:)". + // b. Otherwise, throw a TypeError exception. + try { + if (ObjectHasOwn(value, 'lastIndex')) { + ReflectApply(RegExpProtoSourceGetter, value, []); + return TO_STRING_BRAND_REG_EXP; + } + // eslint-disable-next-line no-empty + } catch (_unused9) {} + // Section 22.1.3 Properties of the String Prototype Object + // https://tc39.es/ecma262/#thisstringvalue + // Step 2: If Type(value) is Object and value has a [[StringData]] internal slot, then + // a. Let s be value.[[StringData]]. + // b. Assert: Type(s) is String. + try { + if (ObjectHasOwn(value, 'length')) { + ReflectApply(StringProtoValueOf, value, []); + return TO_STRING_BRAND_STRING; + } + // eslint-disable-next-line no-empty + } catch (_unused10) {} + // Section 20.3.3 Properties of the Boolean Prototype Object + // https://tc39.es/ecma262/#thisbooleanvalue + // Step 2: If Type(value) is Object and value has a [[BooleanData]] internal slot, then + // a. Let b be value.[[BooleanData]]. + // b. Assert: Type(b) is Boolean. + try { + ReflectApply(BooleanProtoValueOf, value, []); + return TO_STRING_BRAND_BOOLEAN; + // eslint-disable-next-line no-empty + } catch (_unused11) {} + // istanbul ignore else: all platforms that LWS runs tests in support BigInt + if (SUPPORTS_BIG_INT) { + try { + // Section 21.2.3 Properties of the BigInt Prototype Object + // https://tc39.es/ecma262/#thisbigintvalue + // Step 2: If Type(value) is Object and value has a [[BigIntData]] internal slot, then + // a. Assert: Type(value.[[BigIntData]]) is BigInt. + ReflectApply(BigIntProtoValueOf, value, []); + return TO_STRING_BRAND_BIG_INT; + // eslint-disable-next-line no-empty + } catch (_unused12) {} + } + // Cannot detect brands for Arguments and Error objects. + return TO_STRING_BRAND_OBJECT; +} +function getBrand(value) { + // Section 20.1.3.6 Object.prototype.toString ( ) + // https://tc39.es/ecma262/#sec-object.prototype.tostring + if (value === null) { + return TO_STRING_BRAND_NULL; + } + if (value === undefined) { + return TO_STRING_BRAND_UNDEFINED; + } + // eslint-disable-next-line default-case + switch (typeof value) { + case 'bigint': + return TO_STRING_BRAND_BIG_INT; + case 'boolean': + return TO_STRING_BRAND_BOOLEAN; + case 'function': + return TO_STRING_BRAND_FUNCTION; + case 'number': + return TO_STRING_BRAND_NUMBER; + case 'string': + return TO_STRING_BRAND_STRING; + case 'symbol': + return TO_STRING_BRAND_SYMBOL; + } + if (ArrayIsArray(value)) { + return TO_STRING_BRAND_ARRAY; + } + return TO_STRING_TAG_SYMBOL in value ? getBrandByTrialAndError(value) : ReflectApply(ObjectProtoToString, value, []); +} +const { + parse: JSONParse +} = JSON; +// Used by '@locker/near-membrane-dom'. +const { + stringify: JSONStringify +} = JSON; +function getNearMembraneProxySerializedValue(object) { + if (typeof object === 'object' && object !== null || typeof object === 'function') { + // To extract the serialized value of a blue near-membrane proxy we must + // perform a two step handshake. First, we trigger the "has" trap for + // the `LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL` property which + // must report `false`. Second, we trigger the "get" trap to return the + // serialized value. + return LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL in object ? undefined : object[LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL]; + } + return undefined; +} +function isNearMembraneProxy(value) { + if (typeof value === 'object' && value !== null || typeof value === 'function') { + // To extract the flag value of a blue near-membrane proxy we must + // perform a two step handshake. First, we trigger the "has" trap for + // the `LOCKER_NEAR_MEMBRANE_SYMBOL` property which must report `false`. + // Second, we trigger the "get" trap to return the flag value. + return !(LOCKER_NEAR_MEMBRANE_SYMBOL in value) && value[LOCKER_NEAR_MEMBRANE_SYMBOL] === true; + } + return false; +} +const SEEN_OBJECTS = toSafeMap(new MapCtor()); +function cloneBoxedPrimitive(object) { + return ObjectCtor(getNearMembraneProxySerializedValue(object)); +} +function cloneMap(map, queue) { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // Step 26.1.1: Let copiedList be a new empty List. + const clone = new MapCtor(); + // Step 26.1.2: For each Record { [[Key]], [[Value]] } entry of value.[[MapData]]... + const entriesIterable = ReflectApply(MapProtoEntries, map, []); + // Step 26.1.3 For each Record { [[Key]], [[Value]] } entry of copiedList: + let { + length: queueOffset + } = queue; + // eslint-disable-next-line no-constant-condition + while (true) { + const { + done, + value: subKeyValuePair + } = entriesIterable.next(); + if (done) { + break; + } + const { + 0: subKey, + 1: subValue + } = subKeyValuePair; + let subCloneKey; + // Step 26.1.3.1: Let serializedKey be ? StructuredSerializeInternal(entry.[[Key]], forStorage, memory). + queue[queueOffset++] = [subClone => { + subCloneKey = subClone; + }, subKey]; + // Step 26.1.3.2: Let serializedValue be ? StructuredSerializeInternal(entry.[[Value]], forStorage, memory). + queue[queueOffset++] = [subCloneValue => { + ReflectApply(MapProtoSet, clone, [subCloneKey, subCloneValue]); + }, subValue]; + } + return clone; +} +function cloneRegExp(regexp) { + const { + flags, + source + } = JSONParse(getNearMembraneProxySerializedValue(regexp)); + return new RegExpCtor(source, flags); +} +function cloneSet(set, queue) { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // Step 26.2.1: Let copiedList be a new empty List. + const clone = new SetCtor(); + // Step 26.2.2: For each entry of value.[[SetData]]... + const valuesIterable = ReflectApply(SetProtoValues, set, []); + // Step 26.2.3: For each entry of copiedList: + let { + length: queueOffset + } = queue; + // eslint-disable-next-line no-constant-condition + while (true) { + const { + done, + value: subValue + } = valuesIterable.next(); + if (done) { + break; + } + // Step 26.2.3.1: Let serializedEntry be ? StructuredSerializeInternal(entry, forStorage, memory). + queue[queueOffset++] = [subCloneValue => { + ReflectApply(SetProtoAdd, clone, [subCloneValue]); + }, subValue]; + } + return clone; +} +function enqueue(queue, originalValue, cloneValue) { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // Step 26.4: Otherwise, for each key in ! EnumerableOwnPropertyNames(value, key)... + // Note: Object.keys() performs EnumerableOwnPropertyNames() internally as + // defined in ECMA262: + // https://tc39.es/ecma262/#sec-object.keys + const keys = ObjectKeys(originalValue); + let { + length: queueOffset + } = queue; + for (let i = 0, { + length + } = keys; i < length; i += 1) { + // Step 26.4.1.1: Let inputValue be ? value.[[Get]](key, value). + // The [[Get]] operation is defined in ECMA262 for ordinary objects, + // argument objects, integer-indexed exotic objects, module namespace + // objects, and proxy objects. + // https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-get-p-receiver + const key = keys[i]; + const subValue = originalValue[key]; + queue[queueOffset++] = [subCloneValue => { + // Step 26.4.1.3: Property descriptor attributes are not + // preserved during deserialization because only keys and + // values are captured in serialized.[[Properties]]. + cloneValue[key] = subCloneValue; + }, subValue]; + } +} +// This function is the unguarded internal variant of `partialStructuredClone()`. +// Any error thrown that is captured by `partialStructuredClone()` is treated as +// a `DataCloneError`. This function clones blue membrane proxied arrays, plain +// objects, maps, regexps, sets, and boxed primitives. The following non-membrane +// proxied objects are set by reference instead of cloning: +// ArrayBuffer +// BigInt64Array +// BigUint64Array +// Blob +// DataView +// Date +// DOMException +// DOMMatrix +// DOMMatrixReadOnly +// DOMPoint +// DOMPointReadOnly +// DOMQuad +// DOMRect +// DOMRectReadOnly +// Error +// EvalError +// File +// FileList +// Float32Array +// Float64Array +// ImageBitMap +// ImageData +// Int8Array +// Int16Array +// Int32Array +// RangeError +// ReferenceError +// SyntaxError +// TypeError +// Uint8Array +// Uint8ClampedArray +// Uint16Array +// Uint32Array +// URIError +// +// Note: +// This function performs brand checks using `Object.prototype.toString`. The +// results can be faked with `Symbol.toStringTag` property values and are a poor +// substitute for native internal slot checks. However, for our purposes they +// are perfectly fine and avoid having to repeatedly walk the prototype of proxied +// values. Cloned values should be passed to native methods, like `postMessage()`, +// which perform their own validation with internal slot checks. +function partialStructuredCloneInternal(value) { + // Using a queue instead of recursive function calls avoids call stack limits + // and enables cloning more complex and deeply nested objects. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Too_much_recursion + let result; + const queue = [[subClone => { + result = subClone; + }, value]]; + // eslint-disable-next-line no-labels + queueLoop: while (queue.length) { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // prettier-ignore + const { + 0: setter, + 1: originalValue + } = ReflectApply(ArrayProtoShift, queue, []); + // Step 4: If Type(value) is Undefined, Null, Boolean, Number, BigInt, or String + if (originalValue === null || originalValue === undefined || typeof originalValue === 'boolean' || typeof originalValue === 'number' || typeof originalValue === 'string' || typeof originalValue === 'bigint') { + setter(originalValue); + // eslint-disable-next-line no-continue, no-extra-label, no-labels + continue queueLoop; + } + // Step 5: If Type(value) is Symbol, then throw a 'DataCloneError' DOMException. + if (typeof originalValue === 'symbol') { + // Stop cloning and set the original value and defer throwing to + // native methods. + setter(originalValue); + // eslint-disable-next-line no-extra-label, no-labels + break queueLoop; + } + // To support circular references check if the original value has been + // seen. If it has then use the clone associated with its record instead + // of creating a new clone. + let cloneValue = SEEN_OBJECTS.get(originalValue); + if (cloneValue) { + setter(cloneValue); + // eslint-disable-next-line no-continue, no-extra-label, no-labels + continue queueLoop; + } + // Perform a brand check on originalValue. + const brand = getBrand(originalValue); + // eslint-disable-next-line default-case + switch (brand) { + // Step 19: Otherwise, if value is a platform object... + case TO_STRING_BRAND_OBJECT: + { + const proto = ReflectGetPrototypeOf(originalValue); + if (proto === ObjectProto || proto === null || + // Possible `Object.prototype` from another document. + ReflectGetPrototypeOf(proto) === null) { + cloneValue = {}; + // Step 19.4: Set deep to true. + enqueue(queue, originalValue, cloneValue); + } + break; + } + // Step 18: Otherwise, if value is an Array exotic object... + case TO_STRING_BRAND_ARRAY: + // Step 18.1 Let valueLenDescriptor be ? OrdinaryGetOwnProperty(value, 'length'). + // Note: Rather than perform the more complex OrdinaryGetOwnProperty() + // operation for 'length' because it is a non-configurable property + // we can access it with the simpler [[Get]]() operation defined + // in ECMA262. + // https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-get-p-receiver + cloneValue = ArrayCtor(originalValue.length); + // Step 18.4: Set deep to true. + enqueue(queue, originalValue, cloneValue); + break; + // Step 15: Otherwise, if value has [[MapData]] internal slot... + // Step 15.2: Set deep to true. + case TO_STRING_BRAND_MAP: + cloneValue = cloneMap(originalValue, queue); + break; + // Step 16: Otherwise, if value has [[SetData]] internal slot... + // Step 16.2: Set deep to true. + case TO_STRING_BRAND_SET: + cloneValue = cloneSet(originalValue, queue); + break; + } + if (cloneValue === undefined) { + // istanbul ignore else + if (!isNearMembraneProxy(originalValue)) { + // Skip cloning non-membrane proxied objects. + SEEN_OBJECTS.set(originalValue, originalValue); + setter(originalValue); + // eslint-disable-next-line no-extra-label, no-labels + continue queueLoop; + } + // Cases ordered by a guestimate on frequency of encounter. + // eslint-disable-next-line default-case + switch (brand) { + // Step 12: Otherwise, if value has a [[RegExpMatcher]] internal slot... + case TO_STRING_BRAND_REG_EXP: + cloneValue = cloneRegExp(originalValue); + break; + // Step 7: If value has a [[BooleanData]] internal slot... + case TO_STRING_BRAND_BOOLEAN: + // Step 8: Otherwise, if value has a [[NumberData]] internal slot... + // eslint-disable-next-line no-fallthrough + case TO_STRING_BRAND_NUMBER: + // Step 9: Otherwise, if value has a [[BigIntData]] internal slot... + // eslint-disable-next-line no-fallthrough + case TO_STRING_BRAND_BIG_INT: + // Step 10: Otherwise, if value has a [[StringData]] internal slot... + // eslint-disable-next-line no-fallthrough + case TO_STRING_BRAND_STRING: + cloneValue = cloneBoxedPrimitive(originalValue); + break; + } + } + // Step 21: Otherwise, if IsCallable(value) is true, then throw a 'DataCloneError' + // Step 20: Otherwise, if value is a platform object, then throw a 'DataCloneError' + if (cloneValue === undefined) { + // Stop cloning and set the original value and defer throwing to + // native methods. + setter(originalValue); + // eslint-disable-next-line no-extra-label, no-labels + break queueLoop; + } + SEEN_OBJECTS.set(originalValue, cloneValue); + setter(cloneValue); + } + return result; +} +function partialStructuredClone(value) { + let result = value; + try { + result = partialStructuredCloneInternal(value); + // eslint-disable-next-line no-empty + } catch (_unused13) {} + SEEN_OBJECTS.clear(); + return result; +} +const ErrorCtor = Error; +const TypeErrorCtor = TypeError; +function noop() { + // No operation performed. +} + +// Used by '@locker/near-membrane-dom'. +const { + min: MathMin +} = Math; +const ProxyCtor = Proxy; +export { ArrayBufferProtoByteLengthGetter, ArrayCtor, ArrayIsArray, ArrayProtoFilter, ArrayProtoFind, ArrayProtoIncludes, ArrayProtoIndexOf, ArrayProtoMap, ArrayProtoPush, ArrayProtoShift, ArrayProtoSort, ArrayProtoSplice, ArrayProtoUnshift, BigIntProtoValueOf, BooleanProtoValueOf, CHAR_ELLIPSIS, DateProtoValueOf, ERR_ILLEGAL_PROPERTY_ACCESS, ErrorCtor, JSONParse, JSONStringify, LOCKER_IDENTIFIER_MARKER, LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL, LOCKER_NEAR_MEMBRANE_SYMBOL, LOCKER_UNMINIFIED_FLAG, MapCtor, MapProtoEntries, MapProtoSet, MapProtoSizeGetter, MathMin, NumberCtor, NumberIsFinite, NumberIsInteger, NumberIsNaN, NumberProtoValueOf, ObjectAssign, ObjectCtor, ObjectFreeze, ObjectHasOwn, ObjectKeys, ObjectLookupOwnGetter, ObjectLookupOwnSetter, ObjectProto, ObjectProtoToString, ProxyCtor, ReflectApply, ReflectDefineProperty, ReflectDeleteProperty, ReflectGetPrototypeOf, ReflectOwnKeys, ReflectSetPrototypeOf, RegExpCtor, RegExpProtoSourceGetter, RegExpProtoTest, SUPPORTS_BIG_INT, SYMBOL_LIVE_OBJECT, SetCtor, SetProtoAdd, SetProtoHas, SetProtoSizeGetter, SetProtoValues, StringCtor, StringProtoSlice, StringProtoValueOf, SymbolFor, SymbolIterator, SymbolProtoValueOf, SymbolToStringTag, SymbolUnscopables, TO_STRING_BRAND_ARRAY, TO_STRING_BRAND_ARRAY_BUFFER, TO_STRING_BRAND_BIG_INT, TO_STRING_BRAND_BOOLEAN, TO_STRING_BRAND_DATE, TO_STRING_BRAND_FUNCTION, TO_STRING_BRAND_MAP, TO_STRING_BRAND_NULL, TO_STRING_BRAND_NUMBER, TO_STRING_BRAND_OBJECT, TO_STRING_BRAND_REG_EXP, TO_STRING_BRAND_SET, TO_STRING_BRAND_STRING, TO_STRING_BRAND_SYMBOL, TO_STRING_BRAND_UNDEFINED, TO_STRING_BRAND_WEAK_MAP, TO_STRING_BRAND_WEAK_SET, TypeErrorCtor, WeakMapCtor, WeakMapProtoHas, WeakSetCtor, WeakSetProtoHas, getBrand, getNearMembraneProxySerializedValue, isNearMembraneProxy, isObject, noop, partialStructuredClone, toSafeArray, toSafeMap, toSafeWeakMap, toSafeWeakSet }; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 | + + + +14x + +14x + + + + + + + + + + + + + + + + + + + + + + + + + +14x + +14x + + + + + + + + + + + + + + +14x + +14x + + +39x +39x +39x + + + + + + + + + + +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x +39x + + | import { ObjectAssign, ObjectFreeze } from './Object'; +import { ReflectSetPrototypeOf } from './Reflect'; +import { SymbolIterator, SymbolUnscopables } from './Symbol'; + +export const ArrayCtor = Array; + +const { prototype: ArrayProto } = ArrayCtor; + +const { + at: ArrayProtoAt, + concat: ArrayProtoConcat, + copyWithin: ArrayProtoCopyWithin, + entries: ArrayProtoEntries, + every: ArrayProtoEvery, + fill: ArrayProtoFill, + findIndex: ArrayProtoFindIndex, + flat: ArrayProtoFlat, + flatMap: ArrayProtoFlatMap, + forEach: ArrayProtoForEach, + join: ArrayProtoJoin, + keys: ArrayProtoKeys, + lastIndexOf: ArrayProtoLastIndexOf, + pop: ArrayProtoPop, + reduce: ArrayProtoReduce, + reduceRight: ArrayProtoReduceRight, + reverse: ArrayProtoReverse, + slice: ArrayProtoSlice, + some: ArrayProtoSome, + toLocaleString: ArrayProtoToLocaleString, + toString: ArrayProtoToString, + values: ArrayProtoValues, + [SymbolIterator as any]: ArrayProtoSymbolIterator, +} = ArrayProto; + +const ArrayUnscopables = ObjectFreeze( + ObjectAssign({ __proto__: null }, ArrayProto[SymbolUnscopables as any]) +); + +export const { + filter: ArrayProtoFilter, + find: ArrayProtoFind, + includes: ArrayProtoIncludes, + indexOf: ArrayProtoIndexOf, + map: ArrayProtoMap, + push: ArrayProtoPush, + shift: ArrayProtoShift, + splice: ArrayProtoSplice, + sort: ArrayProtoSort, + unshift: ArrayProtoUnshift, +} = ArrayProto; + +export const { isArray: ArrayIsArray } = ArrayCtor; + +export function toSafeArray<T extends any[]>(array: T): T { + ReflectSetPrototypeOf(array, null); + array.at = ArrayProtoAt; + array.concat = ArrayProtoConcat; + // *** DO NOT SET THE ARRAY CONSTRUCTOR PROPERTY *** + // https://bugs.chromium.org/p/v8/issues/detail?id=13202 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/lookup.cc;l=196-215?q=IsArraySpeciesLookupChainIntact + // + // In V8 setting the constructor property of an array, promise, regexp, or + // typed array triggers a de-opt because it could change an instance's + // @@species. This de-opt affects at least `Array#splice` and occurs even + // if the prototype of the array is change or nulled beforehand. Further, + // the de-opt persists after a page refresh. It is not until navigating to + // a different page that the performance of `Array#splice` is restored. + array.copyWithin = ArrayProtoCopyWithin as any; + array.entries = ArrayProtoEntries; + array.every = ArrayProtoEvery; + array.fill = ArrayProtoFill as any; + array.filter = ArrayProtoFilter; + array.find = ArrayProtoFind; + array.findIndex = ArrayProtoFindIndex; + array.flat = ArrayProtoFlat; + array.flatMap = ArrayProtoFlatMap; + array.forEach = ArrayProtoForEach; + array.includes = ArrayProtoIncludes; + array.indexOf = ArrayProtoIndexOf; + array.join = ArrayProtoJoin; + array.keys = ArrayProtoKeys; + array.lastIndexOf = ArrayProtoLastIndexOf; + array.map = ArrayProtoMap; + array.pop = ArrayProtoPop; + array.push = ArrayProtoPush; + array.reduce = ArrayProtoReduce; + array.reduceRight = ArrayProtoReduceRight; + array.reverse = ArrayProtoReverse; + array.shift = ArrayProtoShift; + array.slice = ArrayProtoSlice; + array.some = ArrayProtoSome; + array.sort = ArrayProtoSort as any; + array.splice = ArrayProtoSplice; + array.toLocaleString = ArrayProtoToLocaleString; + array.toString = ArrayProtoToString; + array.unshift = ArrayProtoUnshift; + array.values = ArrayProtoValues; + array[SymbolIterator as any] = ArrayProtoSymbolIterator; + array[SymbolUnscopables as any] = ArrayUnscopables; + ReflectSetPrototypeOf(array, ArrayProto); + return array; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 | + +14x + + + + | import { ObjectLookupOwnGetter } from './Object'; + +export const ArrayBufferProtoByteLengthGetter = ObjectLookupOwnGetter( + ArrayBuffer.prototype, + 'byteLength' +)!; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 | +14x + +14x + + + | // https://caniuse.com/bigint +export const SUPPORTS_BIG_INT = typeof BigInt === 'function'; + +export const BigIntProtoValueOf = SUPPORTS_BIG_INT + ? BigInt.prototype.valueOf + : /* istanbul ignore next: currently unreachable via tests */ undefined; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 | 14x + | export const { valueOf: BooleanProtoValueOf } = Boolean.prototype; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 | 14x + | export const { valueOf: DateProtoValueOf } = Date.prototype; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 | 14x +14x + | export const ErrorCtor = Error; +export const TypeErrorCtor = TypeError; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 | + + + | export function noop() { + // No operation performed. +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 | 14x + + +14x + | export const { parse: JSONParse } = JSON; + +// Used by '@locker/near-membrane-dom'. +export const { stringify: JSONStringify } = JSON; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 | + + + +14x + +14x + + + + + + + + + + + +14x + +14x + +14x + + +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x + + + + + + +14x +14x +14x +14x +14x + + | import { ObjectLookupOwnGetter } from './Object'; +import { ReflectDefineProperty, ReflectSetPrototypeOf } from './Reflect'; +import { SymbolIterator, SymbolToStringTag } from './Symbol'; + +export const MapCtor = Map; + +const { prototype: MapProto } = MapCtor; + +const { + clear: MapProtoClear, + delete: MapProtoDelete, + forEach: MapProtoForEach, + get: MapProtoGet, + has: MapProtoHas, + keys: MapProtoKeys, + values: MapProtoValues, + [SymbolIterator]: MapProtoSymbolIterator, + [SymbolToStringTag]: MapProtoSymbolToStringTag, +} = MapProto as any; + +export const { entries: MapProtoEntries, set: MapProtoSet } = MapProto; + +export const MapProtoSizeGetter = ObjectLookupOwnGetter(MapProto, 'size')!; + +export function toSafeMap<T extends Map<any, any>>(map: T): T { + ReflectSetPrototypeOf(map, null); + map.clear = MapProtoClear; + map.delete = MapProtoDelete; + map.entries = MapProtoEntries; + map.forEach = MapProtoForEach; + map.get = MapProtoGet; + map.has = MapProtoHas; + map.keys = MapProtoKeys; + map.set = MapProtoSet as any; + ReflectDefineProperty(map, 'size', { + __proto__: null, + configurable: true, + enumerable: true, + get: MapProtoSizeGetter, + set: undefined, + } as PropertyDescriptor); + map.values = MapProtoValues; + (map as any)[SymbolIterator] = MapProtoSymbolIterator; + (map as any)[SymbolToStringTag] = MapProtoSymbolToStringTag; + ReflectSetPrototypeOf(map, MapProto); + return map; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 | +14x + | // Used by '@locker/near-membrane-dom'. +export const { min: MathMin } = Math; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | import { + LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL, + LOCKER_NEAR_MEMBRANE_SYMBOL, +} from './constants'; +import type { NearMembraneSerializedValue } from './types'; + +export function getNearMembraneProxySerializedValue(object: object): NearMembraneSerializedValue { + if ((typeof object === 'object' && object !== null) || typeof object === 'function') { + // To extract the serialized value of a blue near-membrane proxy we must + // perform a two step handshake. First, we trigger the "has" trap for + // the `LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL` property which + // must report `false`. Second, we trigger the "get" trap to return the + // serialized value. + return LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL in object + ? undefined + : (object as any)[LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL]; + } + return undefined; +} + +export function isNearMembraneProxy(value: any): boolean { + if ((typeof value === 'object' && value !== null) || typeof value === 'function') { + // To extract the flag value of a blue near-membrane proxy we must + // perform a two step handshake. First, we trigger the "has" trap for + // the `LOCKER_NEAR_MEMBRANE_SYMBOL` property which must report `false`. + // Second, we trigger the "get" trap to return the flag value. + return ( + !(LOCKER_NEAR_MEMBRANE_SYMBOL in value) && + (value as any)[LOCKER_NEAR_MEMBRANE_SYMBOL] === true + ); + } + return false; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 | 14x + + + + + +14x + +14x + | export const NumberCtor = Number; + +export const { + isFinite: NumberIsFinite, + isInteger: NumberIsInteger, + isNaN: NumberIsNaN, +} = NumberCtor; + +export const { valueOf: NumberProtoValueOf } = NumberCtor.prototype; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 | + + +14x + + + + + + +14x + +14x + + + + + +14x + + +14x + + + + + + + + +14x + + + + + + +91x + + + + + + + + + + | import { ReflectApply } from './Reflect'; +import type { Getter, Setter } from './types'; + +export const ObjectCtor = Object; + +export const { + assign: ObjectAssign, + freeze: ObjectFreeze, + keys: ObjectKeys, + prototype: ObjectProto, +} = ObjectCtor; + +const { hasOwn: OriginalObjectHasOwn } = ObjectCtor as any; + +const { + __lookupGetter__: ObjectProtoLookupGetter, + __lookupSetter__: ObjectProtoLookupSetter, + hasOwnProperty: ObjectProtoHasOwnProperty, +} = ObjectProto as any; + +export const ObjectHasOwn: (object: any, key: PropertyKey) => boolean = + typeof OriginalObjectHasOwn === 'function' + ? OriginalObjectHasOwn + : /* istanbul ignore next: currently unreachable via tests */ function ObjectHasOwn( + object: any, + key: PropertyKey + ): boolean { + return ReflectApply(ObjectProtoHasOwnProperty, object, [key]); + }; + +export const { toString: ObjectProtoToString } = ObjectProto; + +export function isObject(value: any): boolean { + return typeof value === 'object' && value !== null; +} + +export function ObjectLookupOwnGetter(object: any, key: PropertyKey): Getter | undefined { + return object === null || object === undefined || !ObjectHasOwn(object, key) + ? undefined + : ReflectApply(ObjectProtoLookupGetter, object, [key]); +} + +export function ObjectLookupOwnSetter(object: any, key: PropertyKey): Setter | undefined { + return object === null || object === undefined || !ObjectHasOwn(object, key) + ? undefined + : ReflectApply(ObjectProtoLookupSetter, object, [key]); +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 | 14x + | export const ProxyCtor = Proxy; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 | + + + + + + +14x + | export const { + apply: ReflectApply, + defineProperty: ReflectDefineProperty, + deleteProperty: ReflectDeleteProperty, + getPrototypeOf: ReflectGetPrototypeOf, + ownKeys: ReflectOwnKeys, + setPrototypeOf: ReflectSetPrototypeOf, +} = Reflect; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 | + +14x + +14x + +14x + +14x + | import { ObjectLookupOwnGetter } from './Object'; + +export const RegExpCtor = RegExp; + +const { prototype: RegExpProto } = RegExpCtor; + +export const { test: RegExpProtoTest } = RegExpProto; + +export const RegExpProtoSourceGetter = ObjectLookupOwnGetter(RegExpProto, 'source')!; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 | + +14x + +14x + +14x + +14x + | import { ObjectLookupOwnGetter } from './Object'; + +export const SetCtor = Set; + +const { prototype: SetProto } = SetCtor; + +export const { add: SetProtoAdd, has: SetProtoHas, values: SetProtoValues } = SetProto; + +export const SetProtoSizeGetter = ObjectLookupOwnGetter(SetProto, 'size')!; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 | 14x + +14x + +14x + | export const StringCtor = String; + +const { prototype: StringProto } = StringCtor; + +export const { slice: StringProtoSlice, valueOf: StringProtoValueOf } = StringProto; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 | 14x + + + + + + +14x + +14x + | const SymbolCtor = Symbol; + +export const { + for: SymbolFor, + iterator: SymbolIterator, + toStringTag: SymbolToStringTag, + unscopables: SymbolUnscopables, +} = SymbolCtor; + +export const { valueOf: SymbolProtoValueOf } = SymbolCtor.prototype; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 | + + +14x + +14x + +14x + + + + + + +14x + + +11x +11x +11x +11x +11x +11x +11x +11x + + | import { ReflectSetPrototypeOf } from './Reflect'; +import { SymbolToStringTag } from './Symbol'; + +export const WeakMapCtor = WeakMap; + +const { prototype: WeakMapProto } = WeakMapCtor; + +export const { has: WeakMapProtoHas } = WeakMapProto; + +const { + delete: WeakMapProtoDelete, + get: WeakMapProtoGet, + set: WeakMapProtoSet, + [SymbolToStringTag]: WeakMapProtoSymbolToStringTag, +} = WeakMapProto as any; + +export function toSafeWeakMap<T extends WeakMap<any, any>>(weakMap: T): T { + ReflectSetPrototypeOf(weakMap, null); + weakMap.delete = WeakMapProtoDelete; + weakMap.get = WeakMapProtoGet; + weakMap.has = WeakMapProtoHas; + weakMap.set = WeakMapProtoSet; + (weakMap as any)[SymbolToStringTag] = WeakMapProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakMap, WeakMapProto); + return weakMap; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 | + + +14x + +14x + +14x + + + + + +14x + + + + + + + + + + + | import { ReflectSetPrototypeOf } from './Reflect'; +import { SymbolToStringTag } from './Symbol'; + +export const WeakSetCtor = WeakSet; + +const { prototype: WeakSetProto } = WeakSetCtor; + +export const { has: WeakSetProtoHas } = WeakSetProto; + +const { + add: WeakSetProtoAdd, + delete: WeakSetProtoDelete, + [SymbolToStringTag]: WeakSetProtoSymbolToStringTag, +} = WeakSetProto as any; + +export function toSafeWeakSet<T extends WeakSet<any>>(weakSet: T): T { + ReflectSetPrototypeOf(weakSet, null); + weakSet.add = WeakSetProtoAdd; + weakSet.delete = WeakSetProtoDelete; + weakSet.has = WeakSetProtoHas; + (weakSet as any)[SymbolToStringTag] = WeakSetProtoSymbolToStringTag; + ReflectSetPrototypeOf(weakSet, WeakSetProto); + return weakSet; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +14x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | import { ArrayIsArray } from './Array'; +import { ArrayBufferProtoByteLengthGetter } from './ArrayBuffer'; +import { BigIntProtoValueOf, SUPPORTS_BIG_INT } from './BigInt'; +import { BooleanProtoValueOf } from './Boolean'; +import { + TO_STRING_BRAND_ARRAY, + TO_STRING_BRAND_ARRAY_BUFFER, + TO_STRING_BRAND_BIG_INT, + TO_STRING_BRAND_BOOLEAN, + TO_STRING_BRAND_DATE, + TO_STRING_BRAND_FUNCTION, + TO_STRING_BRAND_MAP, + TO_STRING_BRAND_NULL, + TO_STRING_BRAND_NUMBER, + TO_STRING_BRAND_OBJECT, + TO_STRING_BRAND_REG_EXP, + TO_STRING_BRAND_SET, + TO_STRING_BRAND_STRING, + TO_STRING_BRAND_SYMBOL, + TO_STRING_BRAND_UNDEFINED, + TO_STRING_BRAND_WEAK_MAP, + TO_STRING_BRAND_WEAK_SET, +} from './constants'; +import { DateProtoValueOf } from './Date'; +import { MapProtoSizeGetter } from './Map'; +import { NumberProtoValueOf } from './Number'; +import { ObjectHasOwn, ObjectProtoToString } from './Object'; +import { ReflectApply } from './Reflect'; +import { RegExpProtoSourceGetter } from './RegExp'; +import { SetProtoSizeGetter } from './Set'; +import { StringProtoValueOf } from './String'; +import { SymbolProtoValueOf } from './Symbol'; +import { WeakMapProtoHas } from './WeakMap'; +import { WeakSetProtoHas } from './WeakSet'; + +const { toStringTag: TO_STRING_TAG_SYMBOL } = Symbol; + +function getBrandByTrialAndError(value: any): string { + // Trail and error attempts are performed in order of most likely, + // e.g. those values that have a @@toStringTag defined by default, + // to least likely. + // + // Internally these brand checks rely on native methods that throw and catch + // an exception when they operate on values with unexpected internal slot + // entries. + + // Section 25.1.5.1 get ArrayBuffer.prototype.byteLength + // https://tc39.es/ecma262/#sec-get-arraybuffer.prototype.bytelength + // Step 2: Perform RequireInternalSlot(O, [[ArrayBufferData]]). + try { + if ('byteLength' in value) { + ReflectApply(ArrayBufferProtoByteLengthGetter, value, []); + return TO_STRING_BRAND_ARRAY_BUFFER; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 21.4.4 Properties of the Date Prototype Object + // https://tc39.es/ecma262/#thistimevalue + // Step 1: If Type(value) is Object and value has a [[DateValue]] internal slot, then + // a. Return value.[[DateValue]]. + // Step 2: Throw a TypeError exception. + try { + if ('toLocaleDateString' in value) { + ReflectApply(DateProtoValueOf, value, []); + return TO_STRING_BRAND_DATE; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 24.1.3.10 get Map.prototype.size + // https://tc39.es/ecma262/#sec-get-map.prototype.size + // Step 2: Perform ? RequireInternalSlot(M, [[MapData]]). + try { + if ('get' in value && 'size' in value) { + ReflectApply(MapProtoSizeGetter, value, []); + return TO_STRING_BRAND_MAP; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 24.2.3.9 get Set.prototype.size + // https://tc39.es/ecma262/#sec-get-set.prototype.size + // Step 2: Perform ? RequireInternalSlot(S, [[SetData]]). + try { + if ('add' in value && 'size' in value) { + ReflectApply(SetProtoSizeGetter, value, []); + return TO_STRING_BRAND_SET; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 24.3.3.4 WeakMap.prototype.has ( key ) + // https://tc39.es/ecma262/#sec-weakmap.prototype.has + // Step 2: Perform RequireInternalSlot(M, [[WeakMapData]]). + try { + if ('get' in value && !('size' in value)) { + ReflectApply(WeakMapProtoHas, value, []); + return TO_STRING_BRAND_WEAK_MAP; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 24.4.3.4 WeakSet.prototype.has ( value ) + // https://tc39.es/ecma262/#sec-weakset.prototype.has + // Step 2: 2. Perform RequireInternalSlot(S, [[WeakSetData]]). + try { + if ('add' in value && !('size' in value)) { + ReflectApply(WeakSetProtoHas, value, []); + return TO_STRING_BRAND_WEAK_SET; + } + // eslint-disable-next-line no-empty + } catch {} + + // The following checks are for the rare occurrence of object, i.e. boxed, + // primitive values or those objects without a default @@toStringTag. + + // Section 21.1.3 Properties of the Number Prototype Object + // https://tc39.es/ecma262/#thisnumbervalue + // Step 2: If Type(value) is Object and value has a [[NumberData]] internal slot, then + // a. Let n be value.[[NumberData]]. + // b. Assert: Type(n) is Number. + try { + if ('toPrecision' in value) { + ReflectApply(NumberProtoValueOf, value, []); + return TO_STRING_BRAND_NUMBER; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 20.4.3 Properties of the Symbol Prototype Object + // https://tc39.es/ecma262/#thissymbolvalue + // Step 2: If Type(value) is Object and value has a [[SymbolData]] internal slot, then + // a. Let s be value.[[SymbolData]]. + // b. Assert: Type(s) is Symbol. + try { + if ('description' in value) { + ReflectApply(SymbolProtoValueOf, value, []); + return TO_STRING_BRAND_SYMBOL; + } + // eslint-disable-next-line no-empty + } catch {} + + // Perform heavier checks last. + + // Section 22.2.6.13 get RegExp.prototype.source + // https://tc39.es/ecma262/#sec-get-regexp.prototype.source + // Step 3: If R does not have an [[OriginalSource]] internal slot, then + // a. If SameValue(R, %RegExp.prototype%) is true, return "(?:)". + // b. Otherwise, throw a TypeError exception. + try { + if (ObjectHasOwn(value, 'lastIndex')) { + ReflectApply(RegExpProtoSourceGetter, value, []); + return TO_STRING_BRAND_REG_EXP; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 22.1.3 Properties of the String Prototype Object + // https://tc39.es/ecma262/#thisstringvalue + // Step 2: If Type(value) is Object and value has a [[StringData]] internal slot, then + // a. Let s be value.[[StringData]]. + // b. Assert: Type(s) is String. + try { + if (ObjectHasOwn(value, 'length')) { + ReflectApply(StringProtoValueOf, value, []); + return TO_STRING_BRAND_STRING; + } + // eslint-disable-next-line no-empty + } catch {} + // Section 20.3.3 Properties of the Boolean Prototype Object + // https://tc39.es/ecma262/#thisbooleanvalue + // Step 2: If Type(value) is Object and value has a [[BooleanData]] internal slot, then + // a. Let b be value.[[BooleanData]]. + // b. Assert: Type(b) is Boolean. + try { + ReflectApply(BooleanProtoValueOf, value, []); + return TO_STRING_BRAND_BOOLEAN; + // eslint-disable-next-line no-empty + } catch {} + // istanbul ignore else: all platforms that LWS runs tests in support BigInt + Iif (SUPPORTS_BIG_INT) { + try { + // Section 21.2.3 Properties of the BigInt Prototype Object + // https://tc39.es/ecma262/#thisbigintvalue + // Step 2: If Type(value) is Object and value has a [[BigIntData]] internal slot, then + // a. Assert: Type(value.[[BigIntData]]) is BigInt. + ReflectApply(BigIntProtoValueOf!, value, []); + return TO_STRING_BRAND_BIG_INT; + // eslint-disable-next-line no-empty + } catch {} + } + // Cannot detect brands for Arguments and Error objects. + return TO_STRING_BRAND_OBJECT; +} + +export function getBrand(value: any): string { + // Section 20.1.3.6 Object.prototype.toString ( ) + // https://tc39.es/ecma262/#sec-object.prototype.tostring + if (value === null) { + return TO_STRING_BRAND_NULL; + } + if (value === undefined) { + return TO_STRING_BRAND_UNDEFINED; + } + // eslint-disable-next-line default-case + switch (typeof value) { + case 'bigint': + return TO_STRING_BRAND_BIG_INT; + case 'boolean': + return TO_STRING_BRAND_BOOLEAN; + case 'function': + return TO_STRING_BRAND_FUNCTION; + case 'number': + return TO_STRING_BRAND_NUMBER; + case 'string': + return TO_STRING_BRAND_STRING; + case 'symbol': + return TO_STRING_BRAND_SYMBOL; + } + if (ArrayIsArray(value)) { + return TO_STRING_BRAND_ARRAY; + } + return TO_STRING_TAG_SYMBOL in value + ? getBrandByTrialAndError(value) + : ReflectApply(ObjectProtoToString, value, []); +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 | + + + + + + + + + + + + + + + + + + + + +14x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | import { ArrayCtor, ArrayProtoShift } from './Array'; +import { getBrand } from './basic'; +import { + TO_STRING_BRAND_ARRAY, + TO_STRING_BRAND_BIG_INT, + TO_STRING_BRAND_BOOLEAN, + TO_STRING_BRAND_MAP, + TO_STRING_BRAND_NUMBER, + TO_STRING_BRAND_OBJECT, + TO_STRING_BRAND_REG_EXP, + TO_STRING_BRAND_SET, + TO_STRING_BRAND_STRING, +} from './constants'; +import { JSONParse } from './JSON'; +import { MapCtor, MapProtoEntries, MapProtoSet, toSafeMap } from './Map'; +import { getNearMembraneProxySerializedValue, isNearMembraneProxy } from './NearMembrane'; +import { ObjectCtor, ObjectKeys, ObjectProto } from './Object'; +import { ReflectApply, ReflectGetPrototypeOf } from './Reflect'; +import { RegExpCtor } from './RegExp'; +import { SetCtor, SetProtoAdd, SetProtoValues } from './Set'; + +const SEEN_OBJECTS = toSafeMap(new MapCtor<object, object>()); + +function cloneBoxedPrimitive(object: object): object { + return ObjectCtor(getNearMembraneProxySerializedValue(object)); +} + +function cloneMap(map: Map<any, any>, queue: any[]): Map<any, any> { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // Step 26.1.1: Let copiedList be a new empty List. + const clone = new MapCtor(); + // Step 26.1.2: For each Record { [[Key]], [[Value]] } entry of value.[[MapData]]... + const entriesIterable = ReflectApply(MapProtoEntries, map, []); + // Step 26.1.3 For each Record { [[Key]], [[Value]] } entry of copiedList: + let { length: queueOffset } = queue; + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value: subKeyValuePair } = entriesIterable.next(); + if (done) { + break; + } + const { 0: subKey, 1: subValue } = subKeyValuePair; + let subCloneKey: any; + // Step 26.1.3.1: Let serializedKey be ? StructuredSerializeInternal(entry.[[Key]], forStorage, memory). + queue[queueOffset++] = [ + (subClone: any) => { + subCloneKey = subClone; + }, + subKey, + ]; + // Step 26.1.3.2: Let serializedValue be ? StructuredSerializeInternal(entry.[[Value]], forStorage, memory). + queue[queueOffset++] = [ + (subCloneValue: any) => { + ReflectApply(MapProtoSet, clone, [subCloneKey, subCloneValue]); + }, + subValue, + ]; + } + return clone; +} + +function cloneRegExp(regexp: RegExp): RegExp { + const { flags, source } = JSONParse(getNearMembraneProxySerializedValue(regexp) as string); + return new RegExpCtor(source, flags); +} + +function cloneSet(set: Set<any>, queue: any[]): Set<any> { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // Step 26.2.1: Let copiedList be a new empty List. + const clone = new SetCtor(); + // Step 26.2.2: For each entry of value.[[SetData]]... + const valuesIterable = ReflectApply(SetProtoValues, set, []); + // Step 26.2.3: For each entry of copiedList: + let { length: queueOffset } = queue; + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value: subValue } = valuesIterable.next(); + if (done) { + break; + } + // Step 26.2.3.1: Let serializedEntry be ? StructuredSerializeInternal(entry, forStorage, memory). + queue[queueOffset++] = [ + (subCloneValue: any) => { + ReflectApply(SetProtoAdd, clone, [subCloneValue]); + }, + subValue, + ]; + } + return clone; +} + +function enqueue(queue: any[], originalValue: object, cloneValue: object) { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // Step 26.4: Otherwise, for each key in ! EnumerableOwnPropertyNames(value, key)... + // Note: Object.keys() performs EnumerableOwnPropertyNames() internally as + // defined in ECMA262: + // https://tc39.es/ecma262/#sec-object.keys + const keys = ObjectKeys(originalValue); + let { length: queueOffset } = queue; + for (let i = 0, { length } = keys; i < length; i += 1) { + // Step 26.4.1.1: Let inputValue be ? value.[[Get]](key, value). + // The [[Get]] operation is defined in ECMA262 for ordinary objects, + // argument objects, integer-indexed exotic objects, module namespace + // objects, and proxy objects. + // https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-get-p-receiver + const key = keys[i]; + const subValue = (originalValue as any)[key]; + queue[queueOffset++] = [ + (subCloneValue: object) => { + // Step 26.4.1.3: Property descriptor attributes are not + // preserved during deserialization because only keys and + // values are captured in serialized.[[Properties]]. + (cloneValue as any)[key] = subCloneValue; + }, + subValue, + ]; + } +} + +// This function is the unguarded internal variant of `partialStructuredClone()`. +// Any error thrown that is captured by `partialStructuredClone()` is treated as +// a `DataCloneError`. This function clones blue membrane proxied arrays, plain +// objects, maps, regexps, sets, and boxed primitives. The following non-membrane +// proxied objects are set by reference instead of cloning: +// ArrayBuffer +// BigInt64Array +// BigUint64Array +// Blob +// DataView +// Date +// DOMException +// DOMMatrix +// DOMMatrixReadOnly +// DOMPoint +// DOMPointReadOnly +// DOMQuad +// DOMRect +// DOMRectReadOnly +// Error +// EvalError +// File +// FileList +// Float32Array +// Float64Array +// ImageBitMap +// ImageData +// Int8Array +// Int16Array +// Int32Array +// RangeError +// ReferenceError +// SyntaxError +// TypeError +// Uint8Array +// Uint8ClampedArray +// Uint16Array +// Uint32Array +// URIError +// +// Note: +// This function performs brand checks using `Object.prototype.toString`. The +// results can be faked with `Symbol.toStringTag` property values and are a poor +// substitute for native internal slot checks. However, for our purposes they +// are perfectly fine and avoid having to repeatedly walk the prototype of proxied +// values. Cloned values should be passed to native methods, like `postMessage()`, +// which perform their own validation with internal slot checks. +function partialStructuredCloneInternal(value: any): any { + // Using a queue instead of recursive function calls avoids call stack limits + // and enables cloning more complex and deeply nested objects. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Too_much_recursion + let result: any; + const queue = [ + [ + (subClone: any) => { + result = subClone; + }, + value, + ], + ]; + // eslint-disable-next-line no-labels + queueLoop: while (queue.length) { + // Section 2.7.3 StructuredSerializeInternal: + // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal + // prettier-ignore + const { + 0: setter, + 1: originalValue, + } = ReflectApply(ArrayProtoShift, queue, []); + // Step 4: If Type(value) is Undefined, Null, Boolean, Number, BigInt, or String + if ( + originalValue === null || + originalValue === undefined || + typeof originalValue === 'boolean' || + typeof originalValue === 'number' || + typeof originalValue === 'string' || + typeof originalValue === 'bigint' + ) { + setter(originalValue); + // eslint-disable-next-line no-continue, no-extra-label, no-labels + continue queueLoop; + } + // Step 5: If Type(value) is Symbol, then throw a 'DataCloneError' DOMException. + if (typeof originalValue === 'symbol') { + // Stop cloning and set the original value and defer throwing to + // native methods. + setter(originalValue); + // eslint-disable-next-line no-extra-label, no-labels + break queueLoop; + } + // To support circular references check if the original value has been + // seen. If it has then use the clone associated with its record instead + // of creating a new clone. + let cloneValue = SEEN_OBJECTS.get(originalValue); + if (cloneValue) { + setter(cloneValue); + // eslint-disable-next-line no-continue, no-extra-label, no-labels + continue queueLoop; + } + // Perform a brand check on originalValue. + const brand = getBrand(originalValue); + // eslint-disable-next-line default-case + switch (brand) { + // Step 19: Otherwise, if value is a platform object... + case TO_STRING_BRAND_OBJECT: { + const proto = ReflectGetPrototypeOf(originalValue); + if ( + proto === ObjectProto || + proto === null || + // Possible `Object.prototype` from another document. + ReflectGetPrototypeOf(proto) === null + ) { + cloneValue = {}; + // Step 19.4: Set deep to true. + enqueue(queue, originalValue, cloneValue); + } + break; + } + // Step 18: Otherwise, if value is an Array exotic object... + case TO_STRING_BRAND_ARRAY: + // Step 18.1 Let valueLenDescriptor be ? OrdinaryGetOwnProperty(value, 'length'). + // Note: Rather than perform the more complex OrdinaryGetOwnProperty() + // operation for 'length' because it is a non-configurable property + // we can access it with the simpler [[Get]]() operation defined + // in ECMA262. + // https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-get-p-receiver + cloneValue = ArrayCtor(originalValue.length); + // Step 18.4: Set deep to true. + enqueue(queue, originalValue, cloneValue); + break; + // Step 15: Otherwise, if value has [[MapData]] internal slot... + // Step 15.2: Set deep to true. + case TO_STRING_BRAND_MAP: + cloneValue = cloneMap(originalValue, queue); + break; + // Step 16: Otherwise, if value has [[SetData]] internal slot... + // Step 16.2: Set deep to true. + case TO_STRING_BRAND_SET: + cloneValue = cloneSet(originalValue, queue); + break; + } + if (cloneValue === undefined) { + // istanbul ignore else + Iif (!isNearMembraneProxy(originalValue)) { + // Skip cloning non-membrane proxied objects. + SEEN_OBJECTS.set(originalValue, originalValue); + setter(originalValue); + // eslint-disable-next-line no-extra-label, no-labels + continue queueLoop; + } + // Cases ordered by a guestimate on frequency of encounter. + // eslint-disable-next-line default-case + switch (brand) { + // Step 12: Otherwise, if value has a [[RegExpMatcher]] internal slot... + case TO_STRING_BRAND_REG_EXP: + cloneValue = cloneRegExp(originalValue); + break; + // Step 7: If value has a [[BooleanData]] internal slot... + case TO_STRING_BRAND_BOOLEAN: + // Step 8: Otherwise, if value has a [[NumberData]] internal slot... + // eslint-disable-next-line no-fallthrough + case TO_STRING_BRAND_NUMBER: + // Step 9: Otherwise, if value has a [[BigIntData]] internal slot... + // eslint-disable-next-line no-fallthrough + case TO_STRING_BRAND_BIG_INT: + // Step 10: Otherwise, if value has a [[StringData]] internal slot... + // eslint-disable-next-line no-fallthrough + case TO_STRING_BRAND_STRING: + cloneValue = cloneBoxedPrimitive(originalValue); + break; + } + } + // Step 21: Otherwise, if IsCallable(value) is true, then throw a 'DataCloneError' + // Step 20: Otherwise, if value is a platform object, then throw a 'DataCloneError' + if (cloneValue === undefined) { + // Stop cloning and set the original value and defer throwing to + // native methods. + setter(originalValue); + // eslint-disable-next-line no-extra-label, no-labels + break queueLoop; + } + SEEN_OBJECTS.set(originalValue, cloneValue); + setter(cloneValue); + } + return result; +} + +export function partialStructuredClone(value: any): any { + let result = value; + try { + result = partialStructuredCloneInternal(value); + // eslint-disable-next-line no-empty + } catch {} + SEEN_OBJECTS.clear(); + return result; +} + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 | + + +14x + + + + + + + + + +14x +14x + + + +14x + + +14x + + +14x + + +14x +14x + + +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x + | import { SymbolFor } from './Symbol'; + +// Locker build constants. +export const LOCKER_IDENTIFIER_MARKER = '$LWS'; +// This package is bundled by third-parties that have their own build time +// replacement logic. Instead of customizing each build system to be aware +// of this package we implement a two phase debug mode by performing small +// runtime checks to determine phase one, our code is unminified, and +// phase two, the user opted-in to custom devtools formatters. Phase one +// is used for light weight initialization time debug while phase two is +// reserved for post initialization runtime +export const LOCKER_UNMINIFIED_FLAG = + // eslint-disable-next-line @typescript-eslint/naming-convention + /* istanbul ignore next */ `${(function LOCKER_UNMINIFIED_FLAG() { + return LOCKER_UNMINIFIED_FLAG.name; + })()}`.includes('LOCKER_UNMINIFIED_FLAG'); + +// Character constants. +export const CHAR_ELLIPSIS = '\u2026'; + +// Error message constants. +export const ERR_ILLEGAL_PROPERTY_ACCESS = 'Illegal property access.'; + +// Near-membrane constants. +export const LOCKER_NEAR_MEMBRANE_SERIALIZED_VALUE_SYMBOL = SymbolFor( + '@@lockerNearMembraneSerializedValue' +); +export const LOCKER_NEAR_MEMBRANE_SYMBOL = SymbolFor('@@lockerNearMembrane'); +export const SYMBOL_LIVE_OBJECT = SymbolFor('@@lockerLiveValue'); + +// Object brand constants. +export const TO_STRING_BRAND_ARRAY = '[object Array]'; +export const TO_STRING_BRAND_ARRAY_BUFFER = '[object ArrayBuffer]'; +export const TO_STRING_BRAND_BIG_INT = '[object BigInt]'; +export const TO_STRING_BRAND_BOOLEAN = '[object Boolean]'; +export const TO_STRING_BRAND_DATE = '[object Date]'; +export const TO_STRING_BRAND_FUNCTION = '[object Function]'; +export const TO_STRING_BRAND_MAP = '[object Map]'; +export const TO_STRING_BRAND_NULL = '[object Null]'; +export const TO_STRING_BRAND_NUMBER = '[object Number]'; +export const TO_STRING_BRAND_OBJECT = '[object Object]'; +export const TO_STRING_BRAND_REG_EXP = '[object RegExp]'; +export const TO_STRING_BRAND_SET = '[object Set]'; +export const TO_STRING_BRAND_STRING = '[object String]'; +export const TO_STRING_BRAND_SYMBOL = '[object Symbol]'; +export const TO_STRING_BRAND_UNDEFINED = '[object Undefined]'; +export const TO_STRING_BRAND_WEAK_MAP = '[object WeakMap]'; +export const TO_STRING_BRAND_WEAK_SET = '[object WeakSet]'; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +File | ++ | Statements | ++ | Branches | ++ | Functions | ++ | Lines | ++ |
---|---|---|---|---|---|---|---|---|---|
Array.ts | +
+
+ |
+ 100% | +43/43 | +100% | +0/0 | +100% | +1/1 | +100% | +43/43 | +
ArrayBuffer.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
BigInt.ts | +
+
+ |
+ 100% | +2/2 | +100% | +1/1 | +100% | +0/0 | +100% | +2/2 | +
Boolean.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
Date.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
Error.ts | +
+
+ |
+ 100% | +2/2 | +100% | +0/0 | +100% | +0/0 | +100% | +2/2 | +
Function.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +1/1 | +0% | +0/0 | +
JSON.ts | +
+
+ |
+ 100% | +2/2 | +100% | +0/0 | +100% | +0/0 | +100% | +2/2 | +
Map.ts | +
+
+ |
+ 100% | +20/20 | +100% | +0/0 | +100% | +1/1 | +100% | +20/20 | +
Math.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
NearMembrane.ts | +
+
+ |
+ 0% | +0/6 | +0% | +0/14 | +0% | +0/2 | +0% | +0/6 | +
Number.ts | +
+
+ |
+ 100% | +3/3 | +100% | +0/0 | +100% | +0/0 | +100% | +3/3 | +
Object.ts | +
+
+ |
+ 77.78% | +7/9 | +38.46% | +5/13 | +33.33% | +1/3 | +77.78% | +7/9 | +
Proxy.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
Reflect.ts | +
+
+ |
+ 100% | +1/1 | +100% | +0/0 | +100% | +0/0 | +100% | +1/1 | +
RegExp.ts | +
+
+ |
+ 100% | +4/4 | +100% | +0/0 | +100% | +0/0 | +100% | +4/4 | +
Set.ts | +
+
+ |
+ 100% | +4/4 | +100% | +0/0 | +100% | +0/0 | +100% | +4/4 | +
String.ts | +
+
+ |
+ 100% | +3/3 | +100% | +0/0 | +100% | +0/0 | +100% | +3/3 | +
Symbol.ts | +
+
+ |
+ 100% | +3/3 | +100% | +0/0 | +100% | +0/0 | +100% | +3/3 | +
WeakMap.ts | +
+
+ |
+ 100% | +12/12 | +100% | +0/0 | +100% | +1/1 | +100% | +12/12 | +
WeakSet.ts | +
+
+ |
+ 36.36% | +4/11 | +100% | +0/0 | +0% | +0/1 | +36.36% | +4/11 | +
basic.ts | +
+
+ |
+ 1.59% | +1/63 | +0% | +0/43 | +0% | +0/2 | +1.59% | +1/63 | +
clone.ts | +
+
+ |
+ 1.16% | +1/86 | +0% | +0/35 | +0% | +0/12 | +1.2% | +1/83 | +
constants.ts | +
+
+ |
+ 100% | +25/25 | +100% | +0/0 | +100% | +1/1 | +100% | +25/25 | +
index.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +
types.ts | +
+
+ |
+ 0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +0% | +0/0 | +
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 | + + + + + + + + + + + + + + + + + + + + + + + + + | export * from './Array'; +export * from './ArrayBuffer'; +export * from './basic'; +export * from './BigInt'; +export * from './Boolean'; +export * from './clone'; +export * from './constants'; +export * from './Date'; +export * from './Error'; +export * from './Function'; +export * from './JSON'; +export * from './Map'; +export * from './Math'; +export * from './NearMembrane'; +export * from './Number'; +export * from './Object'; +export * from './Proxy'; +export * from './Reflect'; +export * from './RegExp'; +export * from './Set'; +export * from './String'; +export * from './Symbol'; +export * from './types'; +export * from './WeakMap'; +export * from './WeakSet'; + |
+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +
+ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 | + + + + + + + + + + + + + + + | export type Getter = () => any; +export type NearMembraneSerializedValue = bigint | boolean | number | string | symbol | undefined; +export type ProxyTarget = CallableFunction | NewableFunction | any[] | object; +export type Setter = (value: any) => void; +// eslint-disable-next-line no-shadow +export const enum TargetTraits { + None, + IsArray = 1 << 0, + IsArrayBufferView = 1 << 1, + IsFunction = 1 << 2, + IsArrowFunction = 1 << 3, + IsObject = 1 << 4, + IsTypedArray = 1 << 5, + Revoked = 1 << 6, +} + |