merge mozilla-central to autoland

--HG--
rename : third_party/rust/nom/.cargo-checksum.json => third_party/rust/nom-3.2.1/.cargo-checksum.json
rename : third_party/rust/nom/CHANGELOG.md => third_party/rust/nom-3.2.1/CHANGELOG.md
rename : third_party/rust/nom/Cargo.toml => third_party/rust/nom-3.2.1/Cargo.toml
rename : third_party/rust/nom/src/bits.rs => third_party/rust/nom-3.2.1/src/bits.rs
rename : third_party/rust/nom/src/branch.rs => third_party/rust/nom-3.2.1/src/branch.rs
rename : third_party/rust/nom/src/bytes.rs => third_party/rust/nom-3.2.1/src/bytes.rs
rename : third_party/rust/nom/src/character.rs => third_party/rust/nom-3.2.1/src/character.rs
rename : third_party/rust/nom/src/internal.rs => third_party/rust/nom-3.2.1/src/internal.rs
rename : third_party/rust/nom/src/lib.rs => third_party/rust/nom-3.2.1/src/lib.rs
rename : third_party/rust/nom/src/macros.rs => third_party/rust/nom-3.2.1/src/macros.rs
rename : third_party/rust/nom/src/methods.rs => third_party/rust/nom-3.2.1/src/methods.rs
rename : third_party/rust/nom/src/multi.rs => third_party/rust/nom-3.2.1/src/multi.rs
rename : third_party/rust/nom/src/nom.rs => third_party/rust/nom-3.2.1/src/nom.rs
rename : third_party/rust/nom/src/regexp.rs => third_party/rust/nom-3.2.1/src/regexp.rs
rename : third_party/rust/nom/src/sequence.rs => third_party/rust/nom-3.2.1/src/sequence.rs
rename : third_party/rust/nom/src/simple_errors.rs => third_party/rust/nom-3.2.1/src/simple_errors.rs
rename : third_party/rust/nom/src/str.rs => third_party/rust/nom-3.2.1/src/str.rs
rename : third_party/rust/nom/src/stream.rs => third_party/rust/nom-3.2.1/src/stream.rs
rename : third_party/rust/nom/src/traits.rs => third_party/rust/nom-3.2.1/src/traits.rs
rename : third_party/rust/nom/src/util.rs => third_party/rust/nom-3.2.1/src/util.rs
rename : third_party/rust/nom/src/verbose_errors.rs => third_party/rust/nom-3.2.1/src/verbose_errors.rs
rename : third_party/rust/nom/src/whitespace.rs => third_party/rust/nom-3.2.1/src/whitespace.rs
rename : third_party/rust/nom/tests/arithmetic.rs => third_party/rust/nom-3.2.1/tests/arithmetic.rs
rename : third_party/rust/nom/tests/arithmetic_ast.rs => third_party/rust/nom-3.2.1/tests/arithmetic_ast.rs
rename : third_party/rust/nom/tests/blockbuf-arithmetic.rs => third_party/rust/nom-3.2.1/tests/blockbuf-arithmetic.rs
rename : third_party/rust/nom/tests/cross_function_backtracking.rs => third_party/rust/nom-3.2.1/tests/cross_function_backtracking.rs
rename : third_party/rust/nom/tests/float.rs => third_party/rust/nom-3.2.1/tests/float.rs
rename : third_party/rust/nom/tests/ini.rs => third_party/rust/nom-3.2.1/tests/ini.rs
rename : third_party/rust/nom/tests/ini_str.rs => third_party/rust/nom-3.2.1/tests/ini_str.rs
rename : third_party/rust/nom/tests/issues.rs => third_party/rust/nom-3.2.1/tests/issues.rs
rename : third_party/rust/nom/tests/json.rs => third_party/rust/nom-3.2.1/tests/json.rs
rename : third_party/rust/nom/tests/mp4.rs => third_party/rust/nom-3.2.1/tests/mp4.rs
rename : third_party/rust/nom/tests/multiline.rs => third_party/rust/nom-3.2.1/tests/multiline.rs
rename : third_party/rust/nom/tests/named_args.rs => third_party/rust/nom-3.2.1/tests/named_args.rs
rename : third_party/rust/nom/tests/omnom.rs => third_party/rust/nom-3.2.1/tests/omnom.rs
rename : third_party/rust/nom/tests/overflow.rs => third_party/rust/nom-3.2.1/tests/overflow.rs
rename : third_party/rust/nom/tests/reborrow_fold.rs => third_party/rust/nom-3.2.1/tests/reborrow_fold.rs
rename : third_party/rust/nom/tests/test1.rs => third_party/rust/nom-3.2.1/tests/test1.rs
extra : rebase_source : 6c5b45c092fd51bf1b3ce15960416fb59311d152
This commit is contained in:
Sebastian Hengst 2018-10-22 20:34:24 +03:00
Родитель 64ac0e5cd4 602fbb8422
Коммит 1ad50182a7
218 изменённых файлов: 32591 добавлений и 9942 удалений

Просмотреть файл

@ -152,3 +152,4 @@ ccfd7b716a91241ddbc084cb7116ec561e56d5d1 FIREFOX_BETA_61_BASE
224715760a637bc37c14794839468a954f1f2695 FIREFOX_BETA_64_BASE
224715760a637bc37c14794839468a954f1f2695 FIREFOX_BETA_64_BASE
ad179a6fc14cbd41d10a018ac4a3822db119de3b FIREFOX_BETA_64_BASE
c44fbdd5173548c9035256dda8fd3512f67118a8 FIREFOX_NIGHTLY_64_END

Просмотреть файл

@ -22,5 +22,5 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1488813 - Migrating Pocket off any bootstrap code
Merge day clobber

35
Cargo.lock сгенерированный
Просмотреть файл

@ -160,7 +160,7 @@ dependencies = [
name = "baldrdash"
version = "0.1.0"
dependencies = [
"bindgen 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-wasm 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -214,13 +214,13 @@ dependencies = [
[[package]]
name = "bindgen"
version = "0.39.0"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cexpr 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -336,10 +336,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cexpr"
version = "0.2.3"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -359,7 +359,7 @@ dependencies = [
[[package]]
name = "clang-sys"
version = "0.23.0"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1208,7 +1208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "js"
version = "0.1.4"
dependencies = [
"bindgen 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1232,7 +1232,7 @@ name = "jsrust_shared"
version = "0.1.0"
dependencies = [
"baldrdash 0.1.0",
"bindgen 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1679,6 +1679,14 @@ dependencies = [
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nom"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nserror"
version = "0.1.0"
@ -2350,7 +2358,7 @@ dependencies = [
"app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3124,7 +3132,7 @@ dependencies = [
"checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
"checksum bindgen 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eac4ed5f2de9efc3c87cb722468fa49d0763e98f999d539bfc5e452c13d85c91"
"checksum bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41df015ccbc22b038641bd84d0aeeff01e0a4c0714ed35ed0e9a3dd8ad8d732"
"checksum binjs_meta 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "430239e4551e42b80fa5d92322ac80ea38c9dda56e5d5582e057e2288352b71a"
"checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
"checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
@ -3140,10 +3148,10 @@ dependencies = [
"checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24"
"checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b"
"checksum cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c37f0efaa4b9b001fa6f02d4b644dee4af97d3414df07c51e3e4f015f3a3e131"
"checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c"
"checksum cexpr 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fc0086be9ca82f7fc89fc873435531cb898b86e850005850de1f820e2db6e9b"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2"
"checksum clang-sys 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)" = "481e42017c1416b1c0856ece45658ecbb7c93d8a93455f7e5fa77f3b35455557"
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
"checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
@ -3260,6 +3268,7 @@ dependencies = [
"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
"checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a"
"checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"

Просмотреть файл

@ -439,11 +439,10 @@ NotificationController::ScheduleContentInsertion(nsIContent* aStartChildNode,
node = node->GetNextSibling()) {
MOZ_ASSERT(parent == node->GetFlattenedTreeParentNode());
// Notification triggers for content insertion even if no content was
// actually inserted, check if the given content has a frame to discard
// actually inserted (like if the content is display: none). Try to catch
// this case early.
//
// TODO(emilio): Should this handle display: contents?
if (node->GetPrimaryFrame()) {
if (node->GetPrimaryFrame() ||
(node->IsElement() && node->AsElement()->IsDisplayContents())) {
list.AppendElement(node);
}
}

Просмотреть файл

@ -100,6 +100,40 @@
};
}
// Test for bug 1500416.
function displayContentsInsertion() {
this.eventSeq = [
new invokerChecker(EVENT_REORDER, "c4"),
];
this.invoke = function displayContentsInsertion_invoke() {
document.body.offsetTop; // Flush layout.
let list = document.createElement("ul");
list.style.display = "contents";
list.appendChild(document.createElement("li"));
list.firstChild.appendChild(document.createTextNode("Text"));
getNode("c4").appendChild(list);
};
this.finalCheck = function displayContentsInsertion_finalCheck() {
var accTree =
{ SECTION: [ // container
{ LIST: [
{ LISTITEM: [
{ STATICTEXT: [] },
{ TEXT_LEAF: [] },
] },
] },
] };
testAccessibleTree("c4", accTree);
};
this.getID = function displayContentsInsertion_getID() {
return "insert accessible display: contents element.";
};
}
// //////////////////////////////////////////////////////////////////////////
// Do tests
// //////////////////////////////////////////////////////////////////////////
@ -114,6 +148,7 @@
gQueue.push(new prependAppend("c1"));
gQueue.push(new removeRemove("c2"));
gQueue.push(new insertInaccessibleAccessibleSiblings());
gQueue.push(new displayContentsInsertion());
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -133,5 +168,6 @@
<div id="c2"><span><input type="checkbox"><input></span><input type="button"></div>
<div id="c3"><input type="button" value="button"></div>
<div id="c4"></div>
</body>
</html>

Просмотреть файл

@ -169,7 +169,7 @@ tags = fullscreen
[browser_check_tooltips_in_navbar.js]
[browser_editcontrols_update.js]
subsuite = clipboard
skip-if = verify && !debug && os == 'mac'
skip-if = (verify && !debug && os == 'mac') || (os == 'mac') # Bug 1458046
[browser_customization_context_menus.js]
[browser_newtab_button_customizemode.js]
[browser_open_from_popup.js]

Просмотреть файл

@ -38,6 +38,7 @@ skip-if = verify
skip-if = os == "mac" #1421238
[browser_private_search_perwindowpb.js]
[browser_aboutSearchReset.js]
disabled = bug 1488946 - Telemetry probe needs extension
[browser_searchbar_openpopup.js]
skip-if = os == "linux" # Linux has different focus behaviours.
[browser_searchbar_keyboard_navigation.js]

Просмотреть файл

@ -1 +1 @@
64.0a1
65.0a1

Просмотреть файл

@ -1 +1 @@
64.0a1
65.0a1

Просмотреть файл

@ -40,10 +40,12 @@ run-if = crashreporter
[browser_UsageTelemetry_private_and_restore.js]
skip-if = verify && debug
[browser_UsageTelemetry_urlbar.js]
disabled = bug 1496764 - Telemetry probe needs extension
support-files =
usageTelemetrySearchSuggestions.sjs
usageTelemetrySearchSuggestions.xml
[browser_UsageTelemetry_searchbar.js]
disabled = bug 1496764 - Telemetry probe needs extension
support-files =
usageTelemetrySearchSuggestions.sjs
usageTelemetrySearchSuggestions.xml

Просмотреть файл

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
64.0a1
65.0a1

Просмотреть файл

@ -60,6 +60,7 @@ skip-if = true # Bug 1413765
[browser_toolbox_computed_view.js]
[browser_toolbox_rule_view.js]
[browser_toolbox_rule_view_reload.js]
skip-if = os == "linux" || os == "mac" # Bug 1498336
[browser_toolbox_swap_browsers.js]
[browser_toolbox_swap_inspector.js]
[browser_touch_device.js]

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -477,6 +477,12 @@ private:
nsresult
MaybeRemoveOldDirectories();
template<typename Helper>
nsresult
UpgradeStorage(const int32_t aOldVersion,
const int32_t aNewVersion,
mozIStorageConnection* aConnection);
nsresult
UpgradeStorageFrom0_0To1_0(mozIStorageConnection* aConnection);

Просмотреть файл

@ -7,7 +7,7 @@ license = "MPL-2.0"
[build-dependencies]
env_logger = {version = "0.5", default-features = false} # disable `regex` to reduce code size
bindgen = {version = "0.39", default-features = false} # disable `logging` to reduce code size
bindgen = {version = "0.43", default-features = false} # disable `logging` to reduce code size
cmake = "0.1"
glob = "0.2.11"

Просмотреть файл

@ -299,16 +299,17 @@ function ModuleInstantiate()
} catch (error) {
for (let i = 0; i < stack.length; i++) {
let m = stack[i];
assert(m.status === MODULE_STATUS_INSTANTIATING,
"Expected instantiating status during failed instantiation");
HandleModuleInstantiationFailure(m);
if (m.status === MODULE_STATUS_INSTANTIATING) {
HandleModuleInstantiationFailure(m);
}
}
// Handle OOM when appending to the stack or over-recursion errors.
if (stack.length === 0)
if (stack.length === 0 && module.status === MODULE_STATUS_INSTANTIATING) {
HandleModuleInstantiationFailure(module);
}
assert(module.status === MODULE_STATUS_UNINSTANTIATED,
assert(module.status !== MODULE_STATUS_INSTANTIATING,
"Expected uninstantiated status after failed instantiation");
throw error;

Просмотреть файл

@ -8,6 +8,7 @@
#include "mozilla/EnumSet.h"
#include "builtin/Promise.h"
#include "builtin/SelfHostingDefines.h"
#include "frontend/ParseNode.h"
#include "frontend/SharedContext.h"
@ -1805,3 +1806,88 @@ js::GetOrCreateModuleMetaObject(JSContext* cx, HandleObject moduleArg)
return metaObject;
}
JSObject*
js::CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
{
JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook;
if (!moduleResolveHook) {
JS_ReportErrorASCII(cx, "Module resolve hook not set");
return nullptr;
}
RootedObject result(cx, moduleResolveHook(cx, referencingPrivate, specifier));
if (!result) {
return nullptr;
}
if (!result->is<ModuleObject>()) {
JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object");
return nullptr;
}
return result;
}
JSObject*
js::StartDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleValue specifierArg)
{
RootedObject promiseConstructor(cx, JS::GetPromiseConstructor(cx));
if (!promiseConstructor) {
return nullptr;
}
RootedObject promiseObject(cx, JS::NewPromiseObject(cx, nullptr));
if (!promiseObject) {
return nullptr;
}
Handle<PromiseObject*> promise = promiseObject.as<PromiseObject>();
RootedString specifier(cx, ToString(cx, specifierArg));
if (!specifier) {
if (!RejectPromiseWithPendingError(cx, promise))
return nullptr;
return promise;
}
JS::ModuleDynamicImportHook importHook = cx->runtime()->moduleDynamicImportHook;
MOZ_ASSERT(importHook);
if (!importHook(cx, referencingPrivate, specifier, promise)) {
if (!RejectPromiseWithPendingError(cx, promise))
return nullptr;
return promise;
}
return promise;
}
bool
js::FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
HandleObject promiseArg)
{
Handle<PromiseObject*> promise = promiseArg.as<PromiseObject>();
if (cx->isExceptionPending()) {
return RejectPromiseWithPendingError(cx, promise);
}
RootedObject result(cx, CallModuleResolveHook(cx, referencingPrivate, specifier));
if (!result) {
return RejectPromiseWithPendingError(cx, promise);
}
RootedModuleObject module(cx, &result->as<ModuleObject>());
if (module->status() != MODULE_STATUS_EVALUATED) {
JS_ReportErrorASCII(cx, "Unevaluated or errored module returned by module resolve hook");
return RejectPromiseWithPendingError(cx, promise);
}
RootedObject ns(cx, ModuleObject::GetOrCreateModuleNamespace(cx, module));
if (!ns) {
return RejectPromiseWithPendingError(cx, promise);
}
RootedValue value(cx, ObjectValue(*ns));
return PromiseObject::resolve(cx, promise, value);
}

Просмотреть файл

@ -419,6 +419,16 @@ class MOZ_STACK_CLASS ModuleBuilder
JSObject*
GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module);
JSObject*
CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier);
JSObject*
StartDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleValue specifier);
bool
FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
HandleObject promise);
} // namespace js
template<>

Просмотреть файл

@ -3404,6 +3404,16 @@ OriginalPromiseThenBuiltin(JSContext* cx, HandleValue promiseVal, HandleValue on
return true;
}
MOZ_MUST_USE bool
js::RejectPromiseWithPendingError(JSContext* cx, Handle<PromiseObject*> promise)
{
// Not much we can do about uncatchable exceptions, just bail.
RootedValue exn(cx);
if (!GetAndClearException(cx, &exn))
return false;
return PromiseObject::reject(cx, promise, exn);
}
static MOZ_MUST_USE bool PerformPromiseThenWithReaction(JSContext* cx,
Handle<PromiseObject*> promise,
Handle<PromiseReactionRecord*> reaction);

Просмотреть файл

@ -225,6 +225,8 @@ OriginalPromiseThen(JSContext* cx, HandleObject promiseObj,
MOZ_MUST_USE JSObject*
PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
MOZ_MUST_USE bool
RejectPromiseWithPendingError(JSContext* cx, Handle<PromiseObject*> promise);
/**
* Create the promise object which will be used as the return value of an async

Просмотреть файл

@ -523,16 +523,6 @@ ReportArgTypeError(JSContext* cx, const char* funName, const char* expectedType,
expectedType, bytes.get());
}
static MOZ_MUST_USE bool
RejectWithPendingError(JSContext* cx, Handle<PromiseObject*> promise) {
// Not much we can do about uncatchable exceptions, just bail.
RootedValue exn(cx);
if (!GetAndClearException(cx, &exn)) {
return false;
}
return PromiseObject::reject(cx, promise, exn);
}
static MOZ_MUST_USE bool
ReturnPromiseRejectedWithPendingError(JSContext* cx, const CallArgs& args)
{
@ -1461,7 +1451,7 @@ ReadableStreamTee_Cancel(JSContext* cx, Handle<TeeState*> teeState,
{
AutoRealm ar(cx, promise);
if (!cancelResult) {
if (!RejectWithPendingError(cx, promise)) {
if (!RejectPromiseWithPendingError(cx, promise)) {
return nullptr;
}
} else {

Просмотреть файл

@ -8878,8 +8878,14 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
break;
case ParseNodeKind::CallImport:
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
return false;
if (!cx->runtime()->moduleDynamicImportHook) {
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
return false;
}
if (!emitTree(pn->as<BinaryNode>().right()) || !emit1(JSOP_DYNAMIC_IMPORT)) {
return false;
}
break;
case ParseNodeKind::SetThis:
if (!emitSetThis(&pn->as<BinaryNode>())) {

Просмотреть файл

@ -573,7 +573,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
}
BinaryNodeType newCallImport(NullaryNodeType importHolder, Node singleArg) {
return new_<BinaryNode>(ParseNodeKind::CallImport, JSOP_NOP, importHolder, singleArg);
return new_<BinaryNode>(ParseNodeKind::CallImport, JSOP_DYNAMIC_IMPORT, importHolder, singleArg);
}
UnaryNodeType newExprStatement(Node expr, uint32_t end) {

Просмотреть файл

@ -10913,7 +10913,7 @@ GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling)
MUST_MATCH_TOKEN_MOD(TokenKind::RightParen, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
if (!abortIfSyntaxParser()) {
if (!context->runtime()->moduleDynamicImportHook && !abortIfSyntaxParser()) {
return null();
}

Просмотреть файл

@ -0,0 +1,14 @@
// |jit-test| module
let result = null;
let error = null;
let promise = import("nonexistent.js");
promise.then((ns) => {
result = ns;
}).catch((e) => {
error = e;
});
drainJobQueue();
assertEq(result, null);
assertEq(error instanceof Error, true);

Просмотреть файл

@ -77,9 +77,3 @@ assertParseThrowsSyntaxError("x = import(");
assertParseThrowsSyntaxError("x = import(1,");
assertParseThrowsSyntaxError("x = import(1, 2");
assertParseThrowsSyntaxError("x = import(1, 2)");
// import() is not implemented.
assertThrowsInstanceOf(() => eval("import('foo')"),
SyntaxError);
assertThrowsInstanceOf(() => parseModule("import('foo')"),
SyntaxError);

Просмотреть файл

@ -0,0 +1,16 @@
// Even with --ion-eager, this needs to be run twice before it executes the
// ion-compiled version.
for (let i = 0; i < 2; i++) {
let result = null;
let error = null;
let promise = import("../../modules/module1.js");
promise.then((ns) => {
result = ns;
}).catch((e) => {
error = e;
});
drainJobQueue();
assertEq(error, null);
assertEq(result.a, 1);
}

Просмотреть файл

@ -1,5 +1,3 @@
// |jit-test| error: SyntaxError
function lazyilyParsedFunction()
{
return import("/module1.js");

Просмотреть файл

@ -0,0 +1,39 @@
// |jit-test| module
function testImport(path, name, value) {
let result = null;
let error = null;
let promise = import(path);
promise.then((ns) => {
result = ns;
}).catch((e) => {
error = e;
});
drainJobQueue();
assertEq(error, null);
assertEq(result[name], value);
}
// Resolved via module load path.
testImport("module1.js", "a", 1);
// Relative path resolved relative to this script.
testImport("../../modules/module1a.js", "a", 2);
// Import inside function.
function f() {
testImport("../../modules/module2.js", "b", 2);
}
f();
// Import inside direct eval.
eval(`testImport("../../modules/module3.js", "c", 3)`);
// Import inside indirect eval.
const indirect = eval;
const defineTestFunc = testImport.toSource();
indirect(defineTestFunc + `testImport("../../modules/module3.js");`);
// Import inside dynamic function.
Function(defineTestFunc + `testImport("../../modules/module3.js");`)();

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| skip-if: !('oomTest' in this)
oomTest(() => import("module1.js"));
oomTest(() => import("cyclicImport1.js"));

Просмотреть файл

@ -0,0 +1,45 @@
function testImport(path, name, value) {
let result = null;
let error = null;
let promise = import(path);
promise.then((ns) => {
result = ns;
}).catch((e) => {
error = e;
});
drainJobQueue();
assertEq(error, null);
assertEq(result[name], value);
}
// Resolved via module load path.
testImport("module1.js", "a", 1);
// Relative path resolved relative to this script.
testImport("../../modules/module1a.js", "a", 2);
// Import inside function.
function f() {
testImport("../../modules/module2.js", "b", 2);
}
f();
// Import inside eval.
eval(`testImport("../../modules/module3.js", "c", 3)`);
// Import inside indirect eval.
const indirect = eval;
const defineTestFunc = testImport.toSource();
indirect(defineTestFunc + `testImport("../../modules/module3.js");`);
// Import inside dynamic function.
Function(defineTestFunc + `testImport("../../modules/module3.js");`)();
// Import in eval in promise handler.
let ran = false;
Promise
.resolve(`import("../../modules/module3.js").then(() => { ran = true; })`)
.then(eval)
drainJobQueue();
assertEq(ran, true);

Просмотреть файл

@ -0,0 +1,17 @@
// |jit-test| module
import { a } from "javascript: export let a = 42;";
assertEq(a, 42);
let result = null;
let error = null;
let promise = import("javascript: export let b = 100;");
promise.then((ns) => {
result = ns;
}).catch((e) => {
error = e;
});
drainJobQueue();
assertEq(error, null);
assertEq(result.b, 100);

Просмотреть файл

@ -5451,3 +5451,28 @@ BaselineCompiler::emit_JSOP_IMPORTMETA()
frame.push(R0);
return true;
}
typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleValue, HandleValue);
static const VMFunction StartDynamicModuleImportInfo =
FunctionInfo<StartDynamicModuleImportFn>(js::StartDynamicModuleImport,
"StartDynamicModuleImport");
bool
BaselineCompiler::emit_JSOP_DYNAMIC_IMPORT()
{
RootedValue referencingPrivate(cx, FindScriptOrModulePrivateForScript(script));
// Put specifier value in R0.
frame.popRegsAndSync(1);
prepareVMCall();
pushArg(R0);
pushArg(referencingPrivate);
if (!callVM(StartDynamicModuleImportInfo)) {
return false;
}
masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
frame.push(R0);
return true;
}

Просмотреть файл

@ -245,7 +245,8 @@ namespace jit {
_(JSOP_FUNWITHPROTO) \
_(JSOP_CLASSCONSTRUCTOR) \
_(JSOP_DERIVEDCONSTRUCTOR) \
_(JSOP_IMPORTMETA)
_(JSOP_IMPORTMETA) \
_(JSOP_DYNAMIC_IMPORT)
class BaselineCompiler final
{

Просмотреть файл

@ -3025,6 +3025,19 @@ CodeGenerator::visitModuleMetadata(LModuleMetadata* lir)
callVM(GetOrCreateModuleMetaObjectInfo, lir);
}
typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleValue, HandleValue);
static const VMFunction StartDynamicModuleImportInfo =
FunctionInfo<StartDynamicModuleImportFn>(js::StartDynamicModuleImport,
"StartDynamicModuleImport");
void
CodeGenerator::visitDynamicImport(LDynamicImport* lir)
{
pushArg(ToValue(lir, LDynamicImport::SpecifierIndex));
pushArg(ToValue(lir, LDynamicImport::ReferencingPrivateIndex));
callVM(StartDynamicModuleImportInfo, lir);
}
typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject);
static const VMFunction LambdaInfo = FunctionInfo<LambdaFn>(js::Lambda, "Lambda");

Просмотреть файл

@ -21,6 +21,7 @@
#include "jit/Lowering.h"
#include "jit/MIRGraph.h"
#include "vm/ArgumentsObject.h"
#include "vm/EnvironmentObject.h"
#include "vm/Opcodes.h"
#include "vm/RegExpStatics.h"
#include "vm/TraceLogging.h"
@ -2489,6 +2490,9 @@ IonBuilder::inspectOpcode(JSOp op)
case JSOP_IMPORTMETA:
return jsop_importmeta();
case JSOP_DYNAMIC_IMPORT:
return jsop_dynamic_import();
case JSOP_LOOPENTRY:
return jsop_loopentry();
@ -13828,6 +13832,20 @@ IonBuilder::jsop_importmeta()
return resumeAfter(meta);
}
AbortReasonOr<Ok>
IonBuilder::jsop_dynamic_import()
{
Value referencingPrivate = FindScriptOrModulePrivateForScript(script());
MConstant* ref = constant(referencingPrivate);
MDefinition* specifier = current->pop();
MDynamicImport* ins = MDynamicImport::New(alloc(), ref, specifier);
current->add(ins);
current->push(ins);
return resumeAfter(ins);
}
MInstruction*
IonBuilder::addConvertElementsToDoubles(MDefinition* elements)
{

Просмотреть файл

@ -593,6 +593,7 @@ class IonBuilder
AbortReasonOr<Ok> jsop_pushcallobj();
AbortReasonOr<Ok> jsop_implicitthis(PropertyName* name);
AbortReasonOr<Ok> jsop_importmeta();
AbortReasonOr<Ok> jsop_dynamic_import();
/* Inlining. */

Просмотреть файл

@ -2602,6 +2602,15 @@ LIRGenerator::visitModuleMetadata(MModuleMetadata* ins)
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitDynamicImport(MDynamicImport* ins)
{
LDynamicImport* lir = new(alloc()) LDynamicImport(useBoxAtStart(ins->referencingPrivate()),
useBoxAtStart(ins->specifier()));
defineReturn(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitLambda(MLambda* ins)
{

Просмотреть файл

@ -7819,6 +7819,22 @@ class MModuleMetadata : public MNullaryInstruction
}
};
class MDynamicImport : public MBinaryInstruction,
public BoxInputsPolicy::Data
{
explicit MDynamicImport(MDefinition* referencingPrivate, MDefinition* specifier)
: MBinaryInstruction(classOpcode, referencingPrivate, specifier)
{
setResultType(MIRType::Object);
}
public:
INSTRUCTION_HEADER(DynamicImport)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, referencingPrivate))
NAMED_OPERANDS((1, specifier))
};
struct LambdaFunctionInfo
{
// The functions used in lambdas are the canonical original function in

Просмотреть файл

@ -4903,6 +4903,27 @@ class LModuleMetadata : public LCallInstructionHelper<1, 0, 0>
{}
};
class LDynamicImport : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
{
public:
LIR_HEADER(DynamicImport)
static const size_t ReferencingPrivateIndex = 0;
static const size_t SpecifierIndex = BOX_PIECES;
explicit LDynamicImport(const LBoxAllocation& referencingPrivate,
const LBoxAllocation& specifier)
: LCallInstructionHelper(classOpcode)
{
setBoxOperand(ReferencingPrivateIndex, referencingPrivate);
setBoxOperand(SpecifierIndex, specifier);
}
const MDynamicImport* mir() const {
return mir_->toDynamicImport();
}
};
class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
{
public:

Просмотреть файл

@ -615,6 +615,7 @@ MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found f
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
MSG_DEF(JSMSG_IMPORT_SCRIPT_NOT_FOUND, 0, JSEXN_TYPEERR, "can't find referencing script for dynamic module import")
// Promise
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")

Просмотреть файл

@ -4141,6 +4141,31 @@ JS::SetModuleMetadataHook(JSRuntime* rt, JS::ModuleMetadataHook func)
rt->moduleMetadataHook = func;
}
JS_PUBLIC_API(JS::ModuleDynamicImportHook)
JS::GetModuleDynamicImportHook(JSRuntime* rt)
{
AssertHeapIsIdle();
return rt->moduleDynamicImportHook;
}
JS_PUBLIC_API(void)
JS::SetModuleDynamicImportHook(JSRuntime* rt, JS::ModuleDynamicImportHook func)
{
AssertHeapIsIdle();
rt->moduleDynamicImportHook = func;
}
JS_PUBLIC_API(bool)
JS::FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
HandleObject promise)
{
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(referencingPrivate, promise);
return js::FinishDynamicModuleImport(cx, referencingPrivate, specifier, promise);
}
JS_PUBLIC_API(bool)
JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf, JS::MutableHandleObject module)

Просмотреть файл

@ -3050,6 +3050,25 @@ GetModuleMetadataHook(JSRuntime* rt);
extern JS_PUBLIC_API(void)
SetModuleMetadataHook(JSRuntime* rt, ModuleMetadataHook func);
using ModuleDynamicImportHook = bool (*)(JSContext* cx, HandleValue referencingPrivate,
HandleString specifier, HandleObject promise);
/**
* Get the HostResolveImportedModule hook for the runtime.
*/
extern JS_PUBLIC_API(ModuleDynamicImportHook)
GetModuleDynamicImportHook(JSRuntime* rt);
/**
* Set the HostResolveImportedModule hook for the runtime to the given function.
*/
extern JS_PUBLIC_API(void)
SetModuleDynamicImportHook(JSRuntime* rt, ModuleDynamicImportHook func);
extern JS_PUBLIC_API(bool)
FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
HandleObject promise);
/**
* Parse the given source buffer as a module in the scope of the current global
* of cx and return a source text module record.

Просмотреть файл

@ -12,7 +12,7 @@ path = "lib.rs"
baldrdash = { path = "../../wasm/cranelift" }
[build-dependencies]
bindgen = {version = "0.39", default-features = false} # disable `logging` to reduce code size
bindgen = {version = "0.43", default-features = false} # disable `logging` to reduce code size
# Uncomment this to enable perf support in release mode.
#[profile.release]

Просмотреть файл

@ -5,8 +5,12 @@
/* global getModuleLoadPath setModuleLoadHook setModuleResolveHook setModuleMetadataHook */
/* global getModulePrivate setModulePrivate parseModule os */
/* global setModuleDynamicImportHook finishDynamicModuleImport abortDynamicModuleImport */
// A basic synchronous module loader for testing the shell.
//
// Supports loading files and 'javascript:' URLs that embed JS source text.
{
// Save standard built-ins before scripts can modify them.
const ArrayPrototypeJoin = Array.prototype.join;
@ -21,16 +25,22 @@ const StringPrototypeStartsWith = String.prototype.startsWith;
const StringPrototypeSubstring = String.prototype.substring;
const ErrorClass = Error;
const JAVASCRIPT_SCHEME = "javascript:";
const ReflectLoader = new class {
constructor() {
this.registry = new Map();
this.modulePaths = new Map();
this.loadPath = getModuleLoadPath();
}
isJavascriptURL(name) {
return ReflectApply(StringPrototypeStartsWith, name, [JAVASCRIPT_SCHEME]);
}
resolve(name, referencingInfo) {
if (os.path.isAbsolute(name))
if (this.isJavascriptURL(name) || os.path.isAbsolute(name)) {
return name;
}
let loadPath = this.loadPath;
@ -67,6 +77,10 @@ const ReflectLoader = new class {
}
normalize(path) {
if (this.isJavascriptURL(path)) {
return path;
}
#ifdef XP_WIN
// Replace all forward slashes with backward slashes.
// NB: It may be tempting to replace this loop with a call to
@ -150,6 +164,10 @@ const ReflectLoader = new class {
}
fetch(path) {
if (this.isJavascriptURL(path)) {
return ReflectApply(StringPrototypeSubstring, path, [JAVASCRIPT_SCHEME.length]);
}
return os.file.readFile(path);
}
@ -176,7 +194,7 @@ const ReflectLoader = new class {
return this.loadAndExecute(path);
}
["import"](name, referrer) {
["import"](name, referencingInfo) {
let path = this.resolve(name, null);
return this.loadAndExecute(path);
}
@ -196,8 +214,8 @@ const ReflectLoader = new class {
setModuleLoadHook((path) => ReflectLoader.importRoot(path));
setModuleResolveHook((module, requestName) => {
let path = ReflectLoader.resolve(requestName, module);
setModuleResolveHook((referencingInfo, requestName) => {
let path = ReflectLoader.resolve(requestName, referencingInfo);
return ReflectLoader.loadAndParse(path);
});
@ -205,5 +223,14 @@ setModuleMetadataHook((module, metaObject) => {
ReflectLoader.populateImportMeta(module, metaObject);
});
}
setModuleDynamicImportHook((referencingInfo, specifier, promise) => {
try {
let path = ReflectLoader.resolve(specifier, referencingInfo);
ReflectLoader.loadAndExecute(path);
finishDynamicModuleImport(referencingInfo, specifier, promise);
} catch (err) {
abortDynamicModuleImport(referencingInfo, specifier, promise, err);
}
});
}

Просмотреть файл

@ -193,6 +193,7 @@ enum GlobalAppSlot
GlobalAppSlotModuleLoadHook, // Shell-specific; load a module graph
GlobalAppSlotModuleResolveHook, // HostResolveImportedModule
GlobalAppSlotModuleMetadataHook, // HostPopulateImportMeta
GlobalAppSlotModuleDynamicImportHook, // HostImportModuleDynamically
GlobalAppSlotCount
};
static_assert(GlobalAppSlotCount <= JSCLASS_GLOBAL_APPLICATION_SLOTS,
@ -850,6 +851,32 @@ EnvironmentPreparer::invoke(HandleObject global, Closure& closure)
}
}
static bool
RegisterScriptPathWithModuleLoader(JSContext* cx, HandleScript script, const char* filename)
{
// Set the private value associated with a script to a object containing the
// script's filename so that the module loader can use it to resolve
// relative imports.
RootedString path(cx, JS_NewStringCopyZ(cx, filename));
if (!path) {
return false;
}
RootedObject infoObject(cx, JS_NewPlainObject(cx));
if (!infoObject) {
return false;
}
RootedValue pathValue(cx, StringValue(path));
if (!JS_DefineProperty(cx, infoObject, "path", pathValue, 0)) {
return false;
}
JS::SetScriptPrivate(script, ObjectValue(*infoObject));
return true;
}
static MOZ_MUST_USE bool
RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
{
@ -883,6 +910,10 @@ RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
MOZ_ASSERT(script);
}
if (!RegisterScriptPathWithModuleLoader(cx, script, filename)) {
return false;
}
#ifdef DEBUG
if (dumpEntrainedVariables) {
AnalyzeEntrainedVariables(cx, script);
@ -919,6 +950,10 @@ RunBinAST(JSContext* cx, const char* filename, FILE* file)
}
}
if (!RegisterScriptPathWithModuleLoader(cx, script, filename)) {
return false;
}
return JS_ExecuteScript(cx, script);
}
@ -927,7 +962,6 @@ RunBinAST(JSContext* cx, const char* filename, FILE* file)
static bool
InitModuleLoader(JSContext* cx)
{
// Decompress and evaluate the embedded module loader source to initialize
// the module loader for the current compartment.
@ -4723,7 +4757,7 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
}
static JSObject*
CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
ShellModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
{
Handle<GlobalObject*> global = cx->global();
RootedValue hookValue(cx, global->getReservedSlot(GlobalAppSlotModuleResolveHook));
@ -4839,6 +4873,109 @@ ShellGetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
SetModuleDynamicImportHook(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 1) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
"setModuleDynamicImportHook", "0", "s");
return false;
}
if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
const char* typeName = InformalValueTypeName(args[0]);
JS_ReportErrorASCII(cx, "expected hook function, got %s", typeName);
return false;
}
Handle<GlobalObject*> global = cx->global();
global->setReservedSlot(GlobalAppSlotModuleDynamicImportHook, args[0]);
args.rval().setUndefined();
return true;
}
static bool
FinishDynamicModuleImport(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 3) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
"finishDynamicModuleImport", "0", "s");
return false;
}
if (!args[1].isString()) {
return ReportArgumentTypeError(cx, args[1], "String");
}
if (!args[2].isObject() || !args[2].toObject().is<PromiseObject>()) {
return ReportArgumentTypeError(cx, args[2], "PromiseObject");
}
RootedString specifier(cx, args[1].toString());
Rooted<PromiseObject*> promise(cx, &args[2].toObject().as<PromiseObject>());
return js::FinishDynamicModuleImport(cx, args[0], specifier, promise);
}
static bool
AbortDynamicModuleImport(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 4) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
"abortDynamicModuleImport", "0", "s");
return false;
}
if (!args[1].isString()) {
return ReportArgumentTypeError(cx, args[1], "String");
}
if (!args[2].isObject() || !args[2].toObject().is<PromiseObject>()) {
return ReportArgumentTypeError(cx, args[2], "PromiseObject");
}
if (!args[3].isObject() || !args[3].toObject().is<ErrorObject>()) {
return ReportArgumentTypeError(cx, args[3], "ErrorObject");
}
RootedString specifier(cx, args[1].toString());
Rooted<PromiseObject*> promise(cx, &args[2].toObject().as<PromiseObject>());
Rooted<ErrorObject*> error(cx, &args[3].toObject().as<ErrorObject>());
Rooted<Value> value(cx, ObjectValue(*error));
cx->setPendingException(value);
return js::FinishDynamicModuleImport(cx, args[0], specifier, promise);
}
static bool
ShellModuleDynamicImportHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
HandleObject promise)
{
Handle<GlobalObject*> global = cx->global();
RootedValue hookValue(cx, global->getReservedSlot(GlobalAppSlotModuleDynamicImportHook));
if (hookValue.isUndefined()) {
JS_ReportErrorASCII(cx, "Module resolve hook not set");
return false;
}
MOZ_ASSERT(hookValue.toObject().is<JSFunction>());
JS::AutoValueArray<3> args(cx);
args[0].set(referencingPrivate);
args[1].setString(specifier);
args[2].setObject(*promise);
RootedValue result(cx);
if (!JS_CallFunctionValue(cx, nullptr, hookValue, args, &result)) {
return false;
}
return true;
}
static bool
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
{
@ -8059,7 +8196,7 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
" module loader."),
JS_FN_HELP("setModuleResolveHook", SetModuleResolveHook, 1, 0,
"setModuleResolveHook(function(module, specifier) {})",
"setModuleResolveHook(function(referrer, specifier))",
" Set the HostResolveImportedModule hook to |function|.\n"
" This hook is used to look up a previously loaded module object. It should\n"
" be implemented by the module loader."),
@ -8070,6 +8207,22 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
" This hook is used to create the metadata object returned by import.meta for\n"
" a module. It should be implemented by the module loader."),
JS_FN_HELP("setModuleDynamicImportHook", SetModuleDynamicImportHook, 1, 0,
"setModuleDynamicImportHook(function(referrer, specifier, promise))",
" Set the HostImportModuleDynamically hook to |function|.\n"
" This hook is used to dynamically import a module. It should\n"
" be implemented by the module loader."),
JS_FN_HELP("finishDynamicModuleImport", FinishDynamicModuleImport, 3, 0,
"finishDynamicModuleImport(referrer, specifier, promise)",
" The module loader's dynamic import hook should call this when the module has"
" been loaded successfully."),
JS_FN_HELP("abortDynamicModuleImport", AbortDynamicModuleImport, 4, 0,
"abortDynamicModuleImport(referrer, specifier, promise, error)",
" The module loader's dynamic import hook should call this when the module "
" import has failed."),
JS_FN_HELP("setModulePrivate", ShellSetModulePrivate, 2, 0,
"setModulePrivate(scriptObject, privateValue)",
" Associate a private value with a module object.\n"),
@ -10788,7 +10941,8 @@ main(int argc, char** argv, char** envp)
js::SetPreserveWrapperCallback(cx, DummyPreserveWrapperCallback);
JS::SetModuleResolveHook(cx->runtime(), CallModuleResolveHook);
JS::SetModuleResolveHook(cx->runtime(), ShellModuleResolveHook);
JS::SetModuleDynamicImportHook(cx->runtime(), ShellModuleDynamicImportHook);
JS::SetModuleMetadataHook(cx->runtime(), CallModuleMetadataHook);
result = Shell(cx, &op, envp);

Просмотреть файл

@ -372,8 +372,8 @@ class JitTest:
cmd += ['-f', libdir + inc]
if self.skip_if_cond:
cmd += ['-e', "if ({}) quit({})".format(self.skip_if_cond, self.SKIPPED_EXIT_STATUS)]
cmd += ['--module-load-path', moduledir]
if self.is_module:
cmd += ['--module-load-path', moduledir]
cmd += ['--module', path]
elif self.is_binast:
# In builds with BinAST, this will run the test file. In builds without,

Просмотреть файл

@ -3477,6 +3477,23 @@ js::GetModuleObjectForScript(JSScript* script)
return nullptr;
}
Value
js::FindScriptOrModulePrivateForScript(JSScript* script)
{
while (script) {
ScriptSourceObject* sso = &script->scriptSourceUnwrap();
Value value = sso->getPrivate();
if (!value.isUndefined()) {
return value;
}
MOZ_ASSERT(sso->introductionScript() != script);
script = sso->introductionScript();
}
return UndefinedValue();
}
bool
js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc,
MutableHandleValue res)

Просмотреть файл

@ -1182,7 +1182,11 @@ CreateObjectsForEnvironmentChain(JSContext* cx, AutoObjectVector& chain,
HandleObject terminatingEnv,
MutableHandleObject envObj);
ModuleObject* GetModuleObjectForScript(JSScript* script);
ModuleObject*
GetModuleObjectForScript(JSScript* script);
Value
FindScriptOrModulePrivateForScript(JSScript* script);
ModuleEnvironmentObject* GetModuleEnvironmentForScript(JSScript* script);

Просмотреть файл

@ -4724,7 +4724,23 @@ CASE(JSOP_IMPORTMETA)
PUSH_OBJECT(*metaObject);
}
END_CASE(JSOP_NEWTARGET)
END_CASE(JSOP_IMPORTMETA)
CASE(JSOP_DYNAMIC_IMPORT)
{
ReservedRooted<Value> referencingPrivate(&rootValue0);
referencingPrivate = FindScriptOrModulePrivateForScript(script);
ReservedRooted<Value> specifier(&rootValue1);
POP_COPY_TO(specifier);
JSObject* promise = StartDynamicModuleImport(cx, referencingPrivate, specifier);
if (!promise)
goto error;
PUSH_OBJECT(*promise);
}
END_CASE(JSOP_DYNAMIC_IMPORT)
CASE(JSOP_SUPERFUN)
{

Просмотреть файл

@ -2364,14 +2364,23 @@
* Operands:
* Stack: => import.meta
*/ \
macro(JSOP_IMPORTMETA, 232, "importmeta", NULL, 1, 0, 1, JOF_BYTE)
macro(JSOP_IMPORTMETA, 232, "importmeta", NULL, 1, 0, 1, JOF_BYTE) \
/*
* Dynamic import of the module specified by the string value on the top of
* the stack.
*
* Category: Variables and Scopes
* Type: Modules
* Operands:
* Stack: arg => rval
*/ \
macro(JSOP_DYNAMIC_IMPORT, 233, "call-import", NULL, 1, 1, 1, JOF_BYTE)
/*
* In certain circumstances it may be useful to "pad out" the opcode space to
* a power of two. Use this macro to do so.
*/
#define FOR_EACH_TRAILING_UNUSED_OPCODE(macro) \
macro(233) \
macro(234) \
macro(235) \
macro(236) \

Просмотреть файл

@ -176,7 +176,8 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
: js::StackFormat::SpiderMonkey),
wasmInstances(mutexid::WasmRuntimeInstances),
moduleResolveHook(),
moduleMetadataHook()
moduleMetadataHook(),
moduleDynamicImportHook()
{
JS_COUNT_CTOR(JSRuntime);
liveRuntimesCount++;

Просмотреть файл

@ -981,6 +981,10 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
// HostGetImportMetaProperties and HostFinalizeImportMeta.
js::MainThreadData<JS::ModuleMetadataHook> moduleMetadataHook;
// A hook that implements the abstract operation
// HostImportModuleDynamically.
js::MainThreadData<JS::ModuleDynamicImportHook> moduleDynamicImportHook;
public:
#if defined(JS_BUILD_BINAST)
js::BinaryASTSupport& binast() {

Просмотреть файл

@ -1223,12 +1223,6 @@ ModuleScope::getEmptyEnvironmentShape(JSContext* cx)
return EmptyEnvironmentShape(cx, cls, JSSLOT_FREE(cls), ModuleScopeEnvShapeFlags);
}
JSScript*
ModuleScope::script() const
{
return module()->script();
}
static const uint32_t WasmInstanceEnvShapeFlags =
BaseShape::NOT_EXTENSIBLE | BaseShape::DELEGATE;

Просмотреть файл

@ -1027,8 +1027,6 @@ class ModuleScope : public Scope
return data().module;
}
JSScript* script() const;
static Shape* getEmptyEnvironmentShape(JSContext* cx);
};

Просмотреть файл

@ -2183,15 +2183,8 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
RootedString specifier(cx, args[1].toString());
JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook;
if (!moduleResolveHook) {
JS_ReportErrorASCII(cx, "Module resolve hook not set");
return false;
}
RootedObject result(cx);
RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
result = moduleResolveHook(cx, referencingPrivate, specifier);
RootedObject result(cx, CallModuleResolveHook(cx, referencingPrivate, specifier));
if (!result) {
return false;
}

Просмотреть файл

@ -154,13 +154,11 @@ AssertScopeMatchesEnvironment(Scope* scope, JSObject* originalEnv)
MOZ_CRASH("NonSyntactic should not have a syntactic environment");
break;
case ScopeKind::Module: {
ModuleObject* module = &env->as<ModuleEnvironmentObject>().module();
MOZ_ASSERT_IF(module->maybeScript(),
module->script() == si.scope()->as<ModuleScope>().script());
case ScopeKind::Module:
MOZ_ASSERT(&env->as<ModuleEnvironmentObject>().module() ==
si.scope()->as<ModuleScope>().module());
env = &env->as<ModuleEnvironmentObject>().enclosingEnvironment();
break;
}
case ScopeKind::WasmInstance:
env = &env->as<WasmInstanceEnvironmentObject>().enclosingEnvironment();

Просмотреть файл

@ -15,7 +15,7 @@ log = { version = "0.4.4", default-features = false, features = ["release_max_le
env_logger = "0.5.6"
[build-dependencies]
bindgen = {version = "0.39", default-features = false} # disable `logging` to reduce code size
bindgen = {version = "0.43", default-features = false} # disable `logging` to reduce code size
# Uncomment this to enable perf support in release mode.
#[profile.release]

Просмотреть файл

@ -112,6 +112,10 @@ cargo_extra_outputs = {
'bzip2-1.0.6/randtable.o',
'libbz2.a',
],
'clang-sys': [
'common.rs',
'dynamic.rs',
],
'cranelift-codegen': [
'binemit-arm32.rs',
'binemit-arm64.rs',

Просмотреть файл

@ -8,7 +8,7 @@ for (let [key, val] of Object.entries({
// Don't manually modify this line, as it is automatically replaced on merge day
// by the gecko_migration.py script.
WEAVE_VERSION: "1.66.0",
WEAVE_VERSION: "1.67.0",
// Sync Server API version that the client supports.
SYNC_API_VERSION: "1.5",

Просмотреть файл

@ -78,7 +78,7 @@ void = "1.0.2"
[build-dependencies]
lazy_static = "1"
log = "0.4"
bindgen = { version = "0.39", optional = true, default-features = false }
bindgen = { version = "0.43", optional = true, default-features = false }
regex = {version = "1.0", optional = true}
walkdir = "2.1.4"
toml = {version = "0.4.5", optional = true, default-features = false}

Просмотреть файл

@ -0,0 +1,31 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
loader: taskgraph.loader.transform:loader
transforms:
- taskgraph.transforms.bouncer_locations_breakpoint:transforms
- taskgraph.transforms.task:transforms
job-defaults:
description: nightly bouncer locations breakpoint job
attributes:
build_platform: linux64-nightly
nightly: true
worker-type:
by-project:
mozilla-central: null-provisioner/human-breakpoint
default: invalid/invalid
worker:
implementation: bouncer-locations-breakpoint
run-on-projects: ['mozilla-central']
treeherder:
symbol: BncLoc-Br
kind: other
tier: 2
jobs:
firefox:
treeherder:
platform: firefox-release/opt

Просмотреть файл

@ -8,6 +8,9 @@ transforms:
- taskgraph.transforms.bouncer_locations:transforms
- taskgraph.transforms.task:transforms
kind-dependencies:
- bouncer-locations-breakpoint
job-defaults:
description: nightly bouncer locations job
attributes:

Просмотреть файл

@ -311,6 +311,10 @@ bouncer-locations
-----------------
Updates nightly bouncer locations for version bump
bouncer-locations-breakpoint
----------------------------
Human breakpoint to block the running of the bouncer locations job until shippable builds are implemented
release-bouncer-check
---------------------
Checks Bouncer (download.mozilla.org) uptake as part of the release tasks.

Просмотреть файл

@ -28,6 +28,12 @@ def make_task_worker(config, jobs):
)
job['worker']['bouncer-products'] = job['bouncer-products']
del job['bouncer-products']
# chain the breakpoint as dependency to this task
dependencies = {}
for dep_task in config.kind_dependencies_tasks:
dependencies[dep_task.kind] = dep_task.label
job.setdefault('dependencies', {}).update(dependencies)
yield job

Просмотреть файл

@ -0,0 +1,24 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, print_function, unicode_literals
import logging
from taskgraph.transforms.base import TransformSequence
from taskgraph.util.schema import resolve_keyed_by
logger = logging.getLogger(__name__)
transforms = TransformSequence()
@transforms.add
def make_task_worker(config, jobs):
for job in jobs:
resolve_keyed_by(
job, 'worker-type', item_name=job['name'], project=config.params['project']
)
job['worker']['payload'] = {}
yield job

Просмотреть файл

@ -571,6 +571,9 @@ task_description_schema = Schema({
}, {
Required('implementation'): 'bouncer-locations',
Required('bouncer-products'): [basestring],
}, {
Required('implementation'): 'bouncer-locations-breakpoint',
Required('payload'): object,
}, {
Required('implementation'): 'bouncer-submission',
Required('locales'): [basestring],
@ -1215,6 +1218,11 @@ def build_bouncer_locations_payload(config, task, task_def):
}
@payload_builder('bouncer-locations-breakpoint')
def build_bouncer_locations_breakpoint_payload(config, task, task_def):
task_def['payload'] = task['worker']['payload']
@payload_builder('bouncer-submission')
def build_bouncer_submission_payload(config, task, task_def):
worker = task['worker']

Просмотреть файл

@ -51,7 +51,18 @@ Documentation
* [Enabling trace logs](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/TraceLogs.html)
* [Analyzing crash data from Firefox](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/CrashReports.html)
* [Contributing](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/index.html#for-developers)
* [Contributing](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/#for-developers)
Source code
-----------
geckodrivers canonical source code can be found in [mozilla-central].
We only use this GitHub repository for issue tracking and making releases.
See our [contribution documentation] for more information.
[mozilla-central]: https://hg.mozilla.org/mozilla-central/file/tip/testing/geckodriver
[contribution documentation]: https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/#for-developers
Contact

Просмотреть файл

@ -73,7 +73,7 @@ promise_test(() => {
}, "Stray argument");
promise_test(() => {
const buffer = new WasmModuleBuilder().toBuffer();
const buffer = new Uint8Array(new WasmModuleBuilder().toBuffer());
assert_equals(buffer[0], 0);
const promise = WebAssembly.compile(buffer);
buffer[0] = 1;

Просмотреть файл

@ -103,7 +103,7 @@ promise_test(t => {
}, "Invalid code");
promise_test(() => {
const buffer = new WasmModuleBuilder().toBuffer();
const buffer = new Uint8Array(new WasmModuleBuilder().toBuffer());
assert_equals(buffer[0], 0);
const promise = WebAssembly.instantiate(buffer);
buffer[0] = 1;

Просмотреть файл

@ -133,18 +133,14 @@ const instanceTestFactory = [
builder
.addFunction("fn", kSig_v_d)
.addBody([
kExprEnd
])
.addBody([])
.exportFunc();
builder
.addFunction("fn2", kSig_v_v)
.addBody([
kExprEnd
])
.addBody([])
.exportFunc();
builder.setFunctionTableLength(1);
builder.setTableLength(1);
builder.addExportOfKind("table", kExternalTable, 0);
builder.addGlobal(kWasmI32, true)
@ -190,7 +186,6 @@ const instanceTestFactory = [
kExprGetGlobal,
index,
kExprReturn,
kExprEnd,
])
.exportFunc();

Просмотреть файл

@ -92,18 +92,14 @@ test(() => {
builder
.addFunction("fn", kSig_v_v)
.addBody([
kExprEnd
])
.addBody([])
.exportFunc();
builder
.addFunction("fn2", kSig_v_v)
.addBody([
kExprEnd
])
.addBody([])
.exportFunc();
builder.setFunctionTableLength(1);
builder.setTableLength(1);
builder.addExportOfKind("table", kExternalTable, 0);
builder.addGlobal(kWasmI32, true)

Просмотреть файл

@ -9,15 +9,11 @@ setup(() => {
builder
.addFunction("fn", kSig_v_d)
.addBody([
kExprEnd
])
.addBody([])
.exportFunc();
builder
.addFunction("fn2", kSig_v_v)
.addBody([
kExprEnd
])
.addBody([])
.exportFunc();
const buffer = builder.toBuffer()

Просмотреть файл

@ -21,7 +21,7 @@ var kWasmH1 = 0x61;
var kWasmH2 = 0x73;
var kWasmH3 = 0x6d;
var kWasmV0 = 1;
var kWasmV0 = 0x1;
var kWasmV1 = 0;
var kWasmV2 = 0;
var kWasmV3 = 0;
@ -65,10 +65,15 @@ let kCodeSectionCode = 10; // Function code
let kDataSectionCode = 11; // Data segments
let kNameSectionCode = 12; // Name section (encoded as string)
// Name section types
let kModuleNameCode = 0;
let kFunctionNamesCode = 1;
let kLocalNamesCode = 2;
let kWasmFunctionTypeForm = 0x60;
let kWasmAnyFunctionTypeForm = 0x70;
let kResizableMaximumFlag = 1;
let kHasMaximumFlag = 1;
// Function declaration flags
let kDeclFunctionName = 0x01;
@ -82,7 +87,6 @@ let kWasmI32 = 0x7f;
let kWasmI64 = 0x7e;
let kWasmF32 = 0x7d;
let kWasmF64 = 0x7c;
let kWasmS128 = 0x7b;
let kExternalFunction = 0;
let kExternalTable = 1;
@ -104,7 +108,7 @@ let kSig_i_dd = makeSig([kWasmF64, kWasmF64], [kWasmI32]);
let kSig_v_v = makeSig([], []);
let kSig_i_v = makeSig([], [kWasmI32]);
let kSig_l_v = makeSig([], [kWasmI64]);
let kSig_f_v = makeSig([], [kWasmF64]);
let kSig_f_v = makeSig([], [kWasmF32]);
let kSig_d_v = makeSig([], [kWasmF64]);
let kSig_v_i = makeSig([kWasmI32], []);
let kSig_v_ii = makeSig([kWasmI32, kWasmI32], []);
@ -113,7 +117,6 @@ let kSig_v_l = makeSig([kWasmI64], []);
let kSig_v_d = makeSig([kWasmF64], []);
let kSig_v_dd = makeSig([kWasmF64, kWasmF64], []);
let kSig_v_ddi = makeSig([kWasmF64, kWasmF64, kWasmI32], []);
let kSig_s_v = makeSig([], [kWasmS128]);
function makeSig(params, results) {
return {params: params, results: results};
@ -191,7 +194,7 @@ let kExprI64StoreMem8 = 0x3c;
let kExprI64StoreMem16 = 0x3d;
let kExprI64StoreMem32 = 0x3e;
let kExprMemorySize = 0x3f;
let kExprGrowMemory = 0x40;
let kExprMemoryGrow = 0x40;
let kExprI32Eqz = 0x45;
let kExprI32Eq = 0x46;
let kExprI32Ne = 0x47;
@ -339,36 +342,34 @@ let kTrapMsgs = [
];
function assertTraps(trap, code) {
var threwException = true;
try {
if (typeof code === 'function') {
code();
} else {
eval(code);
}
threwException = false;
} catch (e) {
assertEquals("object", typeof e);
assertEquals(kTrapMsgs[trap], e.message);
// Success.
return;
try {
if (typeof code === 'function') {
code();
} else {
eval(code);
}
throw new MjsUnitAssertionError("Did not trap, expected: " + kTrapMsgs[trap]);
} catch (e) {
assertEquals('object', typeof e);
assertEquals(kTrapMsgs[trap], e.message);
// Success.
return;
}
throw new MjsUnitAssertionError('Did not trap, expected: ' + kTrapMsgs[trap]);
}
function assertWasmThrows(value, code) {
assertEquals("number", typeof(value));
try {
if (typeof code === 'function') {
code();
} else {
eval(code);
}
} catch (e) {
assertEquals("number", typeof e);
assertEquals(value, e);
// Success.
return;
assertEquals('number', typeof value);
try {
if (typeof code === 'function') {
code();
} else {
eval(code);
}
throw new MjsUnitAssertionError("Did not throw at all, expected: " + value);
} catch (e) {
assertEquals('number', typeof e);
assertEquals(value, e);
// Success.
return;
}
throw new MjsUnitAssertionError('Did not throw, expected: ' + value);
}

Просмотреть файл

@ -69,12 +69,14 @@ class Binary extends Array {
// Emit section name.
this.emit_u8(section_code);
// Emit the section to a temporary buffer: its full length isn't know yet.
let section = new Binary;
const section = new Binary;
content_generator(section);
// Emit section length.
this.emit_u32v(section.length);
// Copy the temporary buffer.
this.push(...section);
for (const b of section) {
this.push(b);
}
}
}
@ -86,6 +88,15 @@ class WasmFunctionBuilder {
this.body = [];
}
numLocalNames() {
if (this.local_names === undefined) return 0;
let num_local_names = 0;
for (let loc_name of this.local_names) {
if (loc_name !== undefined) ++num_local_names;
}
return num_local_names;
}
exportAs(name) {
this.module.addExport(name, this.index);
return this;
@ -97,12 +108,40 @@ class WasmFunctionBuilder {
}
addBody(body) {
for (let b of body) {
if (typeof b !== 'number' || (b & (~0xFF)) !== 0 )
throw new Error('invalid body (entries must be 8 bit numbers): ' + body);
}
this.body = body.slice();
// Automatically add the end for the function block to the body.
this.body.push(kExprEnd);
return this;
}
addBodyWithEnd(body) {
this.body = body;
return this;
}
addLocals(locals) {
this.locals = locals;
getNumLocals() {
let total_locals = 0;
for (let l of this.locals || []) {
for (let type of ["i32", "i64", "f32", "f64"]) {
total_locals += l[type + "_count"] || 0;
}
}
return total_locals;
}
addLocals(locals, names) {
const old_num_locals = this.getNumLocals();
if (!this.locals) this.locals = []
this.locals.push(locals);
if (names) {
if (!this.local_names) this.local_names = [];
const missing_names = old_num_locals - this.local_names.length;
this.local_names.push(...new Array(missing_names), ...names);
}
return this;
}
@ -133,10 +172,10 @@ class WasmModuleBuilder {
this.exports = [];
this.globals = [];
this.functions = [];
this.function_table = [];
this.function_table_length = 0;
this.function_table_inits = [];
this.segments = [];
this.table_length_min = 0;
this.table_length_max = undefined;
this.element_segments = [];
this.data_segments = [];
this.explicit = [];
this.num_imported_funcs = 0;
this.num_imported_globals = 0;
@ -158,6 +197,22 @@ class WasmModuleBuilder {
return this;
}
stringToBytes(name) {
var result = new Binary();
result.emit_u32v(name.length);
for (var i = 0; i < name.length; i++) {
result.emit_u8(name.charCodeAt(i));
}
return result;
}
addCustomSection(name, bytes) {
name = this.stringToBytes(name);
var length = new Binary();
length.emit_u32v(name.length + bytes.length);
this.explicit.push([0, ...length, ...name, ...bytes]);
}
addType(type) {
// TODO: canonicalize types?
this.types.push(type);
@ -180,15 +235,21 @@ class WasmModuleBuilder {
}
addImport(module = "", name, type) {
if (this.functions.length != 0) {
throw new Error('Imported functions must be declared before local ones');
}
let type_index = (typeof type) == "number" ? type : this.addType(type);
this.imports.push({module: module, name: name, kind: kExternalFunction,
type: type_index});
return this.num_imported_funcs++;
}
addImportedGlobal(module = "", name, type) {
addImportedGlobal(module = "", name, type, mutable = false) {
if (this.globals.length != 0) {
throw new Error('Imported globals must be declared before local ones');
}
let o = {module: module, name: name, kind: kExternalGlobal, type: type,
mutable: false}
mutable: mutable};
this.imports.push(o);
return this.num_imported_globals++;
}
@ -217,32 +278,51 @@ class WasmModuleBuilder {
}
addDataSegment(addr, data, is_global = false) {
this.segments.push({addr: addr, data: data, is_global: is_global});
return this.segments.length - 1;
this.data_segments.push({addr: addr, data: data, is_global: is_global});
return this.data_segments.length - 1;
}
exportMemoryAs(name) {
this.exports.push({name: name, kind: kExternalMemory, index: 0});
}
addFunctionTableInit(base, is_global, array) {
this.function_table_inits.push({base: base, is_global: is_global,
addElementSegment(base, is_global, array, is_import = false) {
this.element_segments.push({base: base, is_global: is_global,
array: array});
if (!is_global) {
var length = base + array.length;
if (length > this.function_table_length) {
this.function_table_length = length;
if (length > this.table_length_min && !is_import) {
this.table_length_min = length;
}
if (length > this.table_length_max && !is_import) {
this.table_length_max = length;
}
}
return this;
}
appendToTable(array) {
return this.addFunctionTableInit(this.function_table.length, false, array);
for (let n of array) {
if (typeof n != 'number')
throw new Error('invalid table (entries have to be numbers): ' + array);
}
return this.addElementSegment(this.table_length_min, false, array);
}
setFunctionTableLength(length) {
this.function_table_length = length;
setTableBounds(min, max) {
this.table_length_min = min;
this.table_length_max = max;
return this;
}
setTableLength(length) {
this.table_length_min = length;
this.table_length_max = length;
return this;
}
setName(name) {
this.name = name;
return this;
}
@ -305,40 +385,39 @@ class WasmModuleBuilder {
}
// Add functions declarations
let has_names = false;
let names = false;
if (wasm.functions.length > 0) {
if (debug) print("emitting function decls @ " + binary.length);
binary.emit_section(kFunctionSectionCode, section => {
section.emit_u32v(wasm.functions.length);
for (let func of wasm.functions) {
has_names = has_names || (func.name != undefined &&
func.name.length > 0);
section.emit_u32v(func.type_index);
}
});
}
// Add function_table.
if (wasm.function_table_length > 0) {
// Add table section
if (wasm.table_length_min > 0) {
if (debug) print("emitting table @ " + binary.length);
binary.emit_section(kTableSectionCode, section => {
section.emit_u8(1); // one table entry
section.emit_u8(kWasmAnyFunctionTypeForm);
section.emit_u8(1);
section.emit_u32v(wasm.function_table_length);
section.emit_u32v(wasm.function_table_length);
const max = wasm.table_length_max;
const has_max = max !== undefined;
section.emit_u8(has_max ? kHasMaximumFlag : 0);
section.emit_u32v(wasm.table_length_min);
if (has_max) section.emit_u32v(max);
});
}
// Add memory section
if (wasm.memory != undefined) {
if (wasm.memory !== undefined) {
if (debug) print("emitting memory @ " + binary.length);
binary.emit_section(kMemorySectionCode, section => {
section.emit_u8(1); // one memory entry
section.emit_u32v(kResizableMaximumFlag);
const has_max = wasm.memory.max !== undefined;
section.emit_u8(has_max ? kHasMaximumFlag : 0);
section.emit_u32v(wasm.memory.min);
section.emit_u32v(wasm.memory.max);
if (has_max) section.emit_u32v(wasm.memory.max);
});
}
@ -359,7 +438,7 @@ class WasmModuleBuilder {
break;
case kWasmI64:
section.emit_u8(kExprI64Const);
section.emit_u8(global.init);
section.emit_u32v(global.init);
break;
case kWasmF32:
section.emit_u8(kExprF32Const);
@ -393,7 +472,7 @@ class WasmModuleBuilder {
}
// Add export table.
var mem_export = (wasm.memory != undefined && wasm.memory.exp);
var mem_export = (wasm.memory !== undefined && wasm.memory.exp);
var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
if (exports_count > 0) {
if (debug) print("emitting exports @ " + binary.length);
@ -413,22 +492,22 @@ class WasmModuleBuilder {
}
// Add start function section.
if (wasm.start_index != undefined) {
if (wasm.start_index !== undefined) {
if (debug) print("emitting start function @ " + binary.length);
binary.emit_section(kStartSectionCode, section => {
section.emit_u32v(wasm.start_index);
});
}
// Add table elements.
if (wasm.function_table_inits.length > 0) {
if (debug) print("emitting table @ " + binary.length);
// Add element segments
if (wasm.element_segments.length > 0) {
if (debug) print("emitting element segments @ " + binary.length);
binary.emit_section(kElementSectionCode, section => {
var inits = wasm.function_table_inits;
var inits = wasm.element_segments;
section.emit_u32v(inits.length);
section.emit_u8(0); // table index
for (let init of inits) {
section.emit_u8(0); // table index
if (init.is_global) {
section.emit_u8(kExprGetGlobal);
} else {
@ -453,9 +532,7 @@ class WasmModuleBuilder {
for (let func of wasm.functions) {
// Function body length will be patched later.
let local_decls = [];
let l = func.locals;
if (l != undefined) {
let local_decls_count = 0;
for (let l of func.locals || []) {
if (l.i32_count > 0) {
local_decls.push({count: l.i32_count, type: kWasmI32});
}
@ -485,11 +562,11 @@ class WasmModuleBuilder {
}
// Add data segments.
if (wasm.segments.length > 0) {
if (wasm.data_segments.length > 0) {
if (debug) print("emitting data segments @ " + binary.length);
binary.emit_section(kDataSectionCode, section => {
section.emit_u32v(wasm.segments.length);
for (let seg of wasm.segments) {
section.emit_u32v(wasm.data_segments.length);
for (let seg of wasm.data_segments) {
section.emit_u8(0); // linear memory index 0
if (seg.is_global) {
// initializer is a global variable
@ -513,21 +590,50 @@ class WasmModuleBuilder {
binary.emit_bytes(exp);
}
// Add function names.
if (has_names) {
if (debug) print("emitting names @ " + binary.length);
// Add names.
let num_function_names = 0;
let num_functions_with_local_names = 0;
for (let func of wasm.functions) {
if (func.name !== undefined) ++num_function_names;
if (func.numLocalNames() > 0) ++num_functions_with_local_names;
}
if (num_function_names > 0 || num_functions_with_local_names > 0 ||
wasm.name !== undefined) {
if (debug) print('emitting names @ ' + binary.length);
binary.emit_section(kUnknownSectionCode, section => {
section.emit_string("name");
var count = wasm.functions.length + wasm.num_imported_funcs;
section.emit_u32v(count);
for (var i = 0; i < wasm.num_imported_funcs; i++) {
section.emit_u8(0); // empty string
section.emit_u8(0); // local names count == 0
section.emit_string('name');
// Emit module name.
if (wasm.name !== undefined) {
section.emit_section(kModuleNameCode, name_section => {
name_section.emit_string(wasm.name);
});
}
for (let func of wasm.functions) {
var name = func.name == undefined ? "" : func.name;
section.emit_string(name);
section.emit_u8(0); // local names count == 0
// Emit function names.
if (num_function_names > 0) {
section.emit_section(kFunctionNamesCode, name_section => {
name_section.emit_u32v(num_function_names);
for (let func of wasm.functions) {
if (func.name === undefined) continue;
name_section.emit_u32v(func.index);
name_section.emit_string(func.name);
}
});
}
// Emit local names.
if (num_functions_with_local_names > 0) {
section.emit_section(kLocalNamesCode, name_section => {
name_section.emit_u32v(num_functions_with_local_names);
for (let func of wasm.functions) {
if (func.numLocalNames() == 0) continue;
name_section.emit_u32v(func.index);
name_section.emit_u32v(func.numLocalNames());
for (let i = 0; i < func.local_names.length; ++i) {
if (func.local_names[i] === undefined) continue;
name_section.emit_u32v(i);
name_section.emit_string(func.local_names[i]);
}
}
});
}
});
}
@ -544,12 +650,21 @@ class WasmModuleBuilder {
if ((typeof val) == "string") val = val.charCodeAt(0);
view[i] = val | 0;
}
return new Uint8Array(buffer);
return buffer;
}
instantiate(...args) {
instantiate(ffi) {
let module = new WebAssembly.Module(this.toBuffer());
let instance = new WebAssembly.Instance(module, ...args);
let instance = new WebAssembly.Instance(module, ffi);
return instance;
}
asyncInstantiate(ffi) {
return WebAssembly.instantiate(this.toBuffer(), ffi)
.then(({module, instance}) => instance);
}
toModule(debug = false) {
return new WebAssembly.Module(this.toBuffer(debug));
}
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

5
third_party/rust/bindgen/.cargo_vcs_info.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
{
"git": {
"sha1": "a242c51e6ff0d4cc27940a3927e713e8dff82c5f"
}
}

6
third_party/rust/bindgen/Cargo.toml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "bindgen"
version = "0.39.0"
version = "0.43.0"
authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"]
build = "build.rs"
include = ["LICENSE", "README.md", "Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"]
@ -36,13 +36,13 @@ doc = false
version = "1.0.3"
[dependencies.cexpr]
version = "0.2"
version = "0.3.3"
[dependencies.cfg-if]
version = "0.1.0"
[dependencies.clang-sys]
version = "0.23"
version = "0.26"
features = ["runtime", "clang_6_0"]
[dependencies.clap]

36
third_party/rust/bindgen/src/clang.rs поставляемый
Просмотреть файл

@ -12,7 +12,7 @@ use std::ffi::{CStr, CString};
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::os::raw::{c_char, c_int, c_uint, c_ulong};
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_longlong, c_ulonglong};
/// A cursor into the Clang AST, pointing to an AST node.
///
@ -940,6 +940,7 @@ impl Type {
CXType_RValueReference |
CXType_LValueReference |
CXType_MemberPointer |
CXType_BlockPointer |
CXType_ObjCObjectPointer => {
let ret = Type {
x: unsafe { clang_getPointeeType(self.x) },
@ -1786,13 +1787,34 @@ impl EvalResult {
}
/// Try to get back the result as an integer.
pub fn as_int(&self) -> Option<i32> {
match self.kind() {
CXEval_Int => {
Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i32)
}
_ => None,
pub fn as_int(&self) -> Option<i64> {
if self.kind() != CXEval_Int {
return None;
}
if !clang_EvalResult_isUnsignedInt::is_loaded() {
// FIXME(emilio): There's no way to detect underflow here, and clang
// will just happily give us a value.
return Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i64)
}
if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 {
let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) };
if value > i64::max_value() as c_ulonglong {
return None;
}
return Some(value as i64)
}
let value = unsafe { clang_EvalResult_getAsLongLong(self.x) };
if value > i64::max_value() as c_longlong {
return None;
}
if value < i64::min_value() as c_longlong {
return None;
}
Some(value as i64)
}
/// Evaluates the expression as a literal string, that may or may not be

Просмотреть файл

@ -59,14 +59,14 @@ pub mod attributes {
/// Generates a proper type for a field or type with a given `Layout`, that is,
/// a type with the correct size and alignment restrictions.
pub fn blob(layout: Layout) -> quote::Tokens {
pub fn blob(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
let opaque = layout.opaque();
// FIXME(emilio, #412): We fall back to byte alignment, but there are
// some things that legitimately are more than 8-byte aligned.
//
// Eventually we should be able to `unwrap` here, but...
let ty_name = match opaque.known_rust_type_for_array() {
let ty_name = match opaque.known_rust_type_for_array(ctx) {
Some(ty) => ty,
None => {
warn!("Found unknown alignment on code generation!");
@ -76,7 +76,7 @@ pub fn blob(layout: Layout) -> quote::Tokens {
let ty_name = Term::new(ty_name, Span::call_site());
let data_len = opaque.array_size().unwrap_or(layout.size);
let data_len = opaque.array_size(ctx).unwrap_or(layout.size);
if data_len == 1 {
quote! {
@ -90,8 +90,8 @@ pub fn blob(layout: Layout) -> quote::Tokens {
}
/// Integer type of the same size as the given `Layout`.
pub fn integer_type(layout: Layout) -> Option<quote::Tokens> {
let name = Layout::known_type_for_size(layout.size)?;
pub fn integer_type(ctx: &BindgenContext, layout: Layout) -> Option<quote::Tokens> {
let name = Layout::known_type_for_size(ctx, layout.size)?;
let name = Term::new(name, Span::call_site());
Some(quote! { #name })
}
@ -122,6 +122,7 @@ pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
pub mod ast_ty {
use ir::context::BindgenContext;
use ir::function::FunctionSig;
use ir::layout::Layout;
use ir::ty::FloatKind;
use quote;
use proc_macro2;
@ -144,22 +145,44 @@ pub mod ast_ty {
pub fn float_kind_rust_type(
ctx: &BindgenContext,
fk: FloatKind,
layout: Option<Layout>,
) -> quote::Tokens {
// TODO: we probably should just take the type layout into
// account?
// TODO: we probably should take the type layout into account more
// often?
//
// Also, maybe this one shouldn't be the default?
//
// FIXME: `c_longdouble` doesn't seem to be defined in some
// systems, so we use `c_double` directly.
match (fk, ctx.options().convert_floats) {
(FloatKind::Float, true) => quote! { f32 },
(FloatKind::Double, true) |
(FloatKind::LongDouble, true) => quote! { f64 },
(FloatKind::Double, true) => quote! { f64 },
(FloatKind::Float, false) => raw_type(ctx, "c_float"),
(FloatKind::Double, false) |
(FloatKind::LongDouble, false) => raw_type(ctx, "c_double"),
(FloatKind::Float128, _) => quote! { [u8; 16] },
(FloatKind::Double, false) => raw_type(ctx, "c_double"),
(FloatKind::LongDouble, _) => {
match layout {
Some(layout) => {
match layout.size {
4 => quote! { f32 },
8 => quote! { f64 },
// TODO(emilio): If rust ever gains f128 we should
// use it here and below.
_ => super::integer_type(ctx, layout).unwrap_or(quote! { f64 }),
}
}
None => {
debug_assert!(
false,
"How didn't we know the layout for a primitive type?"
);
quote! { f64 }
}
}
}
(FloatKind::Float128, _) => {
if ctx.options().rust_features.i128_and_u128 {
quote! { u128 }
} else {
quote! { [u64; 2] }
}
}
}
}

Просмотреть файл

@ -42,8 +42,10 @@ pub fn gen_debug_impl(
format_string.push_str(" }}");
tokens.insert(0, quote! { #format_string });
let prefix = ctx.trait_prefix();
quote! {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fn fmt(&self, f: &mut ::#prefix::fmt::Formatter<'_>) -> ::#prefix ::fmt::Result {
write!(f, #( #tokens ),*)
}
}
@ -154,7 +156,6 @@ impl<'a> ImplDebug<'a> for Item {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::BlockPointer |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
@ -184,32 +185,49 @@ impl<'a> ImplDebug<'a> for Item {
// The simple case
debug_print(name, quote! { #name_ident })
} else {
// Let's implement our own print function
Some((
format!("{}: [{{}}]", name),
vec![quote! {
self.#name_ident
.iter()
.enumerate()
.map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
.collect::<String>()
}],
))
if ctx.options().use_core {
// There is no String in core; reducing field visibility to avoid breaking
// no_std setups.
Some((
format!("{}: [...]", name), vec![]
))
} else {
// Let's implement our own print function
Some((
format!("{}: [{{}}]", name),
vec![quote! {
self.#name_ident
.iter()
.enumerate()
.map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v))
.collect::<String>()
}],
))
}
}
}
TypeKind::Vector(_, len) => {
let self_ids = 0..len;
Some((
format!("{}({{}})", name),
vec![quote! {
#(format!("{:?}", self.#self_ids)),*
}]
))
if ctx.options().use_core {
// There is no format! in core; reducing field visibility to avoid breaking
// no_std setups.
Some((
format!("{}(...)", name), vec![]
))
} else {
let self_ids = 0..len;
Some((
format!("{}({{}})", name),
vec![quote! {
#(format!("{:?}", self.#self_ids)),*
}]
))
}
}
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
// We follow the aliases
ctx.resolve_item(t).impl_debug(ctx, name)
}
@ -218,7 +236,7 @@ impl<'a> ImplDebug<'a> for Item {
let inner_type = ctx.resolve_type(inner).canonical_type(ctx);
match *inner_type.kind() {
TypeKind::Function(ref sig)
if !sig.can_trivially_derive_debug() => {
if !sig.can_trivially_derive_debug(ctx) => {
Some((format!("{}: FunctionPointer", name), vec![]))
}
_ => debug_print(name, quote! { #name_ident }),

Просмотреть файл

@ -88,7 +88,6 @@ fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens
TypeKind::Enum(..) |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
@ -125,7 +124,8 @@ fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
let inner_item = ctx.resolve_item(t);
gen_field(ctx, inner_item, name)
}

248
third_party/rust/bindgen/src/codegen/mod.rs поставляемый
Просмотреть файл

@ -7,7 +7,7 @@ pub mod struct_layout;
#[cfg(test)]
#[allow(warnings)]
pub(crate) mod bitfield_unit;
#[cfg(test)]
#[cfg(all(test, target_endian = "little"))]
mod bitfield_unit_tests;
use self::helpers::attributes;
@ -103,6 +103,9 @@ struct CodegenResult<'a> {
/// Whether Objective C types have been seen at least once.
saw_objc: bool,
/// Whether Apple block types have been seen at least once.
saw_block: bool,
/// Whether a bitfield allocation unit has been seen at least once.
saw_bitfield_unit: bool,
@ -140,6 +143,7 @@ impl<'a> CodegenResult<'a> {
saw_bindgen_union: false,
saw_incomplete_array: false,
saw_objc: false,
saw_block: false,
saw_bitfield_unit: false,
codegen_id: codegen_id,
items_seen: Default::default(),
@ -166,6 +170,10 @@ impl<'a> CodegenResult<'a> {
self.saw_objc = true;
}
fn saw_block(&mut self) {
self.saw_block = true;
}
fn saw_bitfield_unit(&mut self) {
self.saw_bitfield_unit = true;
}
@ -215,6 +223,7 @@ impl<'a> CodegenResult<'a> {
self.saw_union |= new.saw_union;
self.saw_incomplete_array |= new.saw_incomplete_array;
self.saw_objc |= new.saw_objc;
self.saw_block |= new.saw_block;
self.saw_bitfield_unit |= new.saw_bitfield_unit;
new.items
@ -293,7 +302,6 @@ impl AppendImplicitTemplateParams for quote::Tokens {
TypeKind::Opaque |
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::BlockPointer |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::TemplateInstantiation(..) => return,
@ -394,6 +402,9 @@ impl CodeGenerator for Module {
}
if item.id() == ctx.root_module() {
if result.saw_block {
utils::prepend_block_header(ctx, &mut *result);
}
if result.saw_bindgen_union {
utils::prepend_union_types(ctx, &mut *result);
}
@ -564,10 +575,16 @@ impl CodeGenerator for Var {
attrs.push(attributes::link_name(self.name()));
}
let maybe_mut = if self.is_const() {
quote! { }
} else {
quote! { mut }
};
let mut tokens = quote!(
extern "C" {
#(#attrs)*
pub static mut #canonical_ident: #ty;
pub static #maybe_mut #canonical_ident: #ty;
}
);
@ -597,7 +614,6 @@ impl CodeGenerator for Type {
TypeKind::Array(..) |
TypeKind::Vector(..) |
TypeKind::Pointer(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::Function(..) |
TypeKind::ResolvedTypeRef(..) |
@ -610,6 +626,39 @@ impl CodeGenerator for Type {
TypeKind::TemplateInstantiation(ref inst) => {
inst.codegen(ctx, result, item)
}
TypeKind::BlockPointer(inner) => {
if !ctx.options().generate_block {
return;
}
let inner_item = inner.into_resolver()
.through_type_refs()
.resolve(ctx);
let name = item.canonical_name(ctx);
let inner_rust_type = {
if let TypeKind::Function(fnsig) = inner_item.kind().expect_type().kind() {
utils::fnsig_block(ctx, fnsig)
} else {
panic!("invalid block typedef: {:?}", inner_item)
}
};
let rust_name = ctx.rust_ident(&name);
let mut tokens = if let Some(comment) = item.comment(ctx) {
attributes::doc(comment)
} else {
quote! {}
};
tokens.append_all(quote! {
pub type #rust_name = #inner_rust_type ;
});
result.push(tokens);
result.saw_block();
}
TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item),
TypeKind::TemplateAlias(inner, _) |
TypeKind::Alias(inner) => {
@ -1146,7 +1195,7 @@ impl Bitfield {
let bitfield_ty_layout = bitfield_ty.layout(ctx).expect(
"Bitfield without layout? Gah!",
);
let bitfield_int_ty = helpers::blob(bitfield_ty_layout);
let bitfield_int_ty = helpers::blob(ctx, bitfield_ty_layout);
let offset = self.offset_into_unit();
let width = self.width() as u8;
@ -1328,7 +1377,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
let bitfield_ty_layout = bitfield_ty.layout(ctx).expect(
"Bitfield without layout? Gah!",
);
let bitfield_int_ty = match helpers::integer_type(bitfield_ty_layout) {
let bitfield_int_ty = match helpers::integer_type(ctx, bitfield_ty_layout) {
Some(int_ty) => {
*bitfield_representable_as_int = true;
int_ty
@ -1501,27 +1550,6 @@ impl CodeGenerator for CompInfo {
let is_union = self.kind() == CompKind::Union;
let layout = item.kind().expect_type().layout(ctx);
if is_union && !is_opaque && !self.is_forward_declaration() {
result.saw_union();
if !self.can_be_rust_union(ctx) {
result.saw_bindgen_union();
}
let layout = layout.expect("Unable to get layout information?");
let ty = helpers::blob(layout);
fields.push(if self.can_be_rust_union(ctx) {
quote! {
_bindgen_union_align: #ty ,
}
} else {
struct_layout.saw_union(layout);
quote! {
pub bindgen_union_field: #ty ,
}
});
}
let mut explicit_align = None;
if is_opaque {
@ -1533,7 +1561,7 @@ impl CodeGenerator for CompInfo {
Some(l) => {
explicit_align = Some(l.align);
let ty = helpers::blob(l);
let ty = helpers::blob(ctx, l);
fields.push(quote! {
pub _bindgen_opaque_blob: #ty ,
});
@ -1556,7 +1584,7 @@ impl CodeGenerator for CompInfo {
} else {
explicit_align = Some(layout.align);
if !ctx.options().rust_features.repr_align {
let ty = helpers::blob(Layout::new(0, layout.align));
let ty = helpers::blob(ctx, Layout::new(0, layout.align));
fields.push(quote! {
pub __bindgen_align: #ty ,
});
@ -1564,6 +1592,32 @@ impl CodeGenerator for CompInfo {
}
}
}
} else if is_union && !self.is_forward_declaration() {
result.saw_union();
if !self.can_be_rust_union(ctx) {
result.saw_bindgen_union();
}
// TODO(emilio): It'd be nice to unify this with the struct path
// above somehow.
let layout = layout.expect("Unable to get layout information?");
if struct_layout.requires_explicit_align(layout) {
explicit_align = Some(layout.align);
}
let ty = helpers::blob(ctx, layout);
fields.push(if self.can_be_rust_union(ctx) {
quote! {
_bindgen_union_align: #ty ,
}
} else {
struct_layout.saw_union(layout);
quote! {
pub bindgen_union_field: #ty ,
}
});
}
// C++ requires every struct to be addressable, so what C++ compilers do
@ -1590,7 +1644,7 @@ impl CodeGenerator for CompInfo {
};
if has_address {
let ty = helpers::blob(Layout::new(1, 1));
let ty = helpers::blob(ctx, Layout::new(1, 1));
fields.push(quote! {
pub _address: #ty,
});
@ -1747,7 +1801,7 @@ impl CodeGenerator for CompInfo {
// all the tests to shit when parsing things like max_align_t.
if self.found_unknown_attr() {
warn!(
"Type {} has an unkown attribute that may affect layout",
"Type {} has an unknown attribute that may affect layout",
canonical_ident.as_str()
);
}
@ -1920,8 +1974,10 @@ impl CodeGenerator for CompInfo {
self.kind(),
);
let prefix = ctx.trait_prefix();
result.push(quote! {
impl #generics ::std::fmt::Debug for #ty_for_impl {
impl #generics ::#prefix::fmt::Debug for #ty_for_impl {
#impl_
}
});
@ -2516,22 +2572,10 @@ impl CodeGenerator for Enum {
}
};
// ModuleConsts has higher precedence before Rust in order to avoid problems with
// overlapping match patterns
let variation = if self.is_constified_enum_module(ctx, item) {
EnumVariation::ModuleConsts
} else if self.is_bitfield(ctx, item) {
EnumVariation::Bitfield
} else if self.is_rustified_enum(ctx, item) {
EnumVariation::Rust
} else if self.is_constified_enum(ctx, item) {
EnumVariation::Consts
} else {
ctx.options().default_enum_style
};
let mut attrs = vec![];
let variation = self.computed_enum_variation(ctx, item);
// TODO(emilio): Delegate this to the builders?
if variation.is_rust() {
attrs.push(attributes::repr(repr_name));
@ -2544,9 +2588,17 @@ impl CodeGenerator for Enum {
}
if !variation.is_const() {
attrs.push(attributes::derives(
&["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"],
));
let mut derives = vec!["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"];
if item.can_derive_partialord(ctx) {
derives.push("PartialOrd");
}
if item.can_derive_ord(ctx) {
derives.push("Ord");
}
attrs.push(attributes::derives(&derives));
}
fn add_constant<'a>(
@ -2759,7 +2811,7 @@ trait TryToOpaque {
extra: &Self::Extra,
) -> error::Result<quote::Tokens> {
self.try_get_layout(ctx, extra).map(|layout| {
helpers::blob(layout)
helpers::blob(ctx, layout)
})
}
}
@ -2786,7 +2838,7 @@ trait ToOpaque: TryToOpaque {
extra: &Self::Extra,
) -> quote::Tokens {
let layout = self.get_layout(ctx, extra);
helpers::blob(layout)
helpers::blob(ctx, layout)
}
}
@ -2844,7 +2896,7 @@ where
|_| if let Ok(layout) =
self.try_get_layout(ctx, extra)
{
Ok(helpers::blob(layout))
Ok(helpers::blob(ctx, layout))
} else {
Err(error::Error::NoLayoutForOpaqueBlob)
},
@ -2996,7 +3048,7 @@ impl TryToRustTy for Type {
IntKind::LongLong => Ok(raw_type(ctx, "c_longlong")),
IntKind::ULongLong => Ok(raw_type(ctx, "c_ulonglong")),
IntKind::WChar { size } => {
let ty = Layout::known_type_for_size(size)
let ty = Layout::known_type_for_size(ctx, size)
.expect("Non-representable wchar_t?");
let ident = ctx.rust_ident_raw(ty);
Ok(quote! { #ident })
@ -3018,17 +3070,27 @@ impl TryToRustTy for Type {
#ident
})
}
// FIXME: This doesn't generate the proper alignment, but we
// can't do better right now. We should be able to use
// i128/u128 when they're available.
IntKind::U128 | IntKind::I128 => {
Ok(quote! { [u64; 2] })
IntKind::U128 => {
Ok(if ctx.options().rust_features.i128_and_u128 {
quote! { u128 }
} else {
// Best effort thing, but wrong alignment
// unfortunately.
quote! { [u64; 2] }
})
}
IntKind::I128 => {
Ok(if ctx.options().rust_features.i128_and_u128 {
quote! { i128 }
} else {
quote! { [u64; 2] }
})
}
}
}
TypeKind::Float(fk) => Ok(float_kind_rust_type(ctx, fk)),
TypeKind::Float(fk) => Ok(float_kind_rust_type(ctx, fk, self.layout(ctx))),
TypeKind::Complex(fk) => {
let float_path = float_kind_rust_type(ctx, fk);
let float_path = float_kind_rust_type(ctx, fk, self.layout(ctx));
ctx.generated_bindgen_complex();
Ok(if ctx.options().enable_cxx_namespaces {
@ -3069,20 +3131,20 @@ impl TryToRustTy for Type {
}
TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()),
TypeKind::TemplateAlias(..) |
TypeKind::Alias(..) => {
TypeKind::Alias(..) |
TypeKind::BlockPointer(..) => {
if self.is_block_pointer() && !ctx.options().generate_block {
let void = raw_type(ctx, "c_void");
return Ok(void.to_ptr(/* is_const = */ false));
}
let template_params = item.used_template_params(ctx)
.into_iter()
.filter(|param| param.is_template_param(ctx, &()))
.collect::<Vec<_>>();
let spelling = self.name().expect("Unnamed alias?");
if item.is_opaque(ctx, &()) && !template_params.is_empty() {
self.try_to_opaque(ctx, item)
} else if let Some(ty) = utils::type_from_named(
ctx,
spelling,
)
{
} else if let Some(ty) = self.name().and_then(|name| utils::type_from_named(ctx, name)) {
Ok(ty)
} else {
utils::build_path(item, ctx)
@ -3099,13 +3161,6 @@ impl TryToRustTy for Type {
utils::build_path(item, ctx)
}
TypeKind::Opaque => self.try_to_opaque(ctx, item),
TypeKind::BlockPointer => {
let void = raw_type(ctx, "c_void");
Ok(void.to_ptr(
/* is_const = */
false
))
}
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) => {
let is_const = ctx.resolve_type(inner).is_const();
@ -3558,6 +3613,25 @@ mod utils {
result.extend(old_items.into_iter());
}
pub fn prepend_block_header(
ctx: &BindgenContext,
result: &mut Vec<quote::Tokens>,
) {
let use_block = if ctx.options().block_extern_crate {
quote! {
extern crate block;
}
} else {
quote! {
use block;
}
};
let items = vec![use_block];
let old_items = mem::replace(result, items);
result.extend(old_items.into_iter());
}
pub fn prepend_union_types(
ctx: &BindgenContext,
result: &mut Vec<quote::Tokens>,
@ -3614,7 +3688,7 @@ mod utils {
let union_field_debug_impl = quote! {
impl<T> ::#prefix::fmt::Debug for __BindgenUnionField<T> {
fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter)
fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>)
-> ::#prefix::fmt::Result {
fmt.write_str("__BindgenUnionField")
}
@ -3701,7 +3775,7 @@ mod utils {
let incomplete_array_debug_impl = quote! {
impl<T> ::#prefix::fmt::Debug for __IncompleteArrayField<T> {
fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter)
fn fmt(&self, fmt: &mut ::#prefix::fmt::Formatter<'_>)
-> ::#prefix::fmt::Result {
fmt.write_str("__IncompleteArrayField")
}
@ -3869,4 +3943,26 @@ mod utils {
args
}
pub fn fnsig_block(
ctx: &BindgenContext,
sig: &FunctionSig,
) -> quote::Tokens {
let args = sig.argument_types().iter().map(|&(_, ty)| {
let arg_item = ctx.resolve_item(ty);
arg_item.to_rust_ty_or_opaque(ctx, &())
});
let return_item = ctx.resolve_item(sig.return_type());
let ret_ty = if let TypeKind::Void = *return_item.kind().expect_type().kind() {
quote! { () }
} else {
return_item.to_rust_ty_or_opaque(ctx, &())
};
quote! {
*const ::block::Block<(#(#args),*), #ret_ty>
}
}
}

Просмотреть файл

@ -287,18 +287,23 @@ impl<'a> StructLayoutTracker<'a> {
}
pub fn requires_explicit_align(&self, layout: Layout) -> bool {
let repr_align = self.ctx.options().rust_features().repr_align;
// Always force explicit repr(align) for stuff more than 16-byte aligned
// to work-around https://github.com/rust-lang/rust/issues/54341.
//
// Worst-case this just generates redundant alignment attributes.
if repr_align && self.max_field_align >= 16 {
return true;
}
if self.max_field_align >= layout.align {
return false;
}
// At this point we require explicit alignment, but we may not be able
// to generate the right bits, let's double check.
if self.ctx.options().rust_features().repr_align {
return true;
}
// We can only generate up-to a word of alignment unless we support
// repr(align).
layout.align <= self.ctx.target_pointer_size()
repr_align || layout.align <= self.ctx.target_pointer_size()
}
fn padding_bytes(&self, layout: Layout) -> usize {
@ -306,7 +311,7 @@ impl<'a> StructLayoutTracker<'a> {
}
fn padding_field(&mut self, layout: Layout) -> quote::Tokens {
let ty = helpers::blob(layout);
let ty = helpers::blob(self.ctx, layout);
let padding_count = self.padding_count;
self.padding_count += 1;

6
third_party/rust/bindgen/src/features.rs поставляемый
Просмотреть файл

@ -96,6 +96,8 @@ macro_rules! rust_target_base {
=> Stable_1_21 => 1.21;
/// Rust stable 1.25
=> Stable_1_25 => 1.25;
/// Rust stable 1.26
=> Stable_1_26 => 1.26;
/// Nightly rust
=> Nightly => nightly;
);
@ -172,6 +174,10 @@ rust_feature_def!(
/// repr(align) ([PR](https://github.com/rust-lang/rust/pull/47006))
=> repr_align;
}
Stable_1_26 {
/// [i128 / u128 support](https://doc.rust-lang.org/std/primitive.i128.html)
=> i128_and_u128;
}
Nightly {
/// `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202))
=> thiscall_abi;

Просмотреть файл

@ -149,7 +149,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_copy()
l.opaque().can_trivially_derive_copy(self.ctx)
});
return if layout_can_derive {
trace!(" we can trivially derive Copy for the layout");
@ -173,7 +173,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::TypeParam |
TypeKind::BlockPointer |
TypeKind::Pointer(..) |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::ObjCInterface(..) |
@ -204,7 +203,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
let cant_derive_copy = self.is_not_copy(t);
if cant_derive_copy {
trace!(

Просмотреть файл

@ -146,7 +146,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_debug()
l.opaque().can_trivially_derive_debug(self.ctx)
});
return if layout_can_derive &&
!(ty.is_union() &&
@ -183,7 +183,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::Vector(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::ObjCInterface(..) |
@ -213,7 +212,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
if self.is_not_debug(t) {
trace!(
" aliases and type refs to T which cannot derive \
@ -242,7 +242,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
}
if ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_debug()
l.opaque().can_trivially_derive_debug(self.ctx)
})
{
trace!(" union layout can trivially derive Debug");
@ -299,7 +299,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
let inner_type =
self.ctx.resolve_type(inner).canonical_type(self.ctx);
if let TypeKind::Function(ref sig) = *inner_type.kind() {
if !sig.can_trivially_derive_debug() {
if !sig.can_trivially_derive_debug(self.ctx) {
trace!(
" function pointer that can't trivially derive Debug"
);

Просмотреть файл

@ -173,7 +173,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_default()
l.opaque().can_trivially_derive_default(self.ctx)
});
return if layout_can_derive &&
!(ty.is_union() &&
@ -215,7 +215,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
TypeKind::Reference(..) |
TypeKind::NullPtr |
TypeKind::Pointer(..) |
TypeKind::BlockPointer |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::ObjCInterface(..) |
@ -244,7 +243,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
if self.is_not_default(t) {
trace!(
" aliases and type refs to T which cannot derive \
@ -278,7 +278,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
}
if ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_default()
l.opaque().can_trivially_derive_default(self.ctx)
})
{
trace!(" union layout can trivially derive Default");

Просмотреть файл

@ -133,7 +133,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_hash()
l.opaque().can_trivially_derive_hash(self.ctx)
});
return if layout_can_derive &&
!(ty.is_union() &&
@ -167,7 +167,6 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
TypeKind::Enum(..) |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
@ -219,7 +218,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
let inner_type =
self.ctx.resolve_type(inner).canonical_type(self.ctx);
if let TypeKind::Function(ref sig) = *inner_type.kind() {
if !sig.can_trivially_derive_hash() {
if !sig.can_trivially_derive_hash(self.ctx) {
trace!(
" function pointer that can't trivially derive Hash"
);
@ -231,7 +230,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
}
TypeKind::Function(ref sig) => {
if !sig.can_trivially_derive_hash() {
if !sig.can_trivially_derive_hash(self.ctx) {
trace!(" function that can't trivially derive Hash");
return self.insert(id);
}
@ -241,7 +240,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
if self.cannot_derive_hash.contains(&t.into()) {
trace!(
" aliases and type refs to T which cannot derive \
@ -275,7 +275,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
}
if ty.layout(self.ctx).map_or(true, |l| {
l.opaque().can_trivially_derive_hash()
l.opaque().can_trivially_derive_hash(self.ctx)
})
{
trace!(" union layout can trivially derive Hash");

Просмотреть файл

@ -43,7 +43,7 @@ use std::collections::hash_map::Entry;
pub struct CannotDerivePartialEqOrPartialOrd<'ctx> {
ctx: &'ctx BindgenContext,
// The incremental result of this analysis's computation.
// The incremental result of this analysis's computation.
// Contains information whether particular item can derive `PartialEq`/`PartialOrd`.
can_derive_partialeq_or_partialord: HashMap<ItemId, CanDerive>,
@ -129,7 +129,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
let layout_can_derive = ty.layout(self.ctx)
.map_or(CanDerive::Yes, |l| {
l.opaque().can_trivially_derive_partialeq_or_partialord()
l.opaque().can_trivially_derive_partialeq_or_partialord(self.ctx)
});
match layout_can_derive {
@ -158,7 +158,6 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::Enum(..) |
TypeKind::TypeParam |
TypeKind::UnresolvedTypeRef(..) |
TypeKind::BlockPointer |
TypeKind::Reference(..) |
TypeKind::ObjCInterface(..) |
TypeKind::ObjCId |
@ -211,7 +210,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
let inner_type =
self.ctx.resolve_type(inner).canonical_type(self.ctx);
if let TypeKind::Function(ref sig) = *inner_type.kind() {
if sig.can_trivially_derive_partialeq_or_partialord()
if sig.can_trivially_derive_partialeq_or_partialord(self.ctx)
!= CanDerive::Yes
{
trace!(
@ -225,7 +224,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
}
TypeKind::Function(ref sig) => {
if sig.can_trivially_derive_partialeq_or_partialord()
if sig.can_trivially_derive_partialeq_or_partialord(self.ctx)
!= CanDerive::Yes
{
trace!(
@ -259,7 +258,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
let layout_can_derive =
ty.layout(self.ctx).map_or(CanDerive::Yes, |l| {
l.opaque()
.can_trivially_derive_partialeq_or_partialord()
.can_trivially_derive_partialeq_or_partialord(self.ctx)
});
match layout_can_derive {
CanDerive::Yes => {
@ -281,6 +280,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
TypeKind::ResolvedTypeRef(..) |
TypeKind::TemplateAlias(..) |
TypeKind::Alias(..) |
TypeKind::BlockPointer(..) |
TypeKind::TemplateInstantiation(..) => {
return self.constrain_join(item);
}

Просмотреть файл

@ -122,7 +122,6 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::Opaque |
TypeKind::Pointer(..) |
@ -159,7 +158,8 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
if self.has_float.contains(&t.into()) {
trace!(" aliases and type refs to T which have float \
also have float");

Просмотреть файл

@ -135,7 +135,6 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::Function(..) |
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::BlockPointer |
TypeKind::TypeParam |
TypeKind::Opaque |
TypeKind::Pointer(..) |
@ -166,7 +165,8 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) => {
if self.has_type_parameter_in_array.contains(&t.into()) {
trace!(
" aliases and type refs to T which have array \

Просмотреть файл

@ -261,7 +261,6 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> {
TypeKind::Enum(..) |
TypeKind::Reference(..) |
TypeKind::NullPtr |
TypeKind::BlockPointer |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::Pointer(..) => {
@ -276,6 +275,7 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> {
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) |
TypeKind::BlockPointer(t) |
TypeKind::ResolvedTypeRef(t) => {
trace!(" aliases and type refs forward to their inner type");
self.forward(t, id)

25
third_party/rust/bindgen/src/ir/comment.rs поставляемый
Просмотреть файл

@ -35,7 +35,6 @@ fn kind(comment: &str) -> Option<Kind> {
fn make_indent(indent: usize) -> String {
const RUST_INDENTATION: usize = 4;
iter::repeat(' ').take(indent * RUST_INDENTATION).collect()
}
@ -49,12 +48,11 @@ fn preprocess_single_lines(comment: &str, indent: usize) -> String {
let mut is_first = true;
let lines: Vec<_> = comment
.lines()
.map(|l| l.trim_left_matches('/').trim())
.map(|l| l.trim().trim_left_matches('/'))
.map(|l| {
let indent = if is_first { "" } else { &*indent };
is_first = false;
let maybe_space = if l.is_empty() { "" } else { " " };
format!("{}///{}{}", indent, maybe_space, l)
format!("{}///{}", indent, l)
})
.collect();
lines.join("\n")
@ -63,30 +61,24 @@ fn preprocess_single_lines(comment: &str, indent: usize) -> String {
fn preprocess_multi_line(comment: &str, indent: usize) -> String {
let comment = comment
.trim_left_matches('/')
.trim_left_matches('*')
.trim_left_matches('!')
.trim_right_matches('/')
.trim_right_matches('*')
.trim();
.trim_right_matches('*');
let indent = make_indent(indent);
// Strip any potential `*` characters preceding each line.
let mut is_first = true;
let mut lines: Vec<_> = comment.lines()
.map(|line| line.trim().trim_left_matches('*').trim())
.skip_while(|line| line.is_empty()) // Skip the first empty lines.
.map(|line| line.trim().trim_left_matches('*').trim_left_matches('!'))
.skip_while(|line| line.trim().is_empty()) // Skip the first empty lines.
.map(|line| {
let indent = if is_first { "" } else { &*indent };
is_first = false;
let maybe_space = if line.is_empty() { "" } else { " " };
format!("{}///{}{}", indent, maybe_space, line)
format!("{}///{}", indent, line)
})
.collect();
// Remove the trailing line corresponding to the `*/`.
let last_line_is_empty = lines.last().map_or(false, |l| l.is_empty());
if last_line_is_empty {
if lines.last().map_or(false, |l| l.trim().is_empty() || l.trim() == "///") {
lines.pop();
}
@ -107,6 +99,7 @@ mod test {
fn processes_single_lines_correctly() {
assert_eq!(preprocess("/// hello", 0), "/// hello");
assert_eq!(preprocess("// hello", 0), "/// hello");
assert_eq!(preprocess("// hello", 0), "/// hello");
}
#[test]
@ -118,7 +111,7 @@ mod test {
assert_eq!(
preprocess("/**\nhello\n*world\n*foo\n*/", 0),
"/// hello\n/// world\n/// foo"
"///hello\n///world\n///foo"
);
}
}

99
third_party/rust/bindgen/src/ir/context.rs поставляемый
Просмотреть файл

@ -226,7 +226,7 @@ where
}
}
impl<'a, T> CanDeriveCopy<'a> for T
impl<T> CanDeriveCopy for T
where
T: Copy + Into<ItemId>
{
@ -514,12 +514,19 @@ const HOST_TARGET: &'static str =
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
use std::env;
for opt in clang_args {
let mut args = clang_args.iter();
while let Some(opt) = args.next() {
if opt.starts_with("--target=") {
let mut split = opt.split('=');
split.next();
return (split.next().unwrap().to_owned(), true);
}
if opt == "-target" {
if let Some(target) = args.next() {
return (target.clone(), true);
}
}
}
// If we're running from a build script, try to find the cargo target.
@ -576,7 +583,10 @@ If you encounter an error missing from this list, please file an issue or a PR!"
{
if let Some(ref ti) = target_info {
if effective_target == HOST_TARGET {
assert_eq!(ti.pointer_width / 8, mem::size_of::<*mut ()>());
assert_eq!(
ti.pointer_width / 8, mem::size_of::<*mut ()>(),
"{:?} {:?}", effective_target, HOST_TARGET
);
}
}
}
@ -844,57 +854,58 @@ If you encounter an error missing from this list, please file an issue or a PR!"
name.contains("$") ||
match name {
"abstract" |
"alignof" |
"as" |
"become" |
"box" |
"alignof" |
"as" |
"async" |
"become" |
"box" |
"break" |
"const" |
"continue" |
"crate" |
"do" |
"const" |
"continue" |
"crate" |
"do" |
"else" |
"enum" |
"extern" |
"false" |
"final" |
"enum" |
"extern" |
"false" |
"final" |
"fn" |
"for" |
"if" |
"impl" |
"in" |
"for" |
"if" |
"impl" |
"in" |
"let" |
"loop" |
"macro" |
"match" |
"mod" |
"loop" |
"macro" |
"match" |
"mod" |
"move" |
"mut" |
"offsetof" |
"override" |
"priv" |
"mut" |
"offsetof" |
"override" |
"priv" |
"proc" |
"pub" |
"pure" |
"ref" |
"return" |
"pub" |
"pure" |
"ref" |
"return" |
"Self" |
"self" |
"sizeof" |
"static" |
"struct" |
"self" |
"sizeof" |
"static" |
"struct" |
"super" |
"trait" |
"true" |
"type" |
"typeof" |
"trait" |
"true" |
"type" |
"typeof" |
"unsafe" |
"unsized" |
"use" |
"virtual" |
"where" |
"unsized" |
"use" |
"virtual" |
"where" |
"while" |
"yield" |
"yield" |
"bool" |
"_" => true,
_ => false,

20
third_party/rust/bindgen/src/ir/derive.rs поставляемый
Просмотреть файл

@ -30,15 +30,15 @@ pub trait CanDeriveDebug {
pub trait CanTriviallyDeriveDebug {
/// Return `true` if `Debug` can trivially be derived for this thing,
/// `false` otherwise.
fn can_trivially_derive_debug(&self) -> bool;
fn can_trivially_derive_debug(&self, ctx: &BindgenContext) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can derive `Copy`
/// for a given thing.
pub trait CanDeriveCopy<'a> {
pub trait CanDeriveCopy {
/// Return `true` if `Copy` can be derived for this thing, `false`
/// otherwise.
fn can_derive_copy(&'a self, ctx: &'a BindgenContext) -> bool;
fn can_derive_copy(&self, ctx: &BindgenContext) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can trivially
@ -47,7 +47,7 @@ pub trait CanDeriveCopy<'a> {
pub trait CanTriviallyDeriveCopy {
/// Return `true` if `Copy` can be trivially derived for this thing, `false`
/// otherwise.
fn can_trivially_derive_copy(&self) -> bool;
fn can_trivially_derive_copy(&self, ctx: &BindgenContext) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can derive
@ -64,7 +64,7 @@ pub trait CanDeriveDefault {
pub trait CanTriviallyDeriveDefault {
/// Return `true` if `Default` can trivially derived for this thing, `false`
/// otherwise.
fn can_trivially_derive_default(&self) -> bool;
fn can_trivially_derive_default(&self, ctx: &BindgenContext) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can derive `Hash`
@ -111,7 +111,7 @@ pub trait CanDeriveOrd {
pub trait CanTriviallyDeriveHash {
/// Return `true` if `Hash` can trivially be derived for this thing, `false`
/// otherwise.
fn can_trivially_derive_hash(&self) -> bool;
fn can_trivially_derive_hash(&self, ctx: &BindgenContext) -> bool;
}
/// A trait that encapsulates the logic for whether or not we can trivially
@ -120,11 +120,11 @@ pub trait CanTriviallyDeriveHash {
pub trait CanTriviallyDerivePartialEqOrPartialOrd {
/// Return `Yes` if `PartialEq` or `PartialOrd` can trivially be derived
/// for this thing.
fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive;
fn can_trivially_derive_partialeq_or_partialord(&self, ctx: &BindgenContext) -> CanDerive;
}
/// Whether it is possible or not to automatically derive trait for an item.
///
///
/// ```ignore
/// No
/// ^
@ -134,7 +134,7 @@ pub trait CanTriviallyDerivePartialEqOrPartialOrd {
/// |
/// Yes
/// ```
///
///
/// Initially we assume that we can derive trait for all types and then
/// update our understanding as we learn more about each type.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord)]
@ -144,7 +144,7 @@ pub enum CanDerive {
/// The only thing that stops us from automatically deriving is that
/// array with more than maximum number of elements is used.
///
///
/// This means we probably can "manually" implement such trait.
ArrayTooLarge,

50
third_party/rust/bindgen/src/ir/enum_ty.rs поставляемый
Просмотреть файл

@ -2,6 +2,7 @@
use super::context::{BindgenContext, TypeId};
use super::item::Item;
use super::super::codegen::EnumVariation;
use super::ty::TypeKind;
use clang;
use ir::annotations::Annotations;
@ -142,32 +143,33 @@ impl Enum {
let path = item.canonical_path(ctx);
let enum_ty = item.expect_type();
let path_matches = enums.matches(&path[1..].join("::"));
let enum_is_anon = enum_ty.name().is_none();
let a_variant_matches = self.variants().iter().any(|v| {
enums.matches(&v.name())
});
path_matches || (enum_is_anon && a_variant_matches)
if enums.matches(&path[1..].join("::")) {
return true;
}
// Test the variants if the enum is anonymous.
if enum_ty.name().is_some() {
return false;
}
self.variants().iter().any(|v| enums.matches(&v.name()))
}
/// Whether the enum should be a bitfield
pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().bitfield_enums, item)
}
/// Whether the enum should be an constified enum module
pub fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().constified_enum_modules, item)
}
/// Whether the enum should be an set of constants
pub fn is_constified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().constified_enums, item)
}
/// Whether the enum should be a Rust enum
pub fn is_rustified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().rustified_enums, item)
/// Returns the final representation of the enum.
pub fn computed_enum_variation(&self, ctx: &BindgenContext, item: &Item) -> EnumVariation {
// ModuleConsts has higher precedence before Rust in order to avoid
// problems with overlapping match patterns.
if self.is_matching_enum(ctx, &ctx.options().constified_enum_modules, item) {
EnumVariation::ModuleConsts
} else if self.is_matching_enum(ctx, &ctx.options().bitfield_enums, item) {
EnumVariation::Bitfield
} else if self.is_matching_enum(ctx, &ctx.options().rustified_enums, item) {
EnumVariation::Rust
} else if self.is_matching_enum(ctx, &ctx.options().constified_enums, item) {
EnumVariation::Consts
} else {
ctx.options().default_enum_style
}
}
}

28
third_party/rust/bindgen/src/ir/function.rs поставляемый
Просмотреть файл

@ -442,7 +442,16 @@ impl FunctionSig {
ty.ret_type().ok_or(ParseError::Continue)?
};
let ret = Item::from_ty_or_ref(ty_ret_type, cursor, None, ctx);
let call_conv = ty.call_conv();
// Clang plays with us at "find the calling convention", see #549 and
// co. This seems to be a better fix than that commit.
let mut call_conv = ty.call_conv();
if let Some(ty) = cursor.cur_type().canonical_type().pointee_type() {
let cursor_call_conv = ty.call_conv();
if cursor_call_conv != CXCallingConv_Invalid {
call_conv = cursor_call_conv;
}
}
let abi = get_abi(call_conv);
if abi.is_unknown() {
@ -581,26 +590,23 @@ impl Trace for FunctionSig {
}
impl CanTriviallyDeriveDebug for FunctionSig {
fn can_trivially_derive_debug(&self) -> bool {
fn can_trivially_derive_debug(&self, _: &BindgenContext) -> bool {
self.function_pointers_can_derive()
}
}
impl CanTriviallyDeriveHash for FunctionSig {
fn can_trivially_derive_hash(&self) -> bool {
fn can_trivially_derive_hash(&self, _: &BindgenContext) -> bool {
self.function_pointers_can_derive()
}
}
impl CanTriviallyDerivePartialEqOrPartialOrd for FunctionSig {
fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive {
if self.argument_types.len() > RUST_DERIVE_FUNPTR_LIMIT {
return CanDerive::No;
}
match self.abi {
Abi::C | Abi::Unknown(..) => CanDerive::Yes,
_ => CanDerive::No,
fn can_trivially_derive_partialeq_or_partialord(&self, _: &BindgenContext) -> CanDerive {
if self.function_pointers_can_derive() {
CanDerive::Yes
} else {
CanDerive::No
}
}
}

7
third_party/rust/bindgen/src/ir/item.rs поставляемый
Просмотреть файл

@ -13,7 +13,7 @@ use super::function::{Function, FunctionKind};
use super::item_kind::ItemKind;
use super::layout::Opaque;
use super::module::Module;
use super::super::codegen::CONSTIFIED_ENUM_MODULE_REPR_NAME;
use super::super::codegen::{CONSTIFIED_ENUM_MODULE_REPR_NAME, EnumVariation};
use super::template::{AsTemplateParam, TemplateParameters};
use super::traversal::{EdgeKind, Trace, Tracer};
use super::ty::{Type, TypeKind};
@ -329,7 +329,7 @@ impl CanDeriveDefault for Item {
}
}
impl<'a> CanDeriveCopy<'a> for Item {
impl CanDeriveCopy for Item {
fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
self.id().can_derive_copy(ctx)
}
@ -637,6 +637,7 @@ impl Item {
let path = self.canonical_path(ctx);
let name = path[1..].join("::");
ctx.options().blacklisted_items.matches(&name) ||
match self.kind {
ItemKind::Type(..) => {
ctx.options().blacklisted_types.matches(&name) ||
@ -928,7 +929,7 @@ impl Item {
match *type_.kind() {
TypeKind::Enum(ref enum_) => {
enum_.is_constified_enum_module(ctx, self)
enum_.computed_enum_variation(ctx, self) == EnumVariation::ModuleConsts
}
TypeKind::Alias(inner_id) => {
// TODO(emilio): Make this "hop through type aliases that aren't

50
third_party/rust/bindgen/src/ir/layout.rs поставляемый
Просмотреть файл

@ -36,8 +36,12 @@ fn test_layout_for_size() {
impl Layout {
/// Gets the integer type name for a given known size.
pub fn known_type_for_size(size: usize) -> Option<&'static str> {
pub fn known_type_for_size(
ctx: &BindgenContext,
size: usize,
) -> Option<&'static str> {
Some(match size {
16 if ctx.options().rust_features.i128_and_u128 => "u128",
8 => "u64",
4 => "u32",
2 => "u16",
@ -105,14 +109,14 @@ impl Opaque {
/// Return the known rust type we should use to create a correctly-aligned
/// field with this layout.
pub fn known_rust_type_for_array(&self) -> Option<&'static str> {
Layout::known_type_for_size(self.0.align)
pub fn known_rust_type_for_array(&self,ctx: &BindgenContext) -> Option<&'static str> {
Layout::known_type_for_size(ctx, self.0.align)
}
/// Return the array size that an opaque type for this layout should have if
/// we know the correct type for it, or `None` otherwise.
pub fn array_size(&self) -> Option<usize> {
if self.known_rust_type_for_array().is_some() {
pub fn array_size(&self, ctx: &BindgenContext) -> Option<usize> {
if self.known_rust_type_for_array(ctx).is_some() {
Some(self.0.size / cmp::max(self.0.align, 1))
} else {
None
@ -122,45 +126,45 @@ impl Opaque {
/// Return `true` if this opaque layout's array size will fit within the
/// maximum number of array elements that Rust allows deriving traits
/// with. Return `false` otherwise.
pub fn array_size_within_derive_limit(&self) -> bool {
self.array_size().map_or(false, |size| {
pub fn array_size_within_derive_limit(&self, ctx: &BindgenContext) -> bool {
self.array_size(ctx).map_or(false, |size| {
size <= RUST_DERIVE_IN_ARRAY_LIMIT
})
}
}
impl CanTriviallyDeriveDebug for Opaque {
fn can_trivially_derive_debug(&self) -> bool {
self.array_size_within_derive_limit()
fn can_trivially_derive_debug(&self, ctx: &BindgenContext) -> bool {
self.array_size_within_derive_limit(ctx)
}
}
impl CanTriviallyDeriveDefault for Opaque {
fn can_trivially_derive_default(&self) -> bool {
self.array_size_within_derive_limit()
fn can_trivially_derive_default(&self, ctx: &BindgenContext) -> bool {
self.array_size_within_derive_limit(ctx)
}
}
impl CanTriviallyDeriveCopy for Opaque {
fn can_trivially_derive_copy(&self) -> bool {
self.array_size_within_derive_limit()
fn can_trivially_derive_copy(&self, ctx: &BindgenContext) -> bool {
self.array_size_within_derive_limit(ctx)
}
}
impl CanTriviallyDeriveHash for Opaque {
fn can_trivially_derive_hash(&self) -> bool {
self.array_size_within_derive_limit()
fn can_trivially_derive_hash(&self, ctx: &BindgenContext) -> bool {
self.array_size_within_derive_limit(ctx)
}
}
impl CanTriviallyDerivePartialEqOrPartialOrd for Opaque {
fn can_trivially_derive_partialeq_or_partialord(&self) -> CanDerive {
self.array_size().map_or(CanDerive::No, |size| {
if size <= RUST_DERIVE_IN_ARRAY_LIMIT {
CanDerive::Yes
} else {
CanDerive::ArrayTooLarge
}
})
fn can_trivially_derive_partialeq_or_partialord(&self, ctx: &BindgenContext) -> CanDerive {
// TODO(emilio): This is inconsistent with the rest of the
// CanTriviallyDerive* traits.
if self.array_size_within_derive_limit(ctx) {
CanDerive::Yes
} else {
CanDerive::ArrayTooLarge
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше