mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge branch 'mozilla-central'
This commit is contained in:
commit
bfa05a5560
@ -193,6 +193,18 @@ extensions.registerSchemaAPI("bookmarks", "bookmarks", (extension, context) => {
|
||||
};
|
||||
|
||||
// The API doesn't give you the old bookmark at the moment
|
||||
try {
|
||||
return Bookmarks.remove(info, {preventRemovalOfNonEmptyFolders: true}).then(result => {});
|
||||
} catch (e) {
|
||||
return Promise.reject({message: `Invalid bookmark: ${JSON.stringify(info)}`});
|
||||
}
|
||||
},
|
||||
|
||||
removeTree: function(id) {
|
||||
let info = {
|
||||
guid: id,
|
||||
};
|
||||
|
||||
try {
|
||||
return Bookmarks.remove(info).then(result => {});
|
||||
} catch (e) {
|
||||
|
@ -400,7 +400,6 @@
|
||||
},
|
||||
{
|
||||
"name": "removeTree",
|
||||
"unsupported": true,
|
||||
"type": "function",
|
||||
"description": "Recursively removes a bookmark folder.",
|
||||
"async": "callback",
|
||||
|
@ -17,3 +17,4 @@ support-files =
|
||||
[browser_service_workers_push.js]
|
||||
[browser_service_workers_start.js]
|
||||
[browser_service_workers_timeout.js]
|
||||
skip-if = true # Bug 1232931
|
||||
|
@ -1,7 +1,7 @@
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
skip-if = (e10s && debug && os == 'mac') # bug 1252283
|
||||
skip-if = e10s && debug # bug 1252283
|
||||
support-files =
|
||||
doc_body_animation.html
|
||||
doc_frame_script.js
|
||||
|
@ -70,7 +70,7 @@ support-files =
|
||||
[browser_rules_completion-popup-hidden-after-navigation.js]
|
||||
[browser_rules_content_01.js]
|
||||
[browser_rules_content_02.js]
|
||||
skip-if = e10s && debug && (os == 'mac' || os == 'win') # Bug 1250058 - Docshell leak on osx/win debug e10s
|
||||
skip-if = e10s && debug # Bug 1250058 - Docshell leak on debug e10s
|
||||
[browser_rules_context-menu-show-mdn-docs-01.js]
|
||||
[browser_rules_context-menu-show-mdn-docs-02.js]
|
||||
[browser_rules_context-menu-show-mdn-docs-03.js]
|
||||
|
@ -79,7 +79,7 @@ support-files =
|
||||
[browser_inspector_iframe-navigation.js]
|
||||
[browser_inspector_infobar_01.js]
|
||||
[browser_inspector_initialization.js]
|
||||
skip-if = e10s && debug && (os == 'mac' || os == 'win') # Bug 1250058 - Docshell leak on osx/win debug e10s
|
||||
skip-if = (e10s && debug) # Bug 1250058 - Docshell leak on debug e10s
|
||||
[browser_inspector_inspect-object-element.js]
|
||||
[browser_inspector_invalidate.js]
|
||||
[browser_inspector_keyboard-shortcuts-copy-outerhtml.js]
|
||||
|
@ -69,6 +69,7 @@ skip-if = e10s # Bug 1091596
|
||||
[browser_net_cyrillic-01.js]
|
||||
[browser_net_cyrillic-02.js]
|
||||
[browser_net_details-no-duplicated-content.js]
|
||||
skip-if = (os == 'linux' && e10s && debug) # Bug 1242204
|
||||
[browser_net_filter-01.js]
|
||||
[browser_net_filter-02.js]
|
||||
[browser_net_filter-03.js]
|
||||
@ -77,7 +78,7 @@ skip-if = e10s # Bug 1091596
|
||||
[browser_net_html-preview.js]
|
||||
[browser_net_icon-preview.js]
|
||||
[browser_net_image-tooltip.js]
|
||||
skip-if = (os == "win" && os_version == "6.2" && bits == 64) # Bug 1234341
|
||||
skip-if = true # Bug 1234341, bug 1252641
|
||||
[browser_net_json-long.js]
|
||||
[browser_net_json-malformed.js]
|
||||
[browser_net_json_custom_mime.js]
|
||||
|
@ -7,9 +7,9 @@ support-files =
|
||||
|
||||
[browser_responsive_cmd.js]
|
||||
[browser_responsivecomputedview.js]
|
||||
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1252201 - Docshell leak on win/osx debug e10s
|
||||
skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
|
||||
[browser_responsiveruleview.js]
|
||||
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1252201 - Docshell leak on win/osx debug e10s
|
||||
skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
|
||||
[browser_responsiveui.js]
|
||||
[browser_responsiveui_touch.js]
|
||||
[browser_responsiveuiaddcustompreset.js]
|
||||
|
@ -16,5 +16,5 @@ support-files =
|
||||
[browser_storage_overflow.js]
|
||||
[browser_storage_search.js]
|
||||
[browser_storage_sidebar.js]
|
||||
skip-if = (os == 'win' && os_version == '6.1' && e10s && !debug) # bug 1229272
|
||||
skip-if = (os == 'win' && e10s) # bug 1229272
|
||||
[browser_storage_values.js]
|
||||
|
@ -59,6 +59,7 @@ support-files =
|
||||
[browser_styleeditor_cmd_edit.js]
|
||||
[browser_styleeditor_enabled.js]
|
||||
[browser_styleeditor_fetch-from-cache.js]
|
||||
skip-if = e10s && debug && (os == 'win')
|
||||
[browser_styleeditor_filesave.js]
|
||||
[browser_styleeditor_highlight-selector.js]
|
||||
[browser_styleeditor_import.js]
|
||||
@ -68,7 +69,7 @@ support-files =
|
||||
[browser_styleeditor_loading.js]
|
||||
[browser_styleeditor_media_sidebar.js]
|
||||
[browser_styleeditor_media_sidebar_links.js]
|
||||
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1252201 - Docshell leak on win/osx debug e10s
|
||||
skip-if = e10s && debug # Bug 1252201 - Docshell leak on debug e10s
|
||||
[browser_styleeditor_media_sidebar_sourcemaps.js]
|
||||
[browser_styleeditor_missing_stylesheet.js]
|
||||
[browser_styleeditor_navigate.js]
|
||||
|
@ -314,24 +314,25 @@ ExplicitChildIterator::GetPreviousChild()
|
||||
bool
|
||||
AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
||||
{
|
||||
if (mPhase == eNeedBeforeKid) {
|
||||
mPhase = eNeedExplicitKids;
|
||||
if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
|
||||
mPhase = eAtExplicitKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
if (beforeFrame->GetContent() == aChildToFind) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPhase == eNeedExplicitKids) {
|
||||
if (mPhase == eAtExplicitKids) {
|
||||
if (ExplicitChildIterator::Seek(aChildToFind)) {
|
||||
return true;
|
||||
}
|
||||
mPhase = eNeedAnonKids;
|
||||
mPhase = eAtAnonKids;
|
||||
}
|
||||
|
||||
nsIContent* child = nullptr;
|
||||
@ -345,59 +346,124 @@ AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
||||
nsIContent*
|
||||
AllChildrenIterator::GetNextChild()
|
||||
{
|
||||
if (mPhase == eNeedBeforeKid) {
|
||||
mPhase = eNeedExplicitKids;
|
||||
if (mPhase == eAtBegin) {
|
||||
mPhase = eAtExplicitKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPhase == eNeedExplicitKids) {
|
||||
if (mPhase == eAtBeforeKid) {
|
||||
// Advance into our explicit kids.
|
||||
mPhase = eAtExplicitKids;
|
||||
}
|
||||
|
||||
if (mPhase == eAtExplicitKids) {
|
||||
nsIContent* kid = ExplicitChildIterator::GetNextChild();
|
||||
if (kid) {
|
||||
return kid;
|
||||
}
|
||||
|
||||
mPhase = eNeedAnonKids;
|
||||
mPhase = eAtAnonKids;
|
||||
}
|
||||
|
||||
if (mPhase == eNeedAnonKids) {
|
||||
if (mPhase == eAtAnonKids) {
|
||||
if (mAnonKids.IsEmpty()) {
|
||||
MOZ_ASSERT(mAnonKidsIdx == UINT32_MAX);
|
||||
nsIAnonymousContentCreator* ac =
|
||||
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
||||
if (ac) {
|
||||
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
||||
}
|
||||
mAnonKidsIdx = 0;
|
||||
}
|
||||
|
||||
if (!mAnonKids.IsEmpty()) {
|
||||
nsIContent* nextKid = mAnonKids[0];
|
||||
mAnonKids.RemoveElementAt(0);
|
||||
if (mAnonKids.IsEmpty()) {
|
||||
mPhase = eNeedAfterKid;
|
||||
else {
|
||||
if (mAnonKidsIdx == UINT32_MAX) {
|
||||
mAnonKidsIdx = 0;
|
||||
}
|
||||
else {
|
||||
mAnonKidsIdx++;
|
||||
}
|
||||
|
||||
return nextKid;
|
||||
}
|
||||
|
||||
mPhase = eNeedAfterKid;
|
||||
}
|
||||
if (mAnonKidsIdx < mAnonKids.Length()) {
|
||||
return mAnonKids[mAnonKidsIdx];
|
||||
}
|
||||
|
||||
if (mPhase == eNeedAfterKid) {
|
||||
mPhase = eDone;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
if (afterFrame) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPhase = eAtEnd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
AllChildrenIterator::GetPreviousChild()
|
||||
{
|
||||
if (mPhase == eAtEnd) {
|
||||
MOZ_ASSERT(mAnonKidsIdx == mAnonKids.Length());
|
||||
mPhase = eAtAnonKids;
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||
if (afterFrame) {
|
||||
mPhase = eAtAfterKid;
|
||||
return afterFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPhase == eAtAfterKid) {
|
||||
mPhase = eAtAnonKids;
|
||||
}
|
||||
|
||||
if (mPhase == eAtAnonKids) {
|
||||
if (mAnonKids.IsEmpty()) {
|
||||
nsIAnonymousContentCreator* ac =
|
||||
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
||||
if (ac) {
|
||||
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
||||
mAnonKidsIdx = mAnonKids.Length();
|
||||
}
|
||||
}
|
||||
|
||||
// If 0 then it turns into UINT32_MAX, which indicates the iterator is
|
||||
// before the anonymous children.
|
||||
--mAnonKidsIdx;
|
||||
if (mAnonKidsIdx < mAnonKids.Length()) {
|
||||
return mAnonKids[mAnonKidsIdx];
|
||||
}
|
||||
mPhase = eAtExplicitKids;
|
||||
}
|
||||
|
||||
if (mPhase == eAtExplicitKids) {
|
||||
nsIContent* kid = ExplicitChildIterator::GetPreviousChild();
|
||||
if (kid) {
|
||||
return kid;
|
||||
}
|
||||
|
||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||
if (beforeFrame) {
|
||||
mPhase = eAtBeforeKid;
|
||||
return beforeFrame->GetContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPhase = eAtBegin;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -182,14 +182,14 @@ class AllChildrenIterator : private FlattenedChildIterator
|
||||
public:
|
||||
AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
|
||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
mOriginalContent(aNode), mFlags(aFlags),
|
||||
mPhase(eNeedBeforeKid) {}
|
||||
mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||
|
||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||
: FlattenedChildIterator(Move(aOther)),
|
||||
mOriginalContent(aOther.mOriginalContent),
|
||||
mAnonKids(Move(aOther.mAnonKids)), mFlags(aOther.mFlags),
|
||||
mPhase(aOther.mPhase)
|
||||
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
|
||||
#ifdef DEBUG
|
||||
, mMutationGuard(aOther.mMutationGuard)
|
||||
#endif
|
||||
@ -202,20 +202,32 @@ public:
|
||||
bool Seek(nsIContent* aChildToFind);
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
nsIContent* GetPreviousChild();
|
||||
nsIContent* Parent() const { return mOriginalContent; }
|
||||
|
||||
private:
|
||||
enum IteratorPhase
|
||||
{
|
||||
eNeedBeforeKid,
|
||||
eNeedExplicitKids,
|
||||
eNeedAnonKids,
|
||||
eNeedAfterKid,
|
||||
eDone
|
||||
eAtBegin,
|
||||
eAtBeforeKid,
|
||||
eAtExplicitKids,
|
||||
eAtAnonKids,
|
||||
eAtAfterKid,
|
||||
eAtEnd
|
||||
};
|
||||
IteratorPhase Phase() const { return mPhase; }
|
||||
|
||||
private:
|
||||
nsIContent* mOriginalContent;
|
||||
|
||||
// mAnonKids is an array of native anonymous children, mAnonKidsIdx is index
|
||||
// in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is
|
||||
// eAtAnonKids then the iterator points at a child at mAnonKidsIdx index. If
|
||||
// mAnonKidsIdx == mAnonKids.Length() then the iterator is somewhere after
|
||||
// the last native anon child. If mAnonKidsIdx == UINT32_MAX then the iterator
|
||||
// is somewhere before the first native anon child.
|
||||
nsTArray<nsIContent*> mAnonKids;
|
||||
uint32_t mAnonKidsIdx;
|
||||
|
||||
uint32_t mFlags;
|
||||
IteratorPhase mPhase;
|
||||
#ifdef DEBUG
|
||||
|
@ -4357,8 +4357,8 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType)
|
||||
// previous type does, we should clear out mFocusedValue.
|
||||
if (MayFireChangeOnBlur(mType) && !MayFireChangeOnBlur(oldType)) {
|
||||
GetValue(mFocusedValue);
|
||||
} else if (!IsSingleLineTextControl(mType, false) &&
|
||||
IsSingleLineTextControl(oldType, false)) {
|
||||
} else if (!IsSingleLineTextControl(false, mType) &&
|
||||
IsSingleLineTextControl(false, oldType)) {
|
||||
mFocusedValue.Truncate();
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,9 @@
|
||||
var testAudio = createMediaElement('audio', 'testAudio');
|
||||
return new Promise((resolve, reject) => {
|
||||
navigator.mozGetUserMedia({ audio: true }, () => {
|
||||
var syncXHR = new XMLHttpRequest();
|
||||
syncXHR.open('GET', location, false);
|
||||
syncXHR.send();
|
||||
ok(true, "Didn't crash");
|
||||
resolve();
|
||||
SpecialPowers.spinEventLoop(window);
|
||||
ok(true, "Didn't crash");
|
||||
resolve();
|
||||
}, () => {});
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,6 @@ support-files =
|
||||
hello.ogg^headers^
|
||||
silence.ogg
|
||||
silence.ogg^headers^
|
||||
|
||||
[test_abort.html]
|
||||
skip-if = toolkit == 'android' # bug 1037287
|
||||
[test_audio_capture_error.html]
|
||||
@ -15,7 +14,7 @@ skip-if = toolkit == 'android' # bug 1037287
|
||||
tags=capturestream
|
||||
skip-if = (android_version == '18' && debug) # bug 967606
|
||||
[test_nested_eventloop.html]
|
||||
skip-if = buildapp == 'mulet' || toolkit == 'android' || e10s # b2g(showmodaldialog)
|
||||
skip-if = buildapp == 'mulet' || toolkit == 'android'
|
||||
[test_preference_enable.html]
|
||||
[test_recognition_service_error.html]
|
||||
[test_success_without_recognition_service.html]
|
||||
|
@ -27,12 +27,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
|
||||
* When this is done from inside DOM event handlers, it is possible to
|
||||
* cause reentrancy in our C++ code, which we should be able to withstand.
|
||||
*/
|
||||
|
||||
function abortAndSpinEventLoop(evt, sr) {
|
||||
sr.abort();
|
||||
window.showModalDialog("javascript:window.close()");
|
||||
SpecialPowers.spinEventLoop(window);
|
||||
}
|
||||
|
||||
function doneFunc() {
|
||||
// Trigger gc now and wait some time to make sure this test gets the blame
|
||||
// for any assertions caused by showModalDialog
|
||||
|
@ -25,7 +25,7 @@ skip-if = buildapp == 'b2g'
|
||||
skip-if = toolkit=='gonk' || toolkit == 'android' #TIMED_OUT # b2g-debug(debug-only timeout)
|
||||
[test_geolocation_is_undefined_when_pref_is_off.html]
|
||||
[test_handlerSpinsEventLoop.html]
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #Don't run modal tests on Android # b2g(showmodaldialog) b2g-debug(showmodaldialog) b2g-desktop(showmodaldialog)
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #Don't run modal tests on Android
|
||||
[test_manyCurrentConcurrent.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT
|
||||
[test_manyCurrentSerial.html]
|
||||
|
@ -38,7 +38,7 @@ function spinEventLoopAndSetTimeout() {
|
||||
return;
|
||||
}
|
||||
|
||||
window.showModalDialog("javascript:window.close()");
|
||||
SpecialPowers.spinEventLoop(window);
|
||||
|
||||
setTimeout(function() {
|
||||
ok(successCallbackCalled != errorCallbackCalled, "Ensure only one callback is called");
|
||||
|
@ -2113,8 +2113,14 @@ nsWindowWatcher::SizeOpenedDocShellItem(nsIDocShellTreeItem* aDocShellItem,
|
||||
int32_t winWidth = width + (sizeChromeWidth ? 0 : chromeWidth),
|
||||
winHeight = height + (sizeChromeHeight ? 0 : chromeHeight);
|
||||
|
||||
screen->GetAvailRectDisplayPix(&screenLeft, &screenTop, &screenWidth,
|
||||
&screenHeight);
|
||||
// Get screen dimensions (in device pixels)
|
||||
screen->GetAvailRect(&screenLeft, &screenTop, &screenWidth,
|
||||
&screenHeight);
|
||||
// Convert them to CSS pixels
|
||||
screenLeft = NSToIntRound(screenLeft / scale);
|
||||
screenTop = NSToIntRound(screenTop / scale);
|
||||
screenWidth = NSToIntRound(screenWidth / scale);
|
||||
screenHeight = NSToIntRound(screenHeight / scale);
|
||||
|
||||
if (aSizeSpec.SizeSpecified()) {
|
||||
/* Unlike position, force size out-of-bounds check only if
|
||||
|
@ -492,6 +492,10 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
|
||||
aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(),
|
||||
"parentScrollId", apzc->GetParent()->GetGuid().mScrollId);
|
||||
}
|
||||
if (aMetrics.IsRootContent()) {
|
||||
aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(),
|
||||
"isRootContent", true);
|
||||
}
|
||||
}
|
||||
|
||||
if (newApzc) {
|
||||
|
@ -39,46 +39,6 @@ function convertTestData(testData) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Utilities for reconstructing the structure of the APZC tree from
|
||||
// 'parentScrollId' entries in the APZ test data.
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// Create a node with scroll id 'id' in the APZC tree.
|
||||
function makeNode(id) {
|
||||
return {scrollId: id, children: []};
|
||||
}
|
||||
|
||||
// Find a node with scroll id 'id' in the APZC tree rooted at 'root'.
|
||||
function findNode(root, id) {
|
||||
if (root.scrollId == id) {
|
||||
return root;
|
||||
}
|
||||
for (var i = 0; i < root.children.length; ++i) {
|
||||
var subtreeResult = findNode(root.children[i], id);
|
||||
if (subtreeResult != null) {
|
||||
return subtreeResult;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add a child -> parent link to the APZC tree rooted at 'root'.
|
||||
function addLink(root, child, parent) {
|
||||
var parentNode = findNode(root, parent);
|
||||
if (parentNode == null) {
|
||||
parentNode = makeNode(parent);
|
||||
root.children.push(parentNode);
|
||||
}
|
||||
parentNode.children.push(makeNode(child));
|
||||
}
|
||||
|
||||
// Add a root node to the APZC tree. It will become a direct
|
||||
// child of 'root'.
|
||||
function addRoot(root, id) {
|
||||
root.children.push(makeNode(id));
|
||||
}
|
||||
|
||||
// Given APZ test data for a single paint on the compositor side,
|
||||
// reconstruct the APZC tree structure from the 'parentScrollId'
|
||||
// entries that were logged. More specifically, the subset of the
|
||||
@ -89,17 +49,38 @@ function buildApzcTree(paint) {
|
||||
// The APZC tree can potentially have multiple root nodes,
|
||||
// so we invent a node that is the parent of all roots.
|
||||
// This 'root' does not correspond to an APZC.
|
||||
var root = makeNode(-1);
|
||||
var root = {scrollId: -1, children: []};
|
||||
for (var scrollId in paint) {
|
||||
paint[scrollId].children = [];
|
||||
paint[scrollId].scrollId = scrollId;
|
||||
}
|
||||
for (var scrollId in paint) {
|
||||
var parentNode = null;
|
||||
if ("hasNoParentWithSameLayersId" in paint[scrollId]) {
|
||||
addRoot(root, scrollId);
|
||||
parentNode = root;
|
||||
} else if ("parentScrollId" in paint[scrollId]) {
|
||||
addLink(root, scrollId, paint[scrollId]["parentScrollId"]);
|
||||
parentNode = paint[paint[scrollId].parentScrollId];
|
||||
}
|
||||
parentNode.children.push(paint[scrollId]);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
// Given an APZC tree produced by buildApzcTree, return the RCD node in
|
||||
// the tree, or null if there was none.
|
||||
function findRcdNode(apzcTree) {
|
||||
if (!!apzcTree.isRootContent) { // isRootContent will be undefined or "1"
|
||||
return apzcTree;
|
||||
}
|
||||
for (var i = 0; i < apzcTree.children.length; i++) {
|
||||
var rcd = findRcdNode(apzcTree.children[i]);
|
||||
if (rcd != null) {
|
||||
return rcd;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function flushApzRepaints(aCallback, aWindow = window) {
|
||||
if (!aCallback) {
|
||||
throw "A callback must be provided!";
|
||||
|
@ -55,15 +55,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1151663
|
||||
// Convert the test data into a representation that's easier to navigate.
|
||||
contentTestData = convertTestData(contentTestData);
|
||||
compositorTestData = convertTestData(compositorTestData);
|
||||
var paint = compositorTestData.paints[lastCompositorPaintSeqNo];
|
||||
|
||||
// Reconstruct the APZC tree structure in the last paint.
|
||||
var apzcTree = buildApzcTree(compositorTestData.paints[lastCompositorPaintSeqNo]);
|
||||
var apzcTree = buildApzcTree(paint);
|
||||
|
||||
// The apzc tree for this page should consist of a single root APZC,
|
||||
// and no child APZCs.
|
||||
SimpleTest.is(apzcTree.children.length, 1, "expected a single root APZC");
|
||||
var rootApzc = apzcTree.children[0];
|
||||
SimpleTest.is(rootApzc.children.length, 0, "expected no child APZCs");
|
||||
// which either is the RCD with no child APZCs (e10s/B2G case) or has a
|
||||
// single child APZC which is for the RCD (fennec case).
|
||||
var rcd = findRcdNode(apzcTree);
|
||||
SimpleTest.ok(rcd != null, "found the RCD node");
|
||||
SimpleTest.is(rcd.children.length, 0, "expected no children on the RCD");
|
||||
|
||||
window.opener.finishTest();
|
||||
}
|
||||
|
@ -59,12 +59,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=982141
|
||||
// Reconstruct the APZC tree structure in the last paint.
|
||||
var apzcTree = buildApzcTree(compositorTestData.paints[lastCompositorPaintSeqNo]);
|
||||
|
||||
// The apzc tree for this page should consist of a single root APZC
|
||||
// and a child APZC for the scrollable <div>.
|
||||
SimpleTest.is(apzcTree.children.length, 1, "expected a single root APZC");
|
||||
var rootApzc = apzcTree.children[0];
|
||||
SimpleTest.is(rootApzc.children.length, 1, "expected a single child APZC");
|
||||
var childScrollId = rootApzc.children[0].scrollId;
|
||||
// The apzc tree for this page should consist of a single child APZC on
|
||||
// the RCD node (the child is for scrollable <div>). Note that in e10s/B2G
|
||||
// cases the RCD will be the root of the tree but on Fennec it will not.
|
||||
var rcd = findRcdNode(apzcTree);
|
||||
SimpleTest.ok(rcd != null, "found the RCD node");
|
||||
SimpleTest.is(rcd.children.length, 1, "expected a single child APZC");
|
||||
var childScrollId = rcd.children[0].scrollId;
|
||||
|
||||
// We should have content-side data for the same paint.
|
||||
SimpleTest.ok(lastCompositorPaintSeqNo in contentTestData.paints,
|
||||
@ -82,7 +83,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=982141
|
||||
var dpWidth = dpFields[2];
|
||||
var dpHeight = dpFields[3];
|
||||
SimpleTest.ok(dpWidth >= 50 && dpHeight >= 50,
|
||||
"expected a displayport at least as large as the scrollable element");
|
||||
"expected a displayport at least as large as the scrollable element, got " + childDisplayport);
|
||||
|
||||
window.opener.finishTest();
|
||||
}
|
||||
@ -92,6 +93,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=982141
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=982141">Mozilla Bug 982141</a>
|
||||
<!-- A scrollable subframe, with enough content to make it have a nonzero scroll range -->
|
||||
<div style="height: 50px; width: 50px; overflow: scroll">
|
||||
<div style="width: 100px">
|
||||
Wide content so that the vertical scrollbar for the parent div
|
||||
doesn't eat into the 50px width and reduce the width of the
|
||||
displayport.
|
||||
</div>
|
||||
Line 1<br>
|
||||
Line 2<br>
|
||||
Line 3<br>
|
||||
|
@ -13,9 +13,7 @@ support-files =
|
||||
helper_tap.html
|
||||
tags = apz
|
||||
[test_bug982141.html]
|
||||
skip-if = toolkit != 'gonk' # bug 991198
|
||||
[test_bug1151663.html]
|
||||
skip-if = toolkit != 'gonk' # bug 991198
|
||||
[test_wheel_scroll.html]
|
||||
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
|
||||
[test_wheel_transactions.html]
|
||||
|
@ -8,7 +8,6 @@
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.testInChaosMode();
|
||||
|
||||
// this page just serially loads each one of the following test helper pages in
|
||||
// a new window and waits for it to call testDone()
|
||||
@ -53,8 +52,10 @@ window.onload = function() {
|
||||
["apz.touch_start_tolerance", "0.0"],
|
||||
// The touchstart from the drag can turn into a long-tap if the touch-move
|
||||
// events get held up. Try to prevent that by making long-taps require
|
||||
// a 10 second hold.
|
||||
["ui.click_hold_context_menus.delay", "10000"],
|
||||
// a 10 second hold. Note that we also cannot enable chaos mode on this
|
||||
// test for this reason, since chaos mode can cause the long-press timer
|
||||
// to fire sooner than the pref dictates.
|
||||
["ui.click_hold_context_menus.delay", 10000],
|
||||
// The subtests in this test do touch-drags to pan the page, but we don't
|
||||
// want those pans to turn into fling animations, so we increase the
|
||||
// fling-stop threshold velocity to absurdly high.
|
||||
|
@ -17,6 +17,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1151663
|
||||
// inside an iframe which means we have no control over the root APZC.
|
||||
var w = null;
|
||||
window.onload = function() {
|
||||
if (!SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled) {
|
||||
ok(true, "APZ is not enabled, this test is not relevant, sorry!\n");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
SpecialPowers.pushPrefEnv({"set": [["apz.test.logging_enabled", true]]}, function() {
|
||||
w = window.open("helper_bug1151663.html", "_blank");
|
||||
});
|
||||
|
@ -17,6 +17,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=982141
|
||||
// inside an iframe which means we have no control over the root APZC.
|
||||
var w = null;
|
||||
window.onload = function() {
|
||||
if (!SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled) {
|
||||
ok(true, "APZ is not enabled, this test is not relevant, sorry!\n");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
SpecialPowers.pushPrefEnv({"set": [["apz.test.logging_enabled", true]]}, function() {
|
||||
w = window.open("helper_bug982141.html", "_blank");
|
||||
});
|
||||
|
@ -19,11 +19,12 @@ namespace mozilla {
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameChild;
|
||||
class ShadowLayerForwarder;
|
||||
} // namespace layout
|
||||
|
||||
namespace layers {
|
||||
|
||||
class ShadowLayerForwarder;
|
||||
|
||||
class LayerTransactionChild : public PLayerTransactionChild
|
||||
, public AsyncTransactionTrackersHolder
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g'
|
||||
|
||||
[test_acceleration.html]
|
||||
fail-if = (os == "win" && os_version == "5.1" && e10s) # Bug 1253862
|
||||
[test_bug509244.html]
|
||||
[test_bug513439.html]
|
||||
skip-if = e10s
|
||||
|
@ -2680,8 +2680,7 @@ class MOZ_STACK_CLASS FunctionValidator
|
||||
LocalMap::AddPtr p = locals_.lookupForAdd(name);
|
||||
if (p)
|
||||
return failName(pn, "duplicate local name '%s' not allowed", name);
|
||||
return locals_.add(p, name, Local(type, locals_.count())) &&
|
||||
fg_.addLocal(type.canonicalToValType());
|
||||
return locals_.add(p, name, Local(type, locals_.count()));
|
||||
}
|
||||
|
||||
/****************************** For consistency of returns in a function */
|
||||
@ -2823,7 +2822,7 @@ class MOZ_STACK_CLASS FunctionValidator
|
||||
return encoder().writeExpr(Expr::I32Const) &&
|
||||
encoder().writeVarU32(i32);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool writeLit(NumLit lit) {
|
||||
MOZ_WARN_UNUSED_RESULT bool writeConstExpr(NumLit lit) {
|
||||
switch (lit.which()) {
|
||||
case NumLit::Fixnum:
|
||||
case NumLit::NegativeInt:
|
||||
@ -3486,15 +3485,7 @@ CheckFinalReturn(FunctionValidator& f, ParseNode* lastNonEmptyStmt)
|
||||
}
|
||||
|
||||
static bool
|
||||
SetLocal(FunctionValidator& f, NumLit lit)
|
||||
{
|
||||
return f.encoder().writeExpr(Expr::SetLocal) &&
|
||||
f.encoder().writeVarU32(f.numLocals()) &&
|
||||
f.writeLit(lit);
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckVariable(FunctionValidator& f, ParseNode* var)
|
||||
CheckVariable(FunctionValidator& f, ParseNode* var, ValTypeVector* types, Vector<NumLit>* inits)
|
||||
{
|
||||
if (!IsDefinition(var))
|
||||
return f.fail(var, "local variable names must not restate argument names");
|
||||
@ -3515,12 +3506,11 @@ CheckVariable(FunctionValidator& f, ParseNode* var)
|
||||
if (!lit.valid())
|
||||
return f.failName(var, "var '%s' initializer out of range", name);
|
||||
|
||||
if (!lit.isZeroBits()) {
|
||||
if (!SetLocal(f, lit))
|
||||
return false;
|
||||
}
|
||||
Type type = Type::canonicalize(Type::lit(lit));
|
||||
|
||||
return f.addLocal(var, name, Type::canonicalize(Type::lit(lit)));
|
||||
return f.addLocal(var, name, type) &&
|
||||
types->append(type.canonicalToValType()) &&
|
||||
inits->append(lit);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -3528,13 +3518,40 @@ CheckVariables(FunctionValidator& f, ParseNode** stmtIter)
|
||||
{
|
||||
ParseNode* stmt = *stmtIter;
|
||||
|
||||
uint32_t firstVar = f.numLocals();
|
||||
|
||||
ValTypeVector types;
|
||||
Vector<NumLit> inits(f.cx());
|
||||
|
||||
for (; stmt && stmt->isKind(PNK_VAR); stmt = NextNonEmptyStatement(stmt)) {
|
||||
for (ParseNode* var = VarListHead(stmt); var; var = NextNode(var)) {
|
||||
if (!CheckVariable(f, var))
|
||||
if (!CheckVariable(f, var, &types, &inits))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(f.encoder().empty());
|
||||
|
||||
if (!f.encoder().writeVarU32(types.length()))
|
||||
return false;
|
||||
|
||||
for (ValType v : types) {
|
||||
if (!f.encoder().writeValType(v))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < inits.length(); i++) {
|
||||
NumLit lit = inits[i];
|
||||
if (lit.isZeroBits())
|
||||
continue;
|
||||
if (!f.encoder().writeExpr(Expr::SetLocal))
|
||||
return false;
|
||||
if (!f.encoder().writeVarU32(firstVar + i))
|
||||
return false;
|
||||
if (!f.writeConstExpr(lit))
|
||||
return false;
|
||||
}
|
||||
|
||||
*stmtIter = stmt;
|
||||
return true;
|
||||
}
|
||||
@ -3549,7 +3566,7 @@ CheckNumericLiteral(FunctionValidator& f, ParseNode* num, Type* type)
|
||||
if (!lit.valid())
|
||||
return f.fail(num, "numeric literal out of representable integer range");
|
||||
*type = Type::lit(lit);
|
||||
return f.writeLit(lit);
|
||||
return f.writeConstExpr(lit);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -3570,7 +3587,7 @@ CheckVarRef(FunctionValidator& f, ParseNode* varRef, Type* type)
|
||||
switch (global->which()) {
|
||||
case ModuleValidator::Global::ConstantLiteral:
|
||||
*type = global->varOrConstType();
|
||||
return f.writeLit(global->constLiteralValue());
|
||||
return f.writeConstExpr(global->constLiteralValue());
|
||||
case ModuleValidator::Global::ConstantImport:
|
||||
case ModuleValidator::Global::Variable: {
|
||||
*type = global->varOrConstType();
|
||||
@ -3729,14 +3746,14 @@ CheckLoadArray(FunctionValidator& f, ParseNode* elem, Type* type)
|
||||
return false;
|
||||
|
||||
switch (viewType) {
|
||||
case Scalar::Int8: f.encoder().patchExpr(opcodeAt, Expr::I32LoadMem8S); break;
|
||||
case Scalar::Uint8: f.encoder().patchExpr(opcodeAt, Expr::I32LoadMem8U); break;
|
||||
case Scalar::Int16: f.encoder().patchExpr(opcodeAt, Expr::I32LoadMem16S); break;
|
||||
case Scalar::Uint16: f.encoder().patchExpr(opcodeAt, Expr::I32LoadMem16U); break;
|
||||
case Scalar::Int8: f.encoder().patchExpr(opcodeAt, Expr::I32Load8S); break;
|
||||
case Scalar::Uint8: f.encoder().patchExpr(opcodeAt, Expr::I32Load8U); break;
|
||||
case Scalar::Int16: f.encoder().patchExpr(opcodeAt, Expr::I32Load16S); break;
|
||||
case Scalar::Uint16: f.encoder().patchExpr(opcodeAt, Expr::I32Load16U); break;
|
||||
case Scalar::Uint32:
|
||||
case Scalar::Int32: f.encoder().patchExpr(opcodeAt, Expr::I32LoadMem); break;
|
||||
case Scalar::Float32: f.encoder().patchExpr(opcodeAt, Expr::F32LoadMem); break;
|
||||
case Scalar::Float64: f.encoder().patchExpr(opcodeAt, Expr::F64LoadMem); break;
|
||||
case Scalar::Int32: f.encoder().patchExpr(opcodeAt, Expr::I32Load); break;
|
||||
case Scalar::Float32: f.encoder().patchExpr(opcodeAt, Expr::F32Load); break;
|
||||
case Scalar::Float64: f.encoder().patchExpr(opcodeAt, Expr::F64Load); break;
|
||||
default: MOZ_CRASH("unexpected scalar type");
|
||||
}
|
||||
|
||||
@ -3801,27 +3818,27 @@ CheckStoreArray(FunctionValidator& f, ParseNode* lhs, ParseNode* rhs, Type* type
|
||||
switch (viewType) {
|
||||
case Scalar::Int8:
|
||||
case Scalar::Uint8:
|
||||
f.encoder().patchExpr(opcodeAt, Expr::I32StoreMem8);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::I32Store8);
|
||||
break;
|
||||
case Scalar::Int16:
|
||||
case Scalar::Uint16:
|
||||
f.encoder().patchExpr(opcodeAt, Expr::I32StoreMem16);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::I32Store16);
|
||||
break;
|
||||
case Scalar::Int32:
|
||||
case Scalar::Uint32:
|
||||
f.encoder().patchExpr(opcodeAt, Expr::I32StoreMem);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::I32Store);
|
||||
break;
|
||||
case Scalar::Float32:
|
||||
if (rhsType.isFloatish())
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F32StoreMem);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F32Store);
|
||||
else
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F64StoreMemF32);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F64StoreF32);
|
||||
break;
|
||||
case Scalar::Float64:
|
||||
if (rhsType.isFloatish())
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F32StoreMemF64);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F32StoreF64);
|
||||
else
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F64StoreMem);
|
||||
f.encoder().patchExpr(opcodeAt, Expr::F64Store);
|
||||
break;
|
||||
default: MOZ_CRASH("unexpected scalar type");
|
||||
}
|
||||
@ -5461,7 +5478,7 @@ CheckCoercedCall(FunctionValidator& f, ParseNode* call, Type ret, Type* type)
|
||||
if (!f.encoder().writePatchableExpr(&coerceOp))
|
||||
return false;
|
||||
NumLit lit = ExtractNumericLiteral(f.m(), call);
|
||||
if (!f.writeLit(lit))
|
||||
if (!f.writeConstExpr(lit))
|
||||
return false;
|
||||
return CoerceResult(f, call, ret, Type::lit(lit), coerceOp, type);
|
||||
}
|
||||
|
@ -86,19 +86,21 @@ class FunctionDecoder
|
||||
ModuleGenerator& mg_;
|
||||
FunctionGenerator& fg_;
|
||||
uint32_t funcIndex_;
|
||||
const ValTypeVector& locals_;
|
||||
Vector<ExprType> blocks_;
|
||||
|
||||
public:
|
||||
FunctionDecoder(JSContext* cx, Decoder& d, ModuleGenerator& mg, FunctionGenerator& fg,
|
||||
uint32_t funcIndex)
|
||||
: cx_(cx), d_(d), mg_(mg), fg_(fg), funcIndex_(funcIndex), blocks_(cx)
|
||||
uint32_t funcIndex, const ValTypeVector& locals)
|
||||
: cx_(cx), d_(d), mg_(mg), fg_(fg), funcIndex_(funcIndex), locals_(locals), blocks_(cx)
|
||||
{}
|
||||
JSContext* cx() const { return cx_; }
|
||||
Decoder& d() const { return d_; }
|
||||
ModuleGenerator& mg() const { return mg_; }
|
||||
FunctionGenerator& fg() const { return fg_; }
|
||||
uint32_t funcIndex() const { return funcIndex_; }
|
||||
ExprType ret() const { return mg_.funcSig(funcIndex_).ret(); }
|
||||
const ValTypeVector& locals() const { return locals_; }
|
||||
const DeclaredSig& sig() const { return mg_.funcSig(funcIndex_); }
|
||||
|
||||
bool fail(const char* str) {
|
||||
return Fail(cx_, d_, str);
|
||||
@ -154,21 +156,19 @@ DecodeValType(JSContext* cx, Decoder& d, ValType *type)
|
||||
case ValType::I32:
|
||||
case ValType::F32:
|
||||
case ValType::F64:
|
||||
break;
|
||||
return true;
|
||||
case ValType::I64:
|
||||
#ifndef JS_CPU_X64
|
||||
return Fail(cx, d, "i64 NYI on this platform");
|
||||
#endif
|
||||
return true;
|
||||
default:
|
||||
// Note: it's important not to remove this default since readValType()
|
||||
// can return ValType values for which there is no enumerator.
|
||||
break;
|
||||
case ValType::I32x4:
|
||||
case ValType::F32x4:
|
||||
case ValType::B32x4:
|
||||
return Fail(cx, d, "value type NYI");
|
||||
case ValType::Limit:
|
||||
MOZ_CRASH("Limit");
|
||||
}
|
||||
|
||||
return true;
|
||||
return Fail(cx, "bad value type");
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -182,21 +182,19 @@ DecodeExprType(JSContext* cx, Decoder& d, ExprType *type)
|
||||
case ExprType::F32:
|
||||
case ExprType::F64:
|
||||
case ExprType::Void:
|
||||
break;
|
||||
return true;
|
||||
case ExprType::I64:
|
||||
#ifndef JS_CPU_X64
|
||||
return Fail(cx, d, "i64 NYI on this platform");
|
||||
#endif
|
||||
return true;
|
||||
default:
|
||||
// Note: it's important not to remove this default since readExprType()
|
||||
// can return ExprType values for which there is no enumerator.
|
||||
break;
|
||||
case ExprType::I32x4:
|
||||
case ExprType::F32x4:
|
||||
case ExprType::B32x4:
|
||||
return Fail(cx, d, "expression type NYI");
|
||||
case ExprType::Limit:
|
||||
MOZ_CRASH("Limit");
|
||||
}
|
||||
|
||||
return true;
|
||||
return Fail(cx, "bad expression type");
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -329,10 +327,10 @@ DecodeGetLocal(FunctionDecoder& f, ExprType* type)
|
||||
if (!f.d().readVarU32(&localIndex))
|
||||
return f.fail("unable to read get_local index");
|
||||
|
||||
if (localIndex >= f.fg().locals().length())
|
||||
if (localIndex >= f.locals().length())
|
||||
return f.fail("get_local index out of range");
|
||||
|
||||
*type = ToExprType(f.fg().locals()[localIndex]);
|
||||
*type = ToExprType(f.locals()[localIndex]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -343,10 +341,10 @@ DecodeSetLocal(FunctionDecoder& f, ExprType* type)
|
||||
if (!f.d().readVarU32(&localIndex))
|
||||
return f.fail("unable to read set_local index");
|
||||
|
||||
if (localIndex >= f.fg().locals().length())
|
||||
if (localIndex >= f.locals().length())
|
||||
return f.fail("set_local index out of range");
|
||||
|
||||
*type = ToExprType(f.fg().locals()[localIndex]);
|
||||
*type = ToExprType(f.locals()[localIndex]);
|
||||
|
||||
ExprType rhsType;
|
||||
if (!DecodeExpr(f, &rhsType))
|
||||
@ -605,12 +603,12 @@ DecodeBrTable(FunctionDecoder& f, ExprType* type)
|
||||
static bool
|
||||
DecodeReturn(FunctionDecoder& f, ExprType* type)
|
||||
{
|
||||
if (f.ret() != ExprType::Void) {
|
||||
if (f.sig().ret() != ExprType::Void) {
|
||||
ExprType actual;
|
||||
if (!DecodeExpr(f, &actual))
|
||||
return false;
|
||||
|
||||
if (!CheckType(f, actual, f.ret()))
|
||||
if (!CheckType(f, actual, f.sig().ret()))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -807,38 +805,38 @@ DecodeExpr(FunctionDecoder& f, ExprType* type)
|
||||
DecodeConversionOperator(f, ValType::F64, ValType::I64, type);
|
||||
case Expr::F64PromoteF32:
|
||||
return DecodeConversionOperator(f, ValType::F64, ValType::F32, type);
|
||||
case Expr::I32LoadMem:
|
||||
case Expr::I32LoadMem8S:
|
||||
case Expr::I32LoadMem8U:
|
||||
case Expr::I32LoadMem16S:
|
||||
case Expr::I32LoadMem16U:
|
||||
case Expr::I32Load:
|
||||
case Expr::I32Load8S:
|
||||
case Expr::I32Load8U:
|
||||
case Expr::I32Load16S:
|
||||
case Expr::I32Load16U:
|
||||
return DecodeLoad(f, ValType::I32, type);
|
||||
case Expr::I64LoadMem:
|
||||
case Expr::I64LoadMem8S:
|
||||
case Expr::I64LoadMem8U:
|
||||
case Expr::I64LoadMem16S:
|
||||
case Expr::I64LoadMem16U:
|
||||
case Expr::I64LoadMem32S:
|
||||
case Expr::I64LoadMem32U:
|
||||
case Expr::I64Load:
|
||||
case Expr::I64Load8S:
|
||||
case Expr::I64Load8U:
|
||||
case Expr::I64Load16S:
|
||||
case Expr::I64Load16U:
|
||||
case Expr::I64Load32S:
|
||||
case Expr::I64Load32U:
|
||||
return f.fail("NYI: i64") &&
|
||||
DecodeLoad(f, ValType::I64, type);
|
||||
case Expr::F32LoadMem:
|
||||
case Expr::F32Load:
|
||||
return DecodeLoad(f, ValType::F32, type);
|
||||
case Expr::F64LoadMem:
|
||||
case Expr::F64Load:
|
||||
return DecodeLoad(f, ValType::F64, type);
|
||||
case Expr::I32StoreMem:
|
||||
case Expr::I32StoreMem8:
|
||||
case Expr::I32StoreMem16:
|
||||
case Expr::I32Store:
|
||||
case Expr::I32Store8:
|
||||
case Expr::I32Store16:
|
||||
return DecodeStore(f, ValType::I32, type);
|
||||
case Expr::I64StoreMem:
|
||||
case Expr::I64StoreMem8:
|
||||
case Expr::I64StoreMem16:
|
||||
case Expr::I64StoreMem32:
|
||||
case Expr::I64Store:
|
||||
case Expr::I64Store8:
|
||||
case Expr::I64Store16:
|
||||
case Expr::I64Store32:
|
||||
return f.fail("NYI: i64") &&
|
||||
DecodeStore(f, ValType::I64, type);
|
||||
case Expr::F32StoreMem:
|
||||
case Expr::F32Store:
|
||||
return DecodeStore(f, ValType::F32, type);
|
||||
case Expr::F64StoreMem:
|
||||
case Expr::F64Store:
|
||||
return DecodeStore(f, ValType::F64, type);
|
||||
case Expr::Br:
|
||||
return DecodeBr(f, type);
|
||||
@ -849,6 +847,8 @@ DecodeExpr(FunctionDecoder& f, ExprType* type)
|
||||
case Expr::Return:
|
||||
return DecodeReturn(f, type);
|
||||
default:
|
||||
// Note: it's important not to remove this default since readExpr()
|
||||
// can return Expr values for which there is no enumerator.
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1240,15 +1240,23 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
|
||||
{
|
||||
int64_t before = PRMJ_Now();
|
||||
|
||||
uint32_t bodySize;
|
||||
if (!d.readVarU32(&bodySize))
|
||||
return Fail(cx, d, "expected number of function body bytes");
|
||||
|
||||
if (d.bytesRemain() < bodySize)
|
||||
return Fail(cx, d, "function body length too big");
|
||||
|
||||
const uint8_t* bodyBegin = d.currentPosition();
|
||||
const uint8_t* bodyEnd = bodyBegin + bodySize;
|
||||
|
||||
FunctionGenerator fg;
|
||||
if (!mg.startFuncDef(d.currentOffset(), &fg))
|
||||
return false;
|
||||
|
||||
const DeclaredSig& sig = mg.funcSig(funcIndex);
|
||||
for (ValType type : sig.args()) {
|
||||
if (!fg.addLocal(type))
|
||||
return false;
|
||||
}
|
||||
ValTypeVector locals;
|
||||
if (!locals.appendAll(mg.funcSig(funcIndex).args()))
|
||||
return false;
|
||||
|
||||
uint32_t numVars;
|
||||
if (!d.readVarU32(&numVars))
|
||||
@ -1258,21 +1266,11 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
|
||||
ValType type;
|
||||
if (!DecodeValType(cx, d, &type))
|
||||
return false;
|
||||
if (!fg.addLocal(type))
|
||||
if (!locals.append(type))
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionDecoder f(cx, d, mg, fg, funcIndex);
|
||||
|
||||
uint32_t numBytes;
|
||||
if (!d.readVarU32(&numBytes))
|
||||
return Fail(cx, d, "expected number of function body bytes");
|
||||
|
||||
if (d.bytesRemain() < numBytes)
|
||||
return Fail(cx, d, "function body length too big");
|
||||
|
||||
const uint8_t* bodyBegin = d.currentPosition();
|
||||
const uint8_t* bodyEnd = bodyBegin + numBytes;
|
||||
FunctionDecoder f(cx, d, mg, fg, funcIndex, locals);
|
||||
|
||||
ExprType type = ExprType::Void;
|
||||
|
||||
@ -1281,17 +1279,16 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CheckType(f, type, f.sig().ret()))
|
||||
return false;
|
||||
|
||||
if (d.currentPosition() != bodyEnd)
|
||||
return Fail(cx, d, "function body length mismatch");
|
||||
|
||||
if (!CheckType(f, type, f.ret()))
|
||||
if (!fg.bytecode().resize(bodySize))
|
||||
return false;
|
||||
|
||||
uintptr_t bodyLength = bodyEnd - bodyBegin;
|
||||
if (!fg.bytecode().resize(bodyLength))
|
||||
return false;
|
||||
|
||||
memcpy(fg.bytecode().begin(), bodyBegin, bodyLength);
|
||||
memcpy(fg.bytecode().begin(), bodyBegin, bodySize);
|
||||
|
||||
int64_t after = PRMJ_Now();
|
||||
unsigned generateTime = (after - before) / PRMJ_USEC_PER_MSEC;
|
||||
@ -1517,17 +1514,23 @@ ImportFunctions(JSContext* cx, HandleObject importObj, const ImportNameVector& i
|
||||
}
|
||||
|
||||
bool
|
||||
wasm::Eval(JSContext* cx, Handle<ArrayBufferObject*> code,
|
||||
HandleObject importObj, MutableHandleObject exportObj)
|
||||
wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj,
|
||||
MutableHandleObject exportObj)
|
||||
{
|
||||
MOZ_ASSERT(!code->isSharedMemory());
|
||||
|
||||
if (!CheckCompilerSupport(cx))
|
||||
return false;
|
||||
|
||||
const uint8_t* bytes = code->dataPointer();
|
||||
if (!TypedArrayObject::ensureHasBuffer(cx, code))
|
||||
return false;
|
||||
|
||||
const uint8_t* bufferStart = code->bufferUnshared()->dataPointer();
|
||||
const uint8_t* bytes = bufferStart + code->byteOffset();
|
||||
uint32_t length = code->byteLength();
|
||||
|
||||
Vector<uint8_t> copy(cx);
|
||||
if (code->hasInlineData()) {
|
||||
if (code->bufferUnshared()->hasInlineData()) {
|
||||
if (!copy.append(bytes, length))
|
||||
return false;
|
||||
bytes = copy.begin();
|
||||
@ -1551,10 +1554,7 @@ wasm::Eval(JSContext* cx, Handle<ArrayBufferObject*> code,
|
||||
if (!ImportFunctions(cx, importObj, importNames, &imports))
|
||||
return false;
|
||||
|
||||
if (!moduleObj->module().dynamicallyLink(cx, moduleObj, heap, imports, *exportMap, exportObj))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return moduleObj->module().dynamicallyLink(cx, moduleObj, heap, imports, *exportMap, exportObj);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1563,7 +1563,13 @@ InstantiateModule(JSContext* cx, unsigned argc, Value* vp)
|
||||
MOZ_ASSERT(cx->runtime()->options().wasm());
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!args.get(0).isObject() || !args.get(0).toObject().is<ArrayBufferObject>()) {
|
||||
if (!args.get(0).isObject() || !args.get(0).toObject().is<TypedArrayObject>()) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_BUF_ARG);
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<TypedArrayObject*> code(cx, &args[0].toObject().as<TypedArrayObject>());
|
||||
if (code->isSharedMemory()) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_BUF_ARG);
|
||||
return false;
|
||||
}
|
||||
@ -1577,8 +1583,6 @@ InstantiateModule(JSContext* cx, unsigned argc, Value* vp)
|
||||
importObj = &args[1].toObject();
|
||||
}
|
||||
|
||||
Rooted<ArrayBufferObject*> code(cx, &args[0].toObject().as<ArrayBufferObject>());
|
||||
|
||||
RootedObject exportObj(cx);
|
||||
if (!Eval(cx, code, importObj, &exportObj))
|
||||
return false;
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
class ArrayBufferObject;
|
||||
class TypedArrayObject;
|
||||
|
||||
namespace wasm {
|
||||
|
||||
@ -49,7 +49,7 @@ static const uint64_t MappedSize = 2 * Uint32Range + PageSize;
|
||||
// Compiles the given binary wasm module given the ArrayBufferObject
|
||||
// and links the module's imports with the given import object.
|
||||
bool
|
||||
Eval(JSContext* cx, Handle<ArrayBufferObject*> code, HandleObject importObj,
|
||||
Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj,
|
||||
MutableHandleObject exportObj);
|
||||
|
||||
} // namespace wasm
|
||||
|
@ -19,24 +19,18 @@
|
||||
#ifndef wasm_binary_h
|
||||
#define wasm_binary_h
|
||||
|
||||
#include "jsstr.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "asmjs/WasmTypes.h"
|
||||
#include "builtin/SIMD.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
class PropertyName;
|
||||
|
||||
namespace wasm {
|
||||
|
||||
// Module header constants
|
||||
static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
|
||||
static const uint32_t EncodingVersion = 0xa; // will change while iterating toward release,
|
||||
// change to 1 at release, and hopefully never
|
||||
// change after that
|
||||
using mozilla::DebugOnly;
|
||||
|
||||
static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
|
||||
static const uint32_t EncodingVersion = 0xa;
|
||||
|
||||
// Section ids:
|
||||
static const char SignaturesId[] = "signatures";
|
||||
static const char ImportTableId[] = "import_table";
|
||||
static const char FunctionSignaturesId[] = "function_signatures";
|
||||
@ -46,199 +40,234 @@ static const char ExportTableId[] = "export_table";
|
||||
static const char FunctionBodiesId[] = "function_bodies";
|
||||
static const char DataSegmentsId[] = "data_segments";
|
||||
|
||||
enum class Expr : uint16_t
|
||||
enum class ValType
|
||||
{
|
||||
// Control opcodes
|
||||
Nop = 0x00,
|
||||
Block = 0x01,
|
||||
Loop = 0x02,
|
||||
If = 0x03,
|
||||
IfElse = 0x04,
|
||||
Select = 0x05,
|
||||
Br = 0x06,
|
||||
BrIf = 0x07,
|
||||
BrTable = 0x08,
|
||||
Return = 0x14,
|
||||
Unreachable = 0x15,
|
||||
// 0x00 is reserved for ExprType::Void in the binary encoding. See comment
|
||||
// below about ExprType going away.
|
||||
|
||||
// Calls
|
||||
Call = 0x12,
|
||||
CallIndirect = 0x13,
|
||||
CallImport = 0x1f,
|
||||
I32 = 0x01,
|
||||
I64 = 0x02,
|
||||
F32 = 0x03,
|
||||
F64 = 0x04,
|
||||
|
||||
// Constants and calls
|
||||
I32Const = 0x0a,
|
||||
I64Const = 0x0b,
|
||||
F64Const = 0x0c,
|
||||
F32Const = 0x0d,
|
||||
GetLocal = 0x0e,
|
||||
SetLocal = 0x0f,
|
||||
// ------------------------------------------------------------------------
|
||||
// The rest of these types are currently only emitted internally when
|
||||
// compiling asm.js and are rejected by wasm validation.
|
||||
|
||||
// I32 opcodes
|
||||
I32Add = 0x40,
|
||||
I32Sub = 0x41,
|
||||
I32Mul = 0x42,
|
||||
I32DivS = 0x43,
|
||||
I32DivU = 0x44,
|
||||
I32RemS = 0x45,
|
||||
I32RemU = 0x46,
|
||||
I32Or = 0x48,
|
||||
I32And = 0x47,
|
||||
I32Xor = 0x49,
|
||||
I32Shl = 0x4a,
|
||||
I32ShrU = 0x4b,
|
||||
I32ShrS = 0x4c,
|
||||
I32Eq = 0x4d,
|
||||
I32Ne = 0x4e,
|
||||
I32LtS = 0x4f,
|
||||
I32LeS = 0x50,
|
||||
I32LtU = 0x51,
|
||||
I32LeU = 0x52,
|
||||
I32GtS = 0x53,
|
||||
I32GeS = 0x54,
|
||||
I32GtU = 0x55,
|
||||
I32GeU = 0x56,
|
||||
I32Clz = 0x57,
|
||||
I32Ctz = 0x58,
|
||||
I32Popcnt = 0x59,
|
||||
I32x4,
|
||||
F32x4,
|
||||
B32x4,
|
||||
|
||||
// I64 opcodes
|
||||
I64Add = 0x5b,
|
||||
I64Sub = 0x5c,
|
||||
I64Mul = 0x5d,
|
||||
I64DivS = 0x5e,
|
||||
I64DivU = 0x5f,
|
||||
I64RemS = 0x60,
|
||||
I64RemU = 0x61,
|
||||
I64Or = 0x63,
|
||||
I64And = 0x62,
|
||||
I64Xor = 0x64,
|
||||
I64Shl = 0x65,
|
||||
I64ShrU = 0x66,
|
||||
I64ShrS = 0x67,
|
||||
I64Eq = 0x68,
|
||||
I64Ne = 0x69,
|
||||
I64LtS = 0x6a,
|
||||
I64LeS = 0x6b,
|
||||
I64LtU = 0x6c,
|
||||
I64LeU = 0x6d,
|
||||
I64GtS = 0x6e,
|
||||
I64GeS = 0x6f,
|
||||
I64GtU = 0x70,
|
||||
I64GeU = 0x71,
|
||||
I64Clz = 0x72,
|
||||
I64Ctz = 0x73,
|
||||
I64Popcnt = 0x74,
|
||||
Limit
|
||||
};
|
||||
|
||||
// F32 opcodes
|
||||
F32Add = 0x75,
|
||||
F32Sub = 0x76,
|
||||
F32Mul = 0x77,
|
||||
F32Div = 0x78,
|
||||
F32Min = 0x79,
|
||||
F32Max = 0x7a,
|
||||
F32Abs = 0x7b,
|
||||
F32Neg = 0x7c,
|
||||
F32CopySign = 0x7d,
|
||||
F32Ceil = 0x7e,
|
||||
F32Floor = 0x7f,
|
||||
F32Trunc = 0x80,
|
||||
F32Nearest = 0x81,
|
||||
F32Sqrt = 0x82,
|
||||
F32Eq = 0x83,
|
||||
F32Ne = 0x84,
|
||||
F32Lt = 0x85,
|
||||
F32Le = 0x86,
|
||||
F32Gt = 0x87,
|
||||
F32Ge = 0x88,
|
||||
enum class Expr
|
||||
{
|
||||
// Control flow operators
|
||||
Nop = 0x00,
|
||||
Block = 0x01,
|
||||
Loop = 0x02,
|
||||
If = 0x03,
|
||||
IfElse = 0x04,
|
||||
Select = 0x05,
|
||||
Br = 0x06,
|
||||
BrIf = 0x07,
|
||||
BrTable = 0x08,
|
||||
Return = 0x14,
|
||||
Unreachable = 0x15,
|
||||
|
||||
// F64 opcodes
|
||||
F64Add = 0x89,
|
||||
F64Sub = 0x8a,
|
||||
F64Mul = 0x8b,
|
||||
F64Div = 0x8c,
|
||||
F64Min = 0x8d,
|
||||
F64Max = 0x8e,
|
||||
F64Abs = 0x8f,
|
||||
F64Neg = 0x90,
|
||||
F64CopySign = 0x91,
|
||||
F64Ceil = 0x92,
|
||||
F64Floor = 0x93,
|
||||
F64Trunc = 0x94,
|
||||
F64Nearest = 0x95,
|
||||
F64Sqrt = 0x96,
|
||||
F64Eq = 0x97,
|
||||
F64Ne = 0x98,
|
||||
F64Lt = 0x99,
|
||||
F64Le = 0x9a,
|
||||
F64Gt = 0x9b,
|
||||
F64Ge = 0x9c,
|
||||
// Basic operators
|
||||
I32Const = 0x0a,
|
||||
I64Const = 0x0b,
|
||||
F64Const = 0x0c,
|
||||
F32Const = 0x0d,
|
||||
GetLocal = 0x0e,
|
||||
SetLocal = 0x0f,
|
||||
Call = 0x12,
|
||||
CallIndirect = 0x13,
|
||||
CallImport = 0x1f,
|
||||
|
||||
// Memory-related operators
|
||||
I32Load8S = 0x20,
|
||||
I32Load8U = 0x21,
|
||||
I32Load16S = 0x22,
|
||||
I32Load16U = 0x23,
|
||||
I64Load8S = 0x24,
|
||||
I64Load8U = 0x25,
|
||||
I64Load16S = 0x26,
|
||||
I64Load16U = 0x27,
|
||||
I64Load32S = 0x28,
|
||||
I64Load32U = 0x29,
|
||||
I32Load = 0x2a,
|
||||
I64Load = 0x2b,
|
||||
F32Load = 0x2c,
|
||||
F64Load = 0x2d,
|
||||
I32Store8 = 0x2e,
|
||||
I32Store16 = 0x2f,
|
||||
I64Store8 = 0x30,
|
||||
I64Store16 = 0x31,
|
||||
I64Store32 = 0x32,
|
||||
I32Store = 0x33,
|
||||
I64Store = 0x34,
|
||||
F32Store = 0x35,
|
||||
F64Store = 0x36,
|
||||
MemorySize = 0x3b,
|
||||
GrowMemory = 0x39,
|
||||
|
||||
// i32 operators
|
||||
I32Add = 0x40,
|
||||
I32Sub = 0x41,
|
||||
I32Mul = 0x42,
|
||||
I32DivS = 0x43,
|
||||
I32DivU = 0x44,
|
||||
I32RemS = 0x45,
|
||||
I32RemU = 0x46,
|
||||
I32And = 0x47,
|
||||
I32Or = 0x48,
|
||||
I32Xor = 0x49,
|
||||
I32Shl = 0x4a,
|
||||
I32ShrU = 0x4b,
|
||||
I32ShrS = 0x4c,
|
||||
I32Eq = 0x4d,
|
||||
I32Ne = 0x4e,
|
||||
I32LtS = 0x4f,
|
||||
I32LeS = 0x50,
|
||||
I32LtU = 0x51,
|
||||
I32LeU = 0x52,
|
||||
I32GtS = 0x53,
|
||||
I32GeS = 0x54,
|
||||
I32GtU = 0x55,
|
||||
I32GeU = 0x56,
|
||||
I32Clz = 0x57,
|
||||
I32Ctz = 0x58,
|
||||
I32Popcnt = 0x59,
|
||||
|
||||
// i64 operators
|
||||
I64Add = 0x5b,
|
||||
I64Sub = 0x5c,
|
||||
I64Mul = 0x5d,
|
||||
I64DivS = 0x5e,
|
||||
I64DivU = 0x5f,
|
||||
I64RemS = 0x60,
|
||||
I64RemU = 0x61,
|
||||
I64And = 0x62,
|
||||
I64Or = 0x63,
|
||||
I64Xor = 0x64,
|
||||
I64Shl = 0x65,
|
||||
I64ShrU = 0x66,
|
||||
I64ShrS = 0x67,
|
||||
I64Eq = 0x68,
|
||||
I64Ne = 0x69,
|
||||
I64LtS = 0x6a,
|
||||
I64LeS = 0x6b,
|
||||
I64LtU = 0x6c,
|
||||
I64LeU = 0x6d,
|
||||
I64GtS = 0x6e,
|
||||
I64GeS = 0x6f,
|
||||
I64GtU = 0x70,
|
||||
I64GeU = 0x71,
|
||||
I64Clz = 0x72,
|
||||
I64Ctz = 0x73,
|
||||
I64Popcnt = 0x74,
|
||||
|
||||
// f32 opcodes
|
||||
F32Add = 0x75,
|
||||
F32Sub = 0x76,
|
||||
F32Mul = 0x77,
|
||||
F32Div = 0x78,
|
||||
F32Min = 0x79,
|
||||
F32Max = 0x7a,
|
||||
F32Abs = 0x7b,
|
||||
F32Neg = 0x7c,
|
||||
F32CopySign = 0x7d,
|
||||
F32Ceil = 0x7e,
|
||||
F32Floor = 0x7f,
|
||||
F32Trunc = 0x80,
|
||||
F32Nearest = 0x81,
|
||||
F32Sqrt = 0x82,
|
||||
F32Eq = 0x83,
|
||||
F32Ne = 0x84,
|
||||
F32Lt = 0x85,
|
||||
F32Le = 0x86,
|
||||
F32Gt = 0x87,
|
||||
F32Ge = 0x88,
|
||||
|
||||
// f64 opcodes
|
||||
F64Add = 0x89,
|
||||
F64Sub = 0x8a,
|
||||
F64Mul = 0x8b,
|
||||
F64Div = 0x8c,
|
||||
F64Min = 0x8d,
|
||||
F64Max = 0x8e,
|
||||
F64Abs = 0x8f,
|
||||
F64Neg = 0x90,
|
||||
F64CopySign = 0x91,
|
||||
F64Ceil = 0x92,
|
||||
F64Floor = 0x93,
|
||||
F64Trunc = 0x94,
|
||||
F64Nearest = 0x95,
|
||||
F64Sqrt = 0x96,
|
||||
F64Eq = 0x97,
|
||||
F64Ne = 0x98,
|
||||
F64Lt = 0x99,
|
||||
F64Le = 0x9a,
|
||||
F64Gt = 0x9b,
|
||||
F64Ge = 0x9c,
|
||||
|
||||
// Conversions
|
||||
I32WrapI64 = 0xa1,
|
||||
I64ExtendSI32 = 0xa6,
|
||||
I64ExtendUI32 = 0xa7,
|
||||
I32TruncSF32 = 0x9d,
|
||||
I32TruncSF64 = 0x9e,
|
||||
I32TruncUF32 = 0x9f,
|
||||
I32TruncUF64 = 0xa0,
|
||||
I64TruncSF32 = 0xa2,
|
||||
I64TruncSF64 = 0xa3,
|
||||
I64TruncUF32 = 0xa4,
|
||||
I64TruncUF64 = 0xa5,
|
||||
F32ConvertSI32 = 0xa8,
|
||||
F32ConvertUI32 = 0xa9,
|
||||
F64ConvertSI32 = 0xae,
|
||||
F64ConvertUI32 = 0xaf,
|
||||
F32ConvertSI64 = 0xaa,
|
||||
F32ConvertUI64 = 0xab,
|
||||
F64ConvertSI64 = 0xb0,
|
||||
F64ConvertUI64 = 0xb1,
|
||||
F32DemoteF64 = 0xac,
|
||||
F64PromoteF32 = 0xb2,
|
||||
I32ReinterpretF32 = 0xb4,
|
||||
F32ReinterpretI32 = 0xad,
|
||||
I64ReinterpretF64 = 0xb5,
|
||||
F64ReinterpretI64 = 0xb3,
|
||||
I32TruncSF32 = 0x9d,
|
||||
I32TruncSF64 = 0x9e,
|
||||
I32TruncUF32 = 0x9f,
|
||||
I32TruncUF64 = 0xa0,
|
||||
I32WrapI64 = 0xa1,
|
||||
I64TruncSF32 = 0xa2,
|
||||
I64TruncSF64 = 0xa3,
|
||||
I64TruncUF32 = 0xa4,
|
||||
I64TruncUF64 = 0xa5,
|
||||
I64ExtendSI32 = 0xa6,
|
||||
I64ExtendUI32 = 0xa7,
|
||||
F32ConvertSI32 = 0xa8,
|
||||
F32ConvertUI32 = 0xa9,
|
||||
F32ConvertSI64 = 0xaa,
|
||||
F32ConvertUI64 = 0xab,
|
||||
F32DemoteF64 = 0xac,
|
||||
F32ReinterpretI32 = 0xad,
|
||||
F64ConvertSI32 = 0xae,
|
||||
F64ConvertUI32 = 0xaf,
|
||||
F64ConvertSI64 = 0xb0,
|
||||
F64ConvertUI64 = 0xb1,
|
||||
F64PromoteF32 = 0xb2,
|
||||
F64ReinterpretI64 = 0xb3,
|
||||
I32ReinterpretF32 = 0xb4,
|
||||
I64ReinterpretF64 = 0xb5,
|
||||
|
||||
// Load/store operations
|
||||
I32LoadMem8S = 0x20,
|
||||
I32LoadMem8U = 0x21,
|
||||
I32LoadMem16S = 0x22,
|
||||
I32LoadMem16U = 0x23,
|
||||
I32LoadMem = 0x2a,
|
||||
I64LoadMem8S = 0x24,
|
||||
I64LoadMem8U = 0x25,
|
||||
I64LoadMem16S = 0x26,
|
||||
I64LoadMem16U = 0x27,
|
||||
I64LoadMem32S = 0x28,
|
||||
I64LoadMem32U = 0x29,
|
||||
I64LoadMem = 0x2b,
|
||||
F32LoadMem = 0x2c,
|
||||
F64LoadMem = 0x2d,
|
||||
|
||||
I32StoreMem8 = 0x2e,
|
||||
I32StoreMem16 = 0x2f,
|
||||
I64StoreMem8 = 0x30,
|
||||
I64StoreMem16 = 0x31,
|
||||
I64StoreMem32 = 0x32,
|
||||
I32StoreMem = 0x33,
|
||||
I64StoreMem = 0x34,
|
||||
F32StoreMem = 0x35,
|
||||
F64StoreMem = 0x36,
|
||||
|
||||
// Special operators
|
||||
MemorySize = 0x3b,
|
||||
GrowMemory = 0x39,
|
||||
|
||||
// asm.js specific
|
||||
Id = 0xc0, // Encodings from here down are specific to baldr.
|
||||
// ------------------------------------------------------------------------
|
||||
// The rest of these operators are currently only emitted internally when
|
||||
// compiling asm.js and are rejected by wasm validation.
|
||||
|
||||
// asm.js-specific operators
|
||||
Id = 0xc0,
|
||||
LoadGlobal,
|
||||
StoreGlobal,
|
||||
|
||||
I32Min,
|
||||
I32Max,
|
||||
I32Not,
|
||||
I32Neg,
|
||||
I32BitNot,
|
||||
I32Abs,
|
||||
F32StoreF64,
|
||||
F64StoreF32,
|
||||
F64Mod,
|
||||
F64Sin,
|
||||
F64Cos,
|
||||
F64Tan,
|
||||
F64Asin,
|
||||
F64Acos,
|
||||
F64Atan,
|
||||
F64Exp,
|
||||
F64Log,
|
||||
F64Pow,
|
||||
F64Atan2,
|
||||
|
||||
// Atomics
|
||||
AtomicsFence,
|
||||
@ -263,7 +292,6 @@ enum class Expr : uint16_t
|
||||
I32x4greaterThanU,
|
||||
I32x4greaterThanOrEqualU,
|
||||
I32x4fromFloat32x4U,
|
||||
|
||||
#define _(OP) SIMD_OPCODE(F32x4, OP)
|
||||
FORALL_FLOAT32X4_ASMJS_OP(_)
|
||||
F32x4Constructor,
|
||||
@ -276,40 +304,37 @@ enum class Expr : uint16_t
|
||||
#undef _
|
||||
#undef OPCODE
|
||||
|
||||
// I32 asm.js opcodes
|
||||
I32Not,
|
||||
I32Neg,
|
||||
I32BitNot,
|
||||
I32Abs,
|
||||
Limit
|
||||
};
|
||||
|
||||
// F32 asm.js opcodes
|
||||
F32StoreMemF64,
|
||||
// The ExprType enum represents the type of a WebAssembly expression or return
|
||||
// value and may either be a value type or void. Soon, expression types will be
|
||||
// generalized to a list of ValType and this enum will go away, replaced,
|
||||
// wherever it is used, by a varU32 + list of ValType.
|
||||
|
||||
// F64 asm.js opcodes
|
||||
F64Mod,
|
||||
|
||||
F64Sin,
|
||||
F64Cos,
|
||||
F64Tan,
|
||||
F64Asin,
|
||||
F64Acos,
|
||||
F64Atan,
|
||||
F64Exp,
|
||||
F64Log,
|
||||
F64Pow,
|
||||
F64Atan2,
|
||||
|
||||
F64StoreMemF32,
|
||||
enum class ExprType
|
||||
{
|
||||
Void = 0x00,
|
||||
I32 = uint8_t(ValType::I32),
|
||||
I64 = uint8_t(ValType::I64),
|
||||
F32 = uint8_t(ValType::F32),
|
||||
F64 = uint8_t(ValType::F64),
|
||||
I32x4 = uint8_t(ValType::I32x4),
|
||||
F32x4 = uint8_t(ValType::F32x4),
|
||||
B32x4 = uint8_t(ValType::B32x4),
|
||||
|
||||
Limit
|
||||
};
|
||||
|
||||
typedef int32_t I32x4[4];
|
||||
typedef float F32x4[4];
|
||||
typedef Vector<uint8_t, 0, SystemAllocPolicy> Bytecode;
|
||||
typedef UniquePtr<Bytecode> UniqueBytecode;
|
||||
|
||||
// The Encoder class appends bytes to the Bytecode object it is given during
|
||||
// construction. The client is responsible for the Bytecode's lifetime and must
|
||||
// keep the Bytecode alive as long as the Encoder is used.
|
||||
|
||||
class Encoder
|
||||
{
|
||||
Bytecode& bytecode_;
|
||||
@ -399,11 +424,11 @@ class Encoder
|
||||
MOZ_WARN_UNUSED_RESULT bool writeFixedF64(double d) {
|
||||
return write<double>(d);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool writeFixedI32x4(const Val::I32x4& i32x4) {
|
||||
return write<Val::I32x4>(i32x4);
|
||||
MOZ_WARN_UNUSED_RESULT bool writeFixedI32x4(const I32x4& i32x4) {
|
||||
return write<I32x4>(i32x4);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool writeFixedF32x4(const Val::F32x4& f32x4) {
|
||||
return write<Val::F32x4>(f32x4);
|
||||
MOZ_WARN_UNUSED_RESULT bool writeFixedF32x4(const F32x4& f32x4) {
|
||||
return write<F32x4>(f32x4);
|
||||
}
|
||||
|
||||
// Variable-length encodings that all use LEB128.
|
||||
@ -494,6 +519,10 @@ class Encoder
|
||||
}
|
||||
};
|
||||
|
||||
// The Decoder class decodes the bytes in the range it is given during
|
||||
// construction. The client is responsible for keeping the byte range alive as
|
||||
// long as the Decoder is used.
|
||||
|
||||
class Decoder
|
||||
{
|
||||
const uint8_t* const beg_;
|
||||
@ -607,11 +636,11 @@ class Decoder
|
||||
MOZ_WARN_UNUSED_RESULT bool readFixedF64(double* d = nullptr) {
|
||||
return read<double>(d);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool readFixedI32x4(Val::I32x4* i32x4 = nullptr) {
|
||||
return read<Val::I32x4>(i32x4);
|
||||
MOZ_WARN_UNUSED_RESULT bool readFixedI32x4(I32x4* i32x4 = nullptr) {
|
||||
return read<I32x4>(i32x4);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool readFixedF32x4(Val::F32x4* f32x4 = nullptr) {
|
||||
return read<Val::F32x4>(f32x4);
|
||||
MOZ_WARN_UNUSED_RESULT bool readFixedF32x4(F32x4* f32x4 = nullptr) {
|
||||
return read<F32x4>(f32x4);
|
||||
}
|
||||
|
||||
// Variable-length encodings that all use LEB128.
|
||||
@ -625,10 +654,10 @@ class Decoder
|
||||
MOZ_WARN_UNUSED_RESULT bool readExpr(Expr* expr = nullptr) {
|
||||
return readEnum(expr);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool readValType(ValType* type = nullptr) {
|
||||
MOZ_WARN_UNUSED_RESULT bool readValType(ValType* type) {
|
||||
return readEnum(type);
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool readExprType(ExprType* type = nullptr) {
|
||||
MOZ_WARN_UNUSED_RESULT bool readExprType(ExprType* type) {
|
||||
return readEnum(type);
|
||||
}
|
||||
|
||||
@ -751,6 +780,9 @@ class Decoder
|
||||
cur_ = before;
|
||||
return ret;
|
||||
}
|
||||
ValType uncheckedReadValType() {
|
||||
return uncheckedReadEnum<ValType>();
|
||||
}
|
||||
|
||||
// Temporary encoding forms which should be removed as part of the
|
||||
// conversion to wasm:
|
||||
@ -766,66 +798,6 @@ class Decoder
|
||||
}
|
||||
};
|
||||
|
||||
// The FuncBytecode class contains the intermediate representation of a
|
||||
// parsed/decoded and validated asm.js/WebAssembly function. The FuncBytecode
|
||||
// lives only until it is fully compiled.
|
||||
class FuncBytecode
|
||||
{
|
||||
// Function metadata
|
||||
const DeclaredSig& sig_;
|
||||
ValTypeVector locals_;
|
||||
uint32_t lineOrBytecode_;
|
||||
Uint32Vector callSiteLineNums_;
|
||||
|
||||
// Compilation bookkeeping
|
||||
uint32_t index_;
|
||||
unsigned generateTime_;
|
||||
|
||||
UniqueBytecode bytecode_;
|
||||
|
||||
public:
|
||||
FuncBytecode(uint32_t index,
|
||||
const DeclaredSig& sig,
|
||||
UniqueBytecode bytecode,
|
||||
ValTypeVector&& locals,
|
||||
uint32_t lineOrBytecode,
|
||||
Uint32Vector&& callSiteLineNums,
|
||||
unsigned generateTime)
|
||||
: sig_(sig),
|
||||
locals_(Move(locals)),
|
||||
lineOrBytecode_(lineOrBytecode),
|
||||
callSiteLineNums_(Move(callSiteLineNums)),
|
||||
index_(index),
|
||||
generateTime_(generateTime),
|
||||
bytecode_(Move(bytecode))
|
||||
{}
|
||||
|
||||
UniqueBytecode recycleBytecode() { return Move(bytecode_); }
|
||||
|
||||
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
|
||||
const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
|
||||
uint32_t index() const { return index_; }
|
||||
const DeclaredSig& sig() const { return sig_; }
|
||||
const Bytecode& bytecode() const { return *bytecode_; }
|
||||
|
||||
size_t numLocals() const { return locals_.length(); }
|
||||
ValType localType(size_t i) const { return locals_[i]; }
|
||||
|
||||
unsigned generateTime() const { return generateTime_; }
|
||||
};
|
||||
|
||||
typedef UniquePtr<FuncBytecode> UniqueFuncBytecode;
|
||||
|
||||
// Module generator limits
|
||||
|
||||
static const unsigned MaxSigs = 4 * 1024;
|
||||
static const unsigned MaxFuncs = 512 * 1024;
|
||||
static const unsigned MaxImports = 4 * 1024;
|
||||
static const unsigned MaxExports = 4 * 1024;
|
||||
static const unsigned MaxTableElems = 128 * 1024;
|
||||
static const unsigned MaxArgsPerFunc = 4 * 1024;
|
||||
static const unsigned MaxBrTableElems = 4 * 1024;
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace js
|
||||
|
||||
|
@ -807,7 +807,6 @@ ModuleGenerator::finishFuncDef(uint32_t funcIndex, unsigned generateTime, Functi
|
||||
js::MakeUnique<FuncBytecode>(funcIndex,
|
||||
funcSig(funcIndex),
|
||||
Move(fg->bytecode_),
|
||||
Move(fg->locals_),
|
||||
fg->lineOrBytecode_,
|
||||
Move(fg->callSiteLineNums_),
|
||||
generateTime);
|
||||
|
@ -295,7 +295,6 @@ class MOZ_STACK_CLASS FunctionGenerator
|
||||
// FuncBytecode in ModuleGenerator::finishFunc().
|
||||
UniqueBytecode bytecode_;
|
||||
Uint32Vector callSiteLineNums_;
|
||||
ValTypeVector locals_;
|
||||
|
||||
uint32_t lineOrBytecode_;
|
||||
|
||||
@ -310,12 +309,6 @@ class MOZ_STACK_CLASS FunctionGenerator
|
||||
bool addCallSiteLineNum(uint32_t lineno) {
|
||||
return callSiteLineNums_.append(lineno);
|
||||
}
|
||||
bool addLocal(ValType v) {
|
||||
return locals_.append(v);
|
||||
}
|
||||
const ValTypeVector& locals() const {
|
||||
return locals_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace wasm
|
||||
|
@ -39,8 +39,9 @@ class FunctionCompiler
|
||||
typedef Vector<BlockVector, 0, SystemAllocPolicy> BlocksVector;
|
||||
|
||||
ModuleGeneratorThreadView& mg_;
|
||||
Decoder& decoder_;
|
||||
const FuncBytecode& func_;
|
||||
Decoder decoder_;
|
||||
const ValTypeVector& locals_;
|
||||
size_t lastReadCallSite_;
|
||||
|
||||
TempAllocator& alloc_;
|
||||
@ -57,11 +58,16 @@ class FunctionCompiler
|
||||
FuncCompileResults& compileResults_;
|
||||
|
||||
public:
|
||||
FunctionCompiler(ModuleGeneratorThreadView& mg, const FuncBytecode& func, MIRGenerator& mirGen,
|
||||
FunctionCompiler(ModuleGeneratorThreadView& mg,
|
||||
Decoder& decoder,
|
||||
const FuncBytecode& func,
|
||||
const ValTypeVector& locals,
|
||||
MIRGenerator& mirGen,
|
||||
FuncCompileResults& compileResults)
|
||||
: mg_(mg),
|
||||
decoder_(decoder),
|
||||
func_(func),
|
||||
decoder_(func.bytecode()),
|
||||
locals_(locals),
|
||||
lastReadCallSite_(0),
|
||||
alloc_(mirGen.alloc()),
|
||||
graph_(mirGen.graph()),
|
||||
@ -97,9 +103,9 @@ class FunctionCompiler
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = args.length(); i < func_.numLocals(); i++) {
|
||||
for (size_t i = args.length(); i < locals_.length(); i++) {
|
||||
MInstruction* ins = nullptr;
|
||||
switch (func_.localType(i)) {
|
||||
switch (locals_[i]) {
|
||||
case ValType::I32:
|
||||
ins = MConstant::NewAsmJS(alloc(), Int32Value(0), MIRType_Int32);
|
||||
break;
|
||||
@ -164,7 +170,7 @@ class FunctionCompiler
|
||||
return curBlock_->getSlot(info().localSlot(slot));
|
||||
}
|
||||
|
||||
ValType localType(unsigned slot) const { return func_.localType(slot); }
|
||||
ValType localType(unsigned slot) const { return locals_[slot]; }
|
||||
|
||||
/***************************** Code generation (after local scope setup) */
|
||||
|
||||
@ -1256,12 +1262,12 @@ class FunctionCompiler
|
||||
Expr peakExpr() { return decoder_.uncheckedPeekExpr(); }
|
||||
|
||||
SimdConstant readI32X4() {
|
||||
Val::I32x4 i32x4;
|
||||
I32x4 i32x4;
|
||||
JS_ALWAYS_TRUE(decoder_.readFixedI32x4(&i32x4));
|
||||
return SimdConstant::CreateX4(i32x4);
|
||||
}
|
||||
SimdConstant readF32X4() {
|
||||
Val::F32x4 f32x4;
|
||||
F32x4 f32x4;
|
||||
JS_ALWAYS_TRUE(decoder_.readFixedF32x4(&f32x4));
|
||||
return SimdConstant::CreateX4(f32x4);
|
||||
}
|
||||
@ -2763,21 +2769,21 @@ EmitExpr(FunctionCompiler& f, MDefinition** def)
|
||||
return EmitBitwise<MUrsh>(f, ValType::I32, def);
|
||||
case Expr::I32BitNot:
|
||||
return EmitBitwiseNot(f, def);
|
||||
case Expr::I32LoadMem8S:
|
||||
case Expr::I32Load8S:
|
||||
return EmitLoad(f, Scalar::Int8, def);
|
||||
case Expr::I32LoadMem8U:
|
||||
case Expr::I32Load8U:
|
||||
return EmitLoad(f, Scalar::Uint8, def);
|
||||
case Expr::I32LoadMem16S:
|
||||
case Expr::I32Load16S:
|
||||
return EmitLoad(f, Scalar::Int16, def);
|
||||
case Expr::I32LoadMem16U:
|
||||
case Expr::I32Load16U:
|
||||
return EmitLoad(f, Scalar::Uint16, def);
|
||||
case Expr::I32LoadMem:
|
||||
case Expr::I32Load:
|
||||
return EmitLoad(f, Scalar::Int32, def);
|
||||
case Expr::I32StoreMem8:
|
||||
case Expr::I32Store8:
|
||||
return EmitStore(f, Scalar::Int8, def);
|
||||
case Expr::I32StoreMem16:
|
||||
case Expr::I32Store16:
|
||||
return EmitStore(f, Scalar::Int16, def);
|
||||
case Expr::I32StoreMem:
|
||||
case Expr::I32Store:
|
||||
return EmitStore(f, Scalar::Int32, def);
|
||||
case Expr::I32Eq:
|
||||
case Expr::I32Ne:
|
||||
@ -2880,11 +2886,11 @@ EmitExpr(FunctionCompiler& f, MDefinition** def)
|
||||
return EmitUnary<MToFloat32>(f, def);
|
||||
case Expr::F32ConvertUI32:
|
||||
return EmitUnary<MAsmJSUnsignedToFloat32>(f, def);
|
||||
case Expr::F32LoadMem:
|
||||
case Expr::F32Load:
|
||||
return EmitLoad(f, Scalar::Float32, def);
|
||||
case Expr::F32StoreMem:
|
||||
case Expr::F32Store:
|
||||
return EmitStore(f, Scalar::Float32, def);
|
||||
case Expr::F32StoreMemF64:
|
||||
case Expr::F32StoreF64:
|
||||
return EmitStoreWithCoercion(f, Scalar::Float32, Scalar::Float64, def);
|
||||
|
||||
// F64
|
||||
@ -2929,11 +2935,11 @@ EmitExpr(FunctionCompiler& f, MDefinition** def)
|
||||
return EmitUnary<MToDouble>(f, def);
|
||||
case Expr::F64ConvertUI32:
|
||||
return EmitUnary<MAsmJSUnsignedToDouble>(f, def);
|
||||
case Expr::F64LoadMem:
|
||||
case Expr::F64Load:
|
||||
return EmitLoad(f, Scalar::Float64, def);
|
||||
case Expr::F64StoreMem:
|
||||
case Expr::F64Store:
|
||||
return EmitStore(f, Scalar::Float64, def);
|
||||
case Expr::F64StoreMemF32:
|
||||
case Expr::F64StoreF32:
|
||||
return EmitStoreWithCoercion(f, Scalar::Float64, Scalar::Float32, def);
|
||||
|
||||
// SIMD
|
||||
@ -3012,17 +3018,17 @@ EmitExpr(FunctionCompiler& f, MDefinition** def)
|
||||
case Expr::F64ReinterpretI64:
|
||||
case Expr::I32ReinterpretF32:
|
||||
case Expr::F32ReinterpretI32:
|
||||
case Expr::I64LoadMem8S:
|
||||
case Expr::I64LoadMem16S:
|
||||
case Expr::I64LoadMem32S:
|
||||
case Expr::I64LoadMem8U:
|
||||
case Expr::I64LoadMem16U:
|
||||
case Expr::I64LoadMem32U:
|
||||
case Expr::I64LoadMem:
|
||||
case Expr::I64StoreMem8:
|
||||
case Expr::I64StoreMem16:
|
||||
case Expr::I64StoreMem32:
|
||||
case Expr::I64StoreMem:
|
||||
case Expr::I64Load8S:
|
||||
case Expr::I64Load16S:
|
||||
case Expr::I64Load32S:
|
||||
case Expr::I64Load8U:
|
||||
case Expr::I64Load16U:
|
||||
case Expr::I64Load32U:
|
||||
case Expr::I64Load:
|
||||
case Expr::I64Store8:
|
||||
case Expr::I64Store16:
|
||||
case Expr::I64Store32:
|
||||
case Expr::I64Store:
|
||||
case Expr::I64Clz:
|
||||
case Expr::I64Ctz:
|
||||
case Expr::I64Popcnt:
|
||||
@ -3045,11 +3051,26 @@ wasm::IonCompileFunction(IonCompileTask* task)
|
||||
const FuncBytecode& func = task->func();
|
||||
FuncCompileResults& results = task->results();
|
||||
|
||||
JitContext jitContext(CompileRuntime::get(task->runtime()), &results.alloc());
|
||||
// Read in the variable types to build the local types vector.
|
||||
|
||||
Decoder d(func.bytecode());
|
||||
|
||||
ValTypeVector locals;
|
||||
if (!locals.appendAll(func.sig().args()))
|
||||
return false;
|
||||
|
||||
uint32_t numVars = d.uncheckedReadVarU32();
|
||||
for (uint32_t i = 0; i < numVars; i++) {
|
||||
if (!locals.append(d.uncheckedReadValType()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up for Ion compilation.
|
||||
|
||||
JitContext jitContext(CompileRuntime::get(task->runtime()), &results.alloc());
|
||||
const JitCompileOptions options;
|
||||
MIRGraph graph(&results.alloc());
|
||||
CompileInfo compileInfo(func.numLocals());
|
||||
CompileInfo compileInfo(locals.length());
|
||||
MIRGenerator mir(nullptr, options, &results.alloc(), &graph, &compileInfo,
|
||||
IonOptimizations.get(OptimizationLevel::AsmJS));
|
||||
mir.initUsesSignalHandlersForAsmJSOOB(task->mg().args().useSignalHandlersForOOB);
|
||||
@ -3057,7 +3078,7 @@ wasm::IonCompileFunction(IonCompileTask* task)
|
||||
|
||||
// Build MIR graph
|
||||
{
|
||||
FunctionCompiler f(task->mg(), func, mir, results);
|
||||
FunctionCompiler f(task->mg(), d, func, locals, mir, results);
|
||||
if (!f.init())
|
||||
return false;
|
||||
|
||||
|
@ -31,6 +31,50 @@ typedef Vector<jit::MIRType, 8, SystemAllocPolicy> MIRTypeVector;
|
||||
typedef jit::ABIArgIter<MIRTypeVector> ABIArgMIRTypeIter;
|
||||
typedef jit::ABIArgIter<ValTypeVector> ABIArgValTypeIter;
|
||||
|
||||
// The FuncBytecode class contains the intermediate representation of a
|
||||
// parsed/decoded and validated asm.js/WebAssembly function. The FuncBytecode
|
||||
// lives only until it is fully compiled.
|
||||
|
||||
class FuncBytecode
|
||||
{
|
||||
// Function metadata
|
||||
const DeclaredSig& sig_;
|
||||
uint32_t lineOrBytecode_;
|
||||
Uint32Vector callSiteLineNums_;
|
||||
|
||||
// Compilation bookkeeping
|
||||
uint32_t index_;
|
||||
unsigned generateTime_;
|
||||
|
||||
UniqueBytecode bytecode_;
|
||||
|
||||
public:
|
||||
FuncBytecode(uint32_t index,
|
||||
const DeclaredSig& sig,
|
||||
UniqueBytecode bytecode,
|
||||
uint32_t lineOrBytecode,
|
||||
Uint32Vector&& callSiteLineNums,
|
||||
unsigned generateTime)
|
||||
: sig_(sig),
|
||||
lineOrBytecode_(lineOrBytecode),
|
||||
callSiteLineNums_(Move(callSiteLineNums)),
|
||||
index_(index),
|
||||
generateTime_(generateTime),
|
||||
bytecode_(Move(bytecode))
|
||||
{}
|
||||
|
||||
UniqueBytecode recycleBytecode() { return Move(bytecode_); }
|
||||
|
||||
uint32_t lineOrBytecode() const { return lineOrBytecode_; }
|
||||
const Uint32Vector& callSiteLineNums() const { return callSiteLineNums_; }
|
||||
uint32_t index() const { return index_; }
|
||||
const DeclaredSig& sig() const { return sig_; }
|
||||
const Bytecode& bytecode() const { return *bytecode_; }
|
||||
unsigned generateTime() const { return generateTime_; }
|
||||
};
|
||||
|
||||
typedef UniquePtr<FuncBytecode> UniqueFuncBytecode;
|
||||
|
||||
// The FuncCompileResults contains the results of compiling a single function
|
||||
// body, ready to be merged into the whole-module MacroAssembler.
|
||||
class FuncCompileResults
|
||||
|
@ -1457,7 +1457,7 @@ WasmTokenStream::next()
|
||||
if (consume(MOZ_UTF16("lt")))
|
||||
return WasmToken(WasmToken::ComparisonOpcode, Expr::F32Lt, begin, cur_);
|
||||
if (consume(MOZ_UTF16("load")))
|
||||
return WasmToken(WasmToken::Load, Expr::F32LoadMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::F32Load, begin, cur_);
|
||||
break;
|
||||
case 'm':
|
||||
if (consume(MOZ_UTF16("max")))
|
||||
@ -1486,7 +1486,7 @@ WasmTokenStream::next()
|
||||
if (consume(MOZ_UTF16("sub")))
|
||||
return WasmToken(WasmToken::BinaryOpcode, Expr::F32Sub, begin, cur_);
|
||||
if (consume(MOZ_UTF16("store")))
|
||||
return WasmToken(WasmToken::Store, Expr::F32StoreMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::F32Store, begin, cur_);
|
||||
break;
|
||||
case 't':
|
||||
if (consume(MOZ_UTF16("trunc")))
|
||||
@ -1544,7 +1544,7 @@ WasmTokenStream::next()
|
||||
if (consume(MOZ_UTF16("lt")))
|
||||
return WasmToken(WasmToken::ComparisonOpcode, Expr::F64Lt, begin, cur_);
|
||||
if (consume(MOZ_UTF16("load")))
|
||||
return WasmToken(WasmToken::Load, Expr::F64LoadMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::F64Load, begin, cur_);
|
||||
break;
|
||||
case 'm':
|
||||
if (consume(MOZ_UTF16("max")))
|
||||
@ -1573,7 +1573,7 @@ WasmTokenStream::next()
|
||||
if (consume(MOZ_UTF16("sub")))
|
||||
return WasmToken(WasmToken::BinaryOpcode, Expr::F64Sub, begin, cur_);
|
||||
if (consume(MOZ_UTF16("store")))
|
||||
return WasmToken(WasmToken::Store, Expr::F64StoreMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::F64Store, begin, cur_);
|
||||
break;
|
||||
case 't':
|
||||
if (consume(MOZ_UTF16("trunc")))
|
||||
@ -1640,15 +1640,15 @@ WasmTokenStream::next()
|
||||
return WasmToken(WasmToken::ComparisonOpcode, Expr::I32LtU, begin, cur_);
|
||||
if (consume(MOZ_UTF16("load"))) {
|
||||
if (IsWasmSpace(*cur_))
|
||||
return WasmToken(WasmToken::Load, Expr::I32LoadMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I32Load, begin, cur_);
|
||||
if (consume(MOZ_UTF16("8_s")))
|
||||
return WasmToken(WasmToken::Load, Expr::I32LoadMem8S, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I32Load8S, begin, cur_);
|
||||
if (consume(MOZ_UTF16("8_u")))
|
||||
return WasmToken(WasmToken::Load, Expr::I32LoadMem8U, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I32Load8U, begin, cur_);
|
||||
if (consume(MOZ_UTF16("16_s")))
|
||||
return WasmToken(WasmToken::Load, Expr::I32LoadMem16S, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I32Load16S, begin, cur_);
|
||||
if (consume(MOZ_UTF16("16_u")))
|
||||
return WasmToken(WasmToken::Load, Expr::I32LoadMem16U, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I32Load16U, begin, cur_);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1688,11 +1688,11 @@ WasmTokenStream::next()
|
||||
return WasmToken(WasmToken::BinaryOpcode, Expr::I32ShrU, begin, cur_);
|
||||
if (consume(MOZ_UTF16("store"))) {
|
||||
if (IsWasmSpace(*cur_))
|
||||
return WasmToken(WasmToken::Store, Expr::I32StoreMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I32Store, begin, cur_);
|
||||
if (consume(MOZ_UTF16("8")))
|
||||
return WasmToken(WasmToken::Store, Expr::I32StoreMem8, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I32Store8, begin, cur_);
|
||||
if (consume(MOZ_UTF16("16")))
|
||||
return WasmToken(WasmToken::Store, Expr::I32StoreMem16, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I32Store16, begin, cur_);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1778,19 +1778,19 @@ WasmTokenStream::next()
|
||||
return WasmToken(WasmToken::ComparisonOpcode, Expr::I64LtU, begin, cur_);
|
||||
if (consume(MOZ_UTF16("load"))) {
|
||||
if (IsWasmSpace(*cur_))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load, begin, cur_);
|
||||
if (consume(MOZ_UTF16("8_s")))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem8S, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load8S, begin, cur_);
|
||||
if (consume(MOZ_UTF16("8_u")))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem8U, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load8U, begin, cur_);
|
||||
if (consume(MOZ_UTF16("16_s")))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem16S, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load16S, begin, cur_);
|
||||
if (consume(MOZ_UTF16("16_u")))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem16U, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load16U, begin, cur_);
|
||||
if (consume(MOZ_UTF16("32_s")))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem32S, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load32S, begin, cur_);
|
||||
if (consume(MOZ_UTF16("32_u")))
|
||||
return WasmToken(WasmToken::Load, Expr::I64LoadMem32U, begin, cur_);
|
||||
return WasmToken(WasmToken::Load, Expr::I64Load32U, begin, cur_);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1830,13 +1830,13 @@ WasmTokenStream::next()
|
||||
return WasmToken(WasmToken::BinaryOpcode, Expr::I64ShrU, begin, cur_);
|
||||
if (consume(MOZ_UTF16("store"))) {
|
||||
if (IsWasmSpace(*cur_))
|
||||
return WasmToken(WasmToken::Store, Expr::I64StoreMem, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I64Store, begin, cur_);
|
||||
if (consume(MOZ_UTF16("8")))
|
||||
return WasmToken(WasmToken::Store, Expr::I64StoreMem8, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I64Store8, begin, cur_);
|
||||
if (consume(MOZ_UTF16("16")))
|
||||
return WasmToken(WasmToken::Store, Expr::I64StoreMem16, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I64Store16, begin, cur_);
|
||||
if (consume(MOZ_UTF16("32")))
|
||||
return WasmToken(WasmToken::Store, Expr::I64StoreMem32, begin, cur_);
|
||||
return WasmToken(WasmToken::Store, Expr::I64Store32, begin, cur_);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -2540,26 +2540,26 @@ ParseLoad(WasmParseContext& c, Expr expr)
|
||||
|
||||
if (align == 0) {
|
||||
switch (expr) {
|
||||
case Expr::I32LoadMem8S:
|
||||
case Expr::I32LoadMem8U:
|
||||
case Expr::I64LoadMem8S:
|
||||
case Expr::I64LoadMem8U:
|
||||
case Expr::I32Load8S:
|
||||
case Expr::I32Load8U:
|
||||
case Expr::I64Load8S:
|
||||
case Expr::I64Load8U:
|
||||
align = 1;
|
||||
break;
|
||||
case Expr::I32LoadMem16S:
|
||||
case Expr::I32LoadMem16U:
|
||||
case Expr::I64LoadMem16S:
|
||||
case Expr::I64LoadMem16U:
|
||||
case Expr::I32Load16S:
|
||||
case Expr::I32Load16U:
|
||||
case Expr::I64Load16S:
|
||||
case Expr::I64Load16U:
|
||||
align = 2;
|
||||
break;
|
||||
case Expr::I32LoadMem:
|
||||
case Expr::F32LoadMem:
|
||||
case Expr::I64LoadMem32S:
|
||||
case Expr::I64LoadMem32U:
|
||||
case Expr::I32Load:
|
||||
case Expr::F32Load:
|
||||
case Expr::I64Load32S:
|
||||
case Expr::I64Load32U:
|
||||
align = 4;
|
||||
break;
|
||||
case Expr::I64LoadMem:
|
||||
case Expr::F64LoadMem:
|
||||
case Expr::I64Load:
|
||||
case Expr::F64Load:
|
||||
align = 8;
|
||||
break;
|
||||
default:
|
||||
@ -2581,21 +2581,21 @@ ParseStore(WasmParseContext& c, Expr expr)
|
||||
|
||||
if (align == 0) {
|
||||
switch (expr) {
|
||||
case Expr::I32StoreMem8:
|
||||
case Expr::I64StoreMem8:
|
||||
case Expr::I32Store8:
|
||||
case Expr::I64Store8:
|
||||
align = 1;
|
||||
break;
|
||||
case Expr::I32StoreMem16:
|
||||
case Expr::I64StoreMem16:
|
||||
case Expr::I32Store16:
|
||||
case Expr::I64Store16:
|
||||
align = 2;
|
||||
break;
|
||||
case Expr::I32StoreMem:
|
||||
case Expr::F32StoreMem:
|
||||
case Expr::I64StoreMem32:
|
||||
case Expr::I32Store:
|
||||
case Expr::F32Store:
|
||||
case Expr::I64Store32:
|
||||
align = 4;
|
||||
break;
|
||||
case Expr::I64StoreMem:
|
||||
case Expr::F64StoreMem:
|
||||
case Expr::I64Store:
|
||||
case Expr::F64Store:
|
||||
align = 8;
|
||||
break;
|
||||
default:
|
||||
@ -3919,6 +3919,12 @@ EncodeFunctionTable(Encoder& e, WasmAstModule& module)
|
||||
static bool
|
||||
EncodeFunctionBody(Encoder& e, WasmAstFunc& func)
|
||||
{
|
||||
size_t bodySizeAt;
|
||||
if (!e.writePatchableVarU32(&bodySizeAt))
|
||||
return false;
|
||||
|
||||
size_t beforeBody = e.currentOffset();
|
||||
|
||||
if (!e.writeVarU32(func.vars().length()))
|
||||
return false;
|
||||
|
||||
@ -3927,12 +3933,6 @@ EncodeFunctionBody(Encoder& e, WasmAstFunc& func)
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t bodySizeAt;
|
||||
if (!e.writePatchableVarU32(&bodySizeAt))
|
||||
return false;
|
||||
|
||||
size_t beforeBody = e.currentOffset();
|
||||
|
||||
for (WasmAstExpr* expr : func.body()) {
|
||||
if (!EncodeExpr(e, *expr))
|
||||
return false;
|
||||
|
@ -19,13 +19,13 @@
|
||||
#ifndef wasm_types_h
|
||||
#define wasm_types_h
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "NamespaceImports.h"
|
||||
|
||||
#include "asmjs/WasmBinary.h"
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "jit/IonTypes.h"
|
||||
#include "js/UniquePtr.h"
|
||||
@ -40,37 +40,50 @@ namespace wasm {
|
||||
|
||||
using mozilla::EnumeratedArray;
|
||||
using mozilla::Move;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::MallocSizeOf;
|
||||
|
||||
typedef Vector<uint32_t, 0, SystemAllocPolicy> Uint32Vector;
|
||||
|
||||
// The ValType enum represents the WebAssembly "value type", which are used to
|
||||
// specify the type of locals and parameters.
|
||||
|
||||
// FIXME: uint16_t would make more sense for the underlying storage class, but
|
||||
// causes miscompilations in GCC (fixed in 4.8.5 and 4.9.3).
|
||||
enum class ValType
|
||||
{
|
||||
I32,
|
||||
I64,
|
||||
F32,
|
||||
F64,
|
||||
I32x4,
|
||||
F32x4,
|
||||
B32x4,
|
||||
|
||||
Limit
|
||||
};
|
||||
|
||||
typedef Vector<ValType, 8, SystemAllocPolicy> ValTypeVector;
|
||||
|
||||
// ValType/ExprType utilities
|
||||
|
||||
static inline bool
|
||||
IsVoid(ExprType et)
|
||||
{
|
||||
return et == ExprType::Void;
|
||||
}
|
||||
|
||||
static inline ValType
|
||||
NonVoidToValType(ExprType et)
|
||||
{
|
||||
MOZ_ASSERT(!IsVoid(et));
|
||||
return ValType(et);
|
||||
}
|
||||
|
||||
static inline ExprType
|
||||
ToExprType(ValType vt)
|
||||
{
|
||||
return ExprType(vt);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsSimdType(ValType vt)
|
||||
{
|
||||
return vt == ValType::I32x4 || vt == ValType::F32x4 || vt == ValType::B32x4;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsSimdType(ExprType et)
|
||||
{
|
||||
return IsVoid(et) ? false : IsSimdType(ValType(et));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsSimdBoolType(ValType vt)
|
||||
{
|
||||
return vt == ValType::B32x4;
|
||||
}
|
||||
|
||||
static inline jit::MIRType
|
||||
ToMIRType(ValType vt)
|
||||
{
|
||||
@ -87,6 +100,35 @@ ToMIRType(ValType vt)
|
||||
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("bad type");
|
||||
}
|
||||
|
||||
static inline jit::MIRType
|
||||
ToMIRType(ExprType et)
|
||||
{
|
||||
return IsVoid(et) ? jit::MIRType_None : ToMIRType(ValType(et));
|
||||
}
|
||||
|
||||
static inline const char*
|
||||
ToCString(ExprType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ExprType::Void: return "void";
|
||||
case ExprType::I32: return "i32";
|
||||
case ExprType::I64: return "i64";
|
||||
case ExprType::F32: return "f32";
|
||||
case ExprType::F64: return "f64";
|
||||
case ExprType::I32x4: return "i32x4";
|
||||
case ExprType::F32x4: return "f32x4";
|
||||
case ExprType::B32x4: return "b32x4";
|
||||
case ExprType::Limit:;
|
||||
}
|
||||
MOZ_CRASH("bad expression type");
|
||||
}
|
||||
|
||||
static inline const char*
|
||||
ToCString(ValType type)
|
||||
{
|
||||
return ToCString(ToExprType(type));
|
||||
}
|
||||
|
||||
// The Val class represents a single WebAssembly value of a given value type,
|
||||
// mostly for the purpose of numeric literals and initializers. A Val does not
|
||||
// directly map to a JS value since there is not (currently) a precise
|
||||
@ -96,11 +138,6 @@ ToMIRType(ValType vt)
|
||||
|
||||
class Val
|
||||
{
|
||||
public:
|
||||
typedef int32_t I32x4[4];
|
||||
typedef float F32x4[4];
|
||||
|
||||
private:
|
||||
ValType type_;
|
||||
union {
|
||||
uint32_t i32_;
|
||||
@ -139,86 +176,6 @@ class Val
|
||||
const F32x4& f32x4() const { MOZ_ASSERT(type_ == ValType::F32x4); return u.f32x4_; }
|
||||
};
|
||||
|
||||
// The ExprType enum represents the type of a WebAssembly expression or return
|
||||
// value and may either be a value type or void. A future WebAssembly extension
|
||||
// may generalize expression types to instead be a list of value types (with
|
||||
// void represented by the empty list). For now it's easier to have a flat enum
|
||||
// and be explicit about conversions to/from value types.
|
||||
|
||||
enum class ExprType : uint16_t
|
||||
{
|
||||
I32 = uint8_t(ValType::I32),
|
||||
I64 = uint8_t(ValType::I64),
|
||||
F32 = uint8_t(ValType::F32),
|
||||
F64 = uint8_t(ValType::F64),
|
||||
I32x4 = uint8_t(ValType::I32x4),
|
||||
F32x4 = uint8_t(ValType::F32x4),
|
||||
B32x4 = uint8_t(ValType::B32x4),
|
||||
Void,
|
||||
|
||||
Limit
|
||||
};
|
||||
|
||||
static inline bool
|
||||
IsVoid(ExprType et)
|
||||
{
|
||||
return et == ExprType::Void;
|
||||
}
|
||||
|
||||
static inline ValType
|
||||
NonVoidToValType(ExprType et)
|
||||
{
|
||||
MOZ_ASSERT(!IsVoid(et));
|
||||
return ValType(et);
|
||||
}
|
||||
|
||||
static inline ExprType
|
||||
ToExprType(ValType vt)
|
||||
{
|
||||
return ExprType(vt);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsSimdType(ExprType et)
|
||||
{
|
||||
return IsVoid(et) ? false : IsSimdType(ValType(et));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsSimdBoolType(ValType vt)
|
||||
{
|
||||
return vt == ValType::B32x4;
|
||||
}
|
||||
|
||||
static inline jit::MIRType
|
||||
ToMIRType(ExprType et)
|
||||
{
|
||||
return IsVoid(et) ? jit::MIRType_None : ToMIRType(ValType(et));
|
||||
}
|
||||
|
||||
static inline const char*
|
||||
ToCString(ExprType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ExprType::Void: return "void";
|
||||
case ExprType::I32: return "i32";
|
||||
case ExprType::I64: return "i64";
|
||||
case ExprType::F32: return "f32";
|
||||
case ExprType::F64: return "f64";
|
||||
case ExprType::I32x4: return "i32x4";
|
||||
case ExprType::F32x4: return "f32x4";
|
||||
case ExprType::B32x4: return "b32x4";
|
||||
case ExprType::Limit:;
|
||||
}
|
||||
MOZ_CRASH("bad expression type");
|
||||
}
|
||||
|
||||
static inline const char*
|
||||
ToCString(ValType type)
|
||||
{
|
||||
return ToCString(ToExprType(type));
|
||||
}
|
||||
|
||||
// The Sig class represents a WebAssembly function signature which takes a list
|
||||
// of value types and returns an expression type. The engine uses two in-memory
|
||||
// representations of the argument Vector's memory (when elements do not fit
|
||||
@ -632,10 +589,18 @@ enum ModuleKind
|
||||
// Constants:
|
||||
|
||||
static const unsigned ActivationGlobalDataOffset = 0;
|
||||
static const unsigned HeapGlobalDataOffset = ActivationGlobalDataOffset + sizeof(void*);
|
||||
static const unsigned NaN64GlobalDataOffset = HeapGlobalDataOffset + sizeof(void*);
|
||||
static const unsigned NaN32GlobalDataOffset = NaN64GlobalDataOffset + sizeof(double);
|
||||
static const unsigned InitialGlobalDataBytes = NaN32GlobalDataOffset + sizeof(float);
|
||||
static const unsigned HeapGlobalDataOffset = ActivationGlobalDataOffset + sizeof(void*);
|
||||
static const unsigned NaN64GlobalDataOffset = HeapGlobalDataOffset + sizeof(void*);
|
||||
static const unsigned NaN32GlobalDataOffset = NaN64GlobalDataOffset + sizeof(double);
|
||||
static const unsigned InitialGlobalDataBytes = NaN32GlobalDataOffset + sizeof(float);
|
||||
|
||||
static const unsigned MaxSigs = 4 * 1024;
|
||||
static const unsigned MaxFuncs = 512 * 1024;
|
||||
static const unsigned MaxImports = 4 * 1024;
|
||||
static const unsigned MaxExports = 4 * 1024;
|
||||
static const unsigned MaxTableElems = 128 * 1024;
|
||||
static const unsigned MaxArgsPerFunc = 4 * 1024;
|
||||
static const unsigned MaxBrTableElems = 4 * 1024;
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace js
|
||||
|
@ -533,13 +533,13 @@ WasmTextToBinary(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<ArrayBufferObject*> buffer(cx, ArrayBufferObject::create(cx, bytes->length()));
|
||||
if (!buffer)
|
||||
RootedObject obj(cx, JS_NewUint8Array(cx, bytes->length()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
memcpy(buffer->dataPointer(), bytes->begin(), bytes->length());
|
||||
memcpy(obj->as<TypedArrayObject>().viewDataUnshared(), bytes->begin(), bytes->length());
|
||||
|
||||
args.rval().setObject(*buffer);
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -726,7 +726,6 @@ template <typename ParseHandler>
|
||||
Parser<ParseHandler>::~Parser()
|
||||
{
|
||||
MOZ_ASSERT(checkOptionsCalled);
|
||||
|
||||
alloc.release(tempPoolMark);
|
||||
|
||||
/*
|
||||
@ -3938,6 +3937,70 @@ Parser<ParseHandler>::AutoPushStmtInfoPC::makeInnermostLexicalScope(StaticBlockS
|
||||
return generateBlockId();
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
Parser<ParseHandler>::PossibleError::PossibleError(Parser<ParseHandler>& parser)
|
||||
: parser_(parser)
|
||||
{
|
||||
state_ = ErrorState::None;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::PossibleError::setPending(ParseReportKind kind, unsigned errorNumber,
|
||||
bool strict)
|
||||
{
|
||||
// If we report an error later, we'll do it from the position where we set
|
||||
// the state to pending.
|
||||
offset_ = parser_.pos().begin;
|
||||
reportKind_ = kind;
|
||||
strict_ = strict;
|
||||
errorNumber_ = errorNumber;
|
||||
state_ = ErrorState::Pending;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::PossibleError::setResolved()
|
||||
{
|
||||
state_ = ErrorState::None;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::PossibleError::hasError()
|
||||
{
|
||||
return state_ == ErrorState::Pending;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::PossibleError::checkForExprErrors()
|
||||
{
|
||||
bool err = hasError();
|
||||
if (err) {
|
||||
parser_.reportWithOffset(reportKind_, strict_, offset_, errorNumber_);
|
||||
}
|
||||
return !err;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::PossibleError::transferErrorTo(PossibleError* other)
|
||||
{
|
||||
if (other) {
|
||||
MOZ_ASSERT(this != other);
|
||||
MOZ_ASSERT(!other->hasError());
|
||||
// We should never allow fields to be copied between instances
|
||||
// that point to different underlying parsers.
|
||||
MOZ_ASSERT(&parser_ == &other->parser_);
|
||||
other->offset_ = offset_;
|
||||
other->reportKind_ = reportKind_;
|
||||
other->errorNumber_ = errorNumber_;
|
||||
other->strict_ = strict_;
|
||||
other->state_ = state_;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
static inline bool
|
||||
HasOuterLexicalBinding(ParseContext<ParseHandler>* pc, StmtInfoPC* stmt, HandleAtom atom)
|
||||
@ -4429,7 +4492,8 @@ Parser<ParseHandler>::destructuringExpr(YieldHandling yieldHandling, BindData<Pa
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
|
||||
pc->inDeclDestructuring = true;
|
||||
Node pn = primaryExpr(yieldHandling, TripledotProhibited, tt);
|
||||
Node pn = primaryExpr(yieldHandling, TripledotProhibited,
|
||||
nullptr /* possibleError */, tt);
|
||||
pc->inDeclDestructuring = false;
|
||||
if (!pn)
|
||||
return null();
|
||||
@ -4582,10 +4646,10 @@ Parser<ParseHandler>::expressionAfterForInOrOf(ParseNodeKind forHeadKind,
|
||||
YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(forHeadKind == PNK_FORIN || forHeadKind == PNK_FOROF);
|
||||
|
||||
return forHeadKind == PNK_FOROF
|
||||
Node pn = forHeadKind == PNK_FOROF
|
||||
? assignExpr(InAllowed, yieldHandling, TripledotProhibited)
|
||||
: expr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
return pn;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
@ -4601,7 +4665,11 @@ Parser<ParseHandler>::declarationPattern(Node decl, TokenKind tt, BindData<Parse
|
||||
Node pattern;
|
||||
{
|
||||
pc->inDeclDestructuring = true;
|
||||
pattern = primaryExpr(yieldHandling, TripledotProhibited, tt);
|
||||
|
||||
// No possible error is required because we already know we're
|
||||
// destructuring.
|
||||
pattern = primaryExpr(yieldHandling, TripledotProhibited,
|
||||
nullptr /* possibleError */ , tt);
|
||||
pc->inDeclDestructuring = false;
|
||||
}
|
||||
if (!pattern)
|
||||
@ -4648,7 +4716,14 @@ Parser<ParseHandler>::declarationPattern(Node decl, TokenKind tt, BindData<Parse
|
||||
return null();
|
||||
}
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL);
|
||||
TokenKind token;
|
||||
if (!tokenStream.getToken(&token, TokenStream::None))
|
||||
return null();
|
||||
|
||||
if (token != TOK_ASSIGN) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_DESTRUCT_DECL);
|
||||
return null();
|
||||
}
|
||||
|
||||
Node init = assignExpr(forHeadKind ? InProhibited : InAllowed,
|
||||
yieldHandling, TripledotProhibited);
|
||||
@ -6824,7 +6899,6 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
|
||||
if (!catchName)
|
||||
return null();
|
||||
break;
|
||||
|
||||
case TOK_YIELD:
|
||||
if (yieldHandling == YieldIsKeyword) {
|
||||
report(ParseError, false, null(), JSMSG_RESERVED_ID, "yield");
|
||||
@ -7459,9 +7533,12 @@ Parser<ParseHandler>::statement(YieldHandling yieldHandling, bool canHaveDirecti
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
Node pn = assignExpr(inHandling, yieldHandling, tripledotHandling, invoked);
|
||||
Node pn = assignExpr(inHandling, yieldHandling, tripledotHandling,
|
||||
possibleError, invoked);
|
||||
if (!pn)
|
||||
return null();
|
||||
|
||||
@ -7476,9 +7553,26 @@ Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
return null();
|
||||
while (true) {
|
||||
|
||||
pn = assignExpr(inHandling, yieldHandling, tripledotHandling);
|
||||
// Additional calls to assignExpr should not reuse the possibleError
|
||||
// which had been passed into the function. Otherwise we would lose
|
||||
// information needed to determine whether or not we're dealing with
|
||||
// a non-recoverable situation.
|
||||
PossibleError possibleErrorInner(*this);
|
||||
pn = assignExpr(inHandling, yieldHandling, tripledotHandling,
|
||||
&possibleErrorInner);
|
||||
if (!pn)
|
||||
return null();
|
||||
|
||||
// If we find an error here we should report it immedately instead of
|
||||
// passing it back out of the function.
|
||||
if (possibleErrorInner.hasError()) {
|
||||
|
||||
// We begin by checking for an outer pending error since it would
|
||||
// have occurred first.
|
||||
if (possibleError->checkForExprErrors())
|
||||
possibleErrorInner.checkForExprErrors();
|
||||
return null();
|
||||
}
|
||||
handler.addList(seq, pn);
|
||||
|
||||
if (!tokenStream.matchToken(&matched, TOK_COMMA))
|
||||
@ -7489,6 +7583,19 @@ Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
return seq;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
PossibleError possibleError(*this);
|
||||
Node pn = expr(inHandling, yieldHandling, tripledotHandling, &possibleError, invoked);
|
||||
if (!pn || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
return pn;
|
||||
}
|
||||
|
||||
static const JSOp ParseNodeKindToJSOp[] = {
|
||||
JSOP_OR,
|
||||
JSOP_AND,
|
||||
@ -7576,7 +7683,9 @@ Precedence(ParseNodeKind pnk) {
|
||||
template <typename ParseHandler>
|
||||
MOZ_ALWAYS_INLINE typename ParseHandler::Node
|
||||
Parser<ParseHandler>::orExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
// Shift-reduce parser for the binary operator part of the JS expression
|
||||
// syntax.
|
||||
@ -7589,7 +7698,7 @@ Parser<ParseHandler>::orExpr1(InHandling inHandling, YieldHandling yieldHandling
|
||||
|
||||
Node pn;
|
||||
for (;;) {
|
||||
pn = unaryExpr(yieldHandling, tripledotHandling, invoked);
|
||||
pn = unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked);
|
||||
if (!pn)
|
||||
return pn;
|
||||
|
||||
@ -7639,19 +7748,22 @@ Parser<ParseHandler>::orExpr1(InHandling inHandling, YieldHandling yieldHandling
|
||||
template <typename ParseHandler>
|
||||
MOZ_ALWAYS_INLINE typename ParseHandler::Node
|
||||
Parser<ParseHandler>::condExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
Node condition = orExpr1(inHandling, yieldHandling, tripledotHandling, invoked);
|
||||
Node condition = orExpr1(inHandling, yieldHandling, tripledotHandling, possibleError, invoked);
|
||||
if (!condition || !tokenStream.isCurrentTokenType(TOK_HOOK))
|
||||
return condition;
|
||||
|
||||
Node thenExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
Node thenExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
|
||||
possibleError);
|
||||
if (!thenExpr)
|
||||
return null();
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
|
||||
|
||||
Node elseExpr = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||
Node elseExpr = assignExpr(inHandling, yieldHandling, TripledotProhibited,
|
||||
possibleError);
|
||||
if (!elseExpr)
|
||||
return null();
|
||||
|
||||
@ -7664,7 +7776,8 @@ Parser<ParseHandler>::condExpr1(InHandling inHandling, YieldHandling yieldHandli
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor flavor)
|
||||
Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor flavor,
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(flavor != KeyedDestructuringAssignment,
|
||||
"destructuring must use special checking/marking code, not "
|
||||
@ -7676,7 +7789,13 @@ Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkDestructuringPattern(nullptr, target);
|
||||
bool isDestructuring = checkDestructuringPattern(nullptr, target);
|
||||
// Here we've successfully distinguished between destructuring and
|
||||
// an object literal. In the case where "CoverInitializedName"
|
||||
// syntax was used there will be a pending error that needs clearing.
|
||||
if (possibleError && isDestructuring)
|
||||
possibleError->setResolved();
|
||||
return isDestructuring;
|
||||
}
|
||||
|
||||
// All other permitted targets are simple.
|
||||
@ -7704,9 +7823,12 @@ Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling, InvokedPrediction invoked)
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
JS_CHECK_RECURSION(context, return null());
|
||||
MOZ_ASSERT(!possibleError->hasError());
|
||||
|
||||
// It's very common at this point to have a "detectably simple" expression,
|
||||
// i.e. a name/number/string token followed by one of the following tokens
|
||||
@ -7756,9 +7878,11 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
TokenStream::Position start(keepAtoms);
|
||||
tokenStream.tell(&start);
|
||||
|
||||
Node lhs = condExpr1(inHandling, yieldHandling, tripledotHandling, invoked);
|
||||
if (!lhs)
|
||||
PossibleError possibleErrorInner(*this);
|
||||
Node lhs = condExpr1(inHandling, yieldHandling, tripledotHandling, &possibleErrorInner, invoked);
|
||||
if (!lhs) {
|
||||
return null();
|
||||
}
|
||||
|
||||
ParseNodeKind kind;
|
||||
JSOp op;
|
||||
@ -7778,6 +7902,7 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
case TOK_POWASSIGN: kind = PNK_POWASSIGN; op = JSOP_POW; break;
|
||||
|
||||
case TOK_ARROW: {
|
||||
|
||||
// A line terminator between ArrowParameters and the => should trigger a SyntaxError.
|
||||
tokenStream.ungetToken();
|
||||
TokenKind next = TOK_EOF;
|
||||
@ -7840,24 +7965,42 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(!tokenStream.isCurrentTokenAssignment());
|
||||
possibleErrorInner.transferErrorTo(possibleError);
|
||||
tokenStream.ungetToken();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
AssignmentFlavor flavor = kind == PNK_ASSIGN ? PlainAssignment : CompoundAssignment;
|
||||
if (!checkAndMarkAsAssignmentLhs(lhs, flavor))
|
||||
if (!checkAndMarkAsAssignmentLhs(lhs, flavor, &possibleErrorInner))
|
||||
return null();
|
||||
if (!possibleErrorInner.checkForExprErrors())
|
||||
return null();
|
||||
|
||||
bool saved = pc->inDeclDestructuring;
|
||||
pc->inDeclDestructuring = false;
|
||||
Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||
Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited,
|
||||
possibleError);
|
||||
pc->inDeclDestructuring = saved;
|
||||
if (!rhs)
|
||||
return null();
|
||||
|
||||
return handler.newAssignment(kind, lhs, rhs, pc, op);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
PossibleError possibleError(*this);
|
||||
Node expr = assignExpr(inHandling, yieldHandling, tripledotHandling, &possibleError, invoked);
|
||||
if (!expr || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::isValidSimpleAssignmentTarget(Node node,
|
||||
@ -7982,8 +8125,9 @@ typename ParseHandler::Node
|
||||
Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op,
|
||||
uint32_t begin)
|
||||
{
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited);
|
||||
if (!kid)
|
||||
PossibleError possibleError(*this);
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited, &possibleError);
|
||||
if (!kid || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
return handler.newUnary(kind, op, begin, kid);
|
||||
}
|
||||
@ -7991,7 +8135,7 @@ Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kin
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked)
|
||||
PossibleError* possibleError, InvokedPrediction invoked)
|
||||
{
|
||||
JS_CHECK_RECURSION(context, return null());
|
||||
|
||||
@ -8023,7 +8167,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
// // Evaluates expression, triggering a runtime ReferenceError for
|
||||
// // the undefined name.
|
||||
// typeof (1, nonExistentName);
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited);
|
||||
Node kid = unaryExpr(yieldHandling, TripledotProhibited, possibleError);
|
||||
if (!kid)
|
||||
return null();
|
||||
|
||||
@ -8036,7 +8180,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
TokenKind tt2;
|
||||
if (!tokenStream.getToken(&tt2, TokenStream::Operand))
|
||||
return null();
|
||||
Node pn2 = memberExpr(yieldHandling, TripledotProhibited, tt2, true);
|
||||
Node pn2 = memberExpr(yieldHandling, TripledotProhibited, possibleError, tt2, true);
|
||||
if (!pn2)
|
||||
return null();
|
||||
AssignmentFlavor flavor = (tt == TOK_INC) ? IncrementAssignment : DecrementAssignment;
|
||||
@ -8049,7 +8193,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
}
|
||||
|
||||
case TOK_DELETE: {
|
||||
Node expr = unaryExpr(yieldHandling, TripledotProhibited);
|
||||
Node expr = unaryExpr(yieldHandling, TripledotProhibited, possibleError);
|
||||
if (!expr)
|
||||
return null();
|
||||
|
||||
@ -8065,7 +8209,7 @@ Parser<ParseHandler>::unaryExpr(YieldHandling yieldHandling, TripledotHandling t
|
||||
}
|
||||
|
||||
default: {
|
||||
Node pn = memberExpr(yieldHandling, tripledotHandling, tt, /* allowCallSyntax = */ true,
|
||||
Node pn = memberExpr(yieldHandling, tripledotHandling, possibleError, tt, /* allowCallSyntax = */ true,
|
||||
invoked);
|
||||
if (!pn)
|
||||
return null();
|
||||
@ -8486,7 +8630,8 @@ Parser<ParseHandler>::checkAndMarkSuperScope()
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
TokenKind tt, bool allowCallSyntax, InvokedPrediction invoked)
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
|
||||
@ -8510,7 +8655,8 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
|
||||
// Gotten by tryNewTarget
|
||||
tt = tokenStream.currentToken().type;
|
||||
Node ctorExpr = memberExpr(yieldHandling, TripledotProhibited, tt, false, PredictInvoked);
|
||||
Node ctorExpr = memberExpr(yieldHandling, TripledotProhibited,
|
||||
possibleError, tt, false, PredictInvoked);
|
||||
if (!ctorExpr)
|
||||
return null();
|
||||
|
||||
@ -8535,7 +8681,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
if (!lhs)
|
||||
return null();
|
||||
} else {
|
||||
lhs = primaryExpr(yieldHandling, tripledotHandling, tt, invoked);
|
||||
lhs = primaryExpr(yieldHandling, tripledotHandling, possibleError, tt, invoked);
|
||||
if (!lhs)
|
||||
return null();
|
||||
}
|
||||
@ -8566,7 +8712,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return null();
|
||||
}
|
||||
} else if (tt == TOK_LB) {
|
||||
Node propExpr = expr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
Node propExpr = expr(InAllowed, yieldHandling, TripledotProhibited, possibleError);
|
||||
if (!propExpr)
|
||||
return null();
|
||||
|
||||
@ -8689,6 +8835,19 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked)
|
||||
{
|
||||
PossibleError possibleError(*this);
|
||||
Node pn = memberExpr(yieldHandling, tripledotHandling, &possibleError, tt,
|
||||
allowCallSyntax, invoked);
|
||||
if (!pn || !possibleError.checkForExprErrors())
|
||||
return null();
|
||||
return pn;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::newName(PropertyName* name)
|
||||
@ -9001,13 +9160,15 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling, Node propList,
|
||||
return propName;
|
||||
}
|
||||
|
||||
if (ltok == TOK_NAME && (tt == TOK_COMMA || tt == TOK_RC)) {
|
||||
if (ltok == TOK_NAME && (tt == TOK_COMMA || tt == TOK_RC || tt == TOK_ASSIGN)) {
|
||||
if (isGenerator) {
|
||||
report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
|
||||
return null();
|
||||
}
|
||||
tokenStream.ungetToken();
|
||||
*propType = PropertyType::Shorthand;
|
||||
*propType = tt == TOK_ASSIGN ?
|
||||
PropertyType::CoverInitializedName :
|
||||
PropertyType::Shorthand;
|
||||
return propName;
|
||||
}
|
||||
|
||||
@ -9048,7 +9209,7 @@ Parser<ParseHandler>::computedPropertyName(YieldHandling yieldHandling, Node lit
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling)
|
||||
Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
|
||||
|
||||
@ -9057,6 +9218,7 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling)
|
||||
return null();
|
||||
|
||||
bool seenPrototypeMutation = false;
|
||||
bool seenCoverInitializedName = false;
|
||||
RootedAtom propAtom(context);
|
||||
for (;;) {
|
||||
TokenKind tt;
|
||||
@ -9115,6 +9277,43 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling)
|
||||
|
||||
if (!handler.addShorthand(literal, propName, nameExpr))
|
||||
return null();
|
||||
} else if (propType == PropertyType::CoverInitializedName) {
|
||||
/*
|
||||
* Support, e.g., |var {x=1, y=2} = o| as destructuring shorthand
|
||||
* with default values, as per ES6 12.14.5 (2016/2/4)
|
||||
*/
|
||||
if (!tokenStream.checkForKeyword(propAtom, nullptr))
|
||||
return null();
|
||||
|
||||
Node lhs = identifierName(yieldHandling);
|
||||
if (!lhs)
|
||||
return null();
|
||||
|
||||
tokenStream.consumeKnownToken(TOK_ASSIGN);
|
||||
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!rhs)
|
||||
return null();
|
||||
|
||||
Node propExpr = handler.newAssignment(PNK_ASSIGN, lhs, rhs, pc, JSOP_NOP);
|
||||
if (!propExpr)
|
||||
return null();
|
||||
|
||||
if (!handler.addPropertyDefinition(literal, propName, propExpr))
|
||||
return null();
|
||||
|
||||
if (!abortIfSyntaxParser())
|
||||
return null();
|
||||
|
||||
if (!seenCoverInitializedName) {
|
||||
seenCoverInitializedName = true;
|
||||
// "shorthand default" or "CoverInitializedName" syntax is only
|
||||
// valid in the case of destructuring. Here we set a pending error so
|
||||
// that later in the parse, once we've determined whether or not we're
|
||||
// destructuring, the error can be reported or ignored appropriately.
|
||||
if (possibleError)
|
||||
possibleError->setPending(ParseError, JSMSG_BAD_PROP_ID, false);
|
||||
}
|
||||
|
||||
} else {
|
||||
// FIXME: Implement ES6 function "name" property semantics
|
||||
// (bug 883377).
|
||||
@ -9214,7 +9413,8 @@ Parser<ParseHandler>::tryNewTarget(Node &newTarget)
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
TokenKind tt, InvokedPrediction invoked)
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
InvokedPrediction invoked)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
JS_CHECK_RECURSION(context, return null());
|
||||
@ -9230,7 +9430,7 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return arrayInitializer(yieldHandling);
|
||||
|
||||
case TOK_LC:
|
||||
return objectLiteral(yieldHandling);
|
||||
return objectLiteral(yieldHandling, possibleError);
|
||||
|
||||
case TOK_LP: {
|
||||
TokenKind next;
|
||||
@ -9262,7 +9462,7 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
return generatorComprehension(begin);
|
||||
}
|
||||
|
||||
Node expr = exprInParens(InAllowed, yieldHandling, TripledotAllowed);
|
||||
Node expr = exprInParens(InAllowed, yieldHandling, TripledotAllowed, possibleError);
|
||||
if (!expr)
|
||||
return null();
|
||||
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
|
||||
@ -9366,6 +9566,16 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LP));
|
||||
return expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
|
@ -374,6 +374,7 @@ enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
|
||||
enum class PropertyType {
|
||||
Normal,
|
||||
Shorthand,
|
||||
CoverInitializedName,
|
||||
Getter,
|
||||
GetterNoExpressionClosure,
|
||||
Setter,
|
||||
@ -415,6 +416,72 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
operator StmtInfoPC*() { return &stmt_; }
|
||||
};
|
||||
|
||||
/*
|
||||
* A class for temporarily stashing errors while parsing continues.
|
||||
*
|
||||
* The ability to stash an error is useful for handling situations where we
|
||||
* aren't able to verify that an error has occurred until later in the parse.
|
||||
* For instance | ({x=1}) | is always parsed as an object literal with
|
||||
* a SyntaxError, however, in the case where it is followed by '=>' we rewind
|
||||
* and reparse it as a valid arrow function. Here a PossibleError would be
|
||||
* set to 'pending' when the initial SyntaxError was encountered then 'resolved'
|
||||
* just before rewinding the parser.
|
||||
*
|
||||
* When using PossibleError one should set a pending error at the location
|
||||
* where an error occurs. From that point, the error may be resolved
|
||||
* (invalidated) or left until the PossibleError is checked.
|
||||
*
|
||||
* Ex:
|
||||
* PossibleError possibleError(*this);
|
||||
* possibleError.setPending(ParseError, JSMSG_BAD_PROP_ID, false);
|
||||
* // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
|
||||
* possibleError.checkForExprErrors();
|
||||
*
|
||||
* PossibleError possibleError(*this);
|
||||
* possibleError.setPending(ParseError, JSMSG_BAD_PROP_ID, false);
|
||||
* possibleError.setResolved();
|
||||
* // Returns true, no error is reported.
|
||||
* possibleError.checkForExprErrors();
|
||||
*
|
||||
* PossibleError possibleError(*this);
|
||||
* // Returns true, no error is reported.
|
||||
* possibleError.checkForExprErrors();
|
||||
*/
|
||||
class MOZ_STACK_CLASS PossibleError
|
||||
{
|
||||
enum ErrorState { None, Pending };
|
||||
ErrorState state_;
|
||||
|
||||
// Error reporting fields.
|
||||
uint32_t offset_;
|
||||
unsigned errorNumber_;
|
||||
ParseReportKind reportKind_;
|
||||
Parser<ParseHandler>& parser_;
|
||||
bool strict_;
|
||||
|
||||
public:
|
||||
explicit PossibleError(Parser<ParseHandler>& parser);
|
||||
|
||||
// Set a pending error.
|
||||
void setPending(ParseReportKind kind, unsigned errorNumber, bool strict);
|
||||
|
||||
// Resolve any pending error.
|
||||
void setResolved();
|
||||
|
||||
// Return true if an error is pending without reporting
|
||||
bool hasError();
|
||||
|
||||
// If there is a pending error report it and return false, otherwise return
|
||||
// true.
|
||||
bool checkForExprErrors();
|
||||
|
||||
// Pass pending errors between possible error instances. This is useful
|
||||
// for extending the lifetime of a pending error beyond the scope of
|
||||
// the PossibleError where it was initially set (keeping in mind that
|
||||
// PossibleError is a MOZ_STACK_CLASS).
|
||||
void transferErrorTo(PossibleError* other);
|
||||
};
|
||||
|
||||
public:
|
||||
ExclusiveContext* const context;
|
||||
LifoAlloc& alloc;
|
||||
@ -765,7 +832,15 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
|
||||
Node expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node expr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
@ -773,16 +848,26 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node yieldExpression(InHandling inHandling);
|
||||
Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node orExpr1(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked = PredictUninvoked);
|
||||
Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
|
||||
bool allowCallSyntax, InvokedPrediction invoked = PredictUninvoked);
|
||||
Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
|
||||
Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError, TokenKind tt,
|
||||
InvokedPrediction invoked = PredictUninvoked);
|
||||
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling,
|
||||
PossibleError* possibleError);
|
||||
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
|
||||
TripledotHandling tripledotHandling);
|
||||
|
||||
@ -854,7 +939,8 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
ForInOrOfTarget
|
||||
};
|
||||
|
||||
bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor);
|
||||
bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor,
|
||||
PossibleError* possibleError=nullptr);
|
||||
bool matchInOrOf(bool* isForInp, bool* isForOfp);
|
||||
|
||||
bool checkFunctionArguments();
|
||||
@ -909,7 +995,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node arrayInitializer(YieldHandling yieldHandling);
|
||||
Node newRegExp();
|
||||
|
||||
Node objectLiteral(YieldHandling yieldHandling);
|
||||
Node objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||
|
||||
enum PrepareLexicalKind {
|
||||
PrepareLet,
|
||||
|
@ -4,6 +4,7 @@ load(libdir + 'eqArrayHelper.js');
|
||||
|
||||
var arrayPattern = '[a = 1, b = 2, c = 3, d = 4, e = 5, f = 6]';
|
||||
var objectPattern = '{0: a = 1, 1: b = 2, 2: c = 3, 3: d = 4, 4: e = 5, 5: f = 6}';
|
||||
var objectPatternShorthand = '{a = 1, b = 2, c = 3, d = 4, e = 5, f = 6}';
|
||||
var nestedPattern = '{a: a = 1, b: [b = 2] = [], c: {c: [c]} = {c: [3]}, d: {d, e} = {d: 4, e: 5}, f: f = 6}';
|
||||
|
||||
function testAll(fn) {
|
||||
@ -17,6 +18,11 @@ function testAll(fn) {
|
||||
assertEqArray(fn(objectPattern, [undefined, 0, false, null, "", undefined]), [1, 0, false, null, "", 6]);
|
||||
assertEqArray(fn(objectPattern, [0, false]), [0, false, 3, 4, 5, 6]);
|
||||
|
||||
assertEqArray(fn(objectPatternShorthand, {}), [1, 2, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(objectPatternShorthand, {a: 2, b: 3, c: 4, d: 5, e: 6, f: 7, g: 8, h: 9}), [2, 3, 4, 5, 6, 7]);
|
||||
assertEqArray(fn(objectPatternShorthand, {a: undefined, b: 0, c: false, d: null, e: "", f: undefined}),
|
||||
[1, 0, false, null, "", 6]);
|
||||
assertEqArray(fn(objectPatternShorthand, {a: 0, b: false}), [0, false, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(nestedPattern, {}), [1, 2, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(nestedPattern, {a: 2, b: [], c: undefined}), [2, 2, 3, 4, 5, 6]);
|
||||
assertEqArray(fn(nestedPattern, {a: undefined, b: [3], c: {c: [4]}}), [1, 3, 4, 4, 5, 6]);
|
||||
@ -175,5 +181,9 @@ if (defaultsSupportedInForVar) {
|
||||
b = undefined;
|
||||
for (let {1: c = 10} in " ") { b = c; }
|
||||
assertEq(b, 10);
|
||||
|
||||
b = undefined;
|
||||
for (let {c = 10} in " ") { b = c; }
|
||||
assertEq(b, 10);
|
||||
`)();
|
||||
}
|
||||
|
@ -26,19 +26,16 @@ const versionError = /failed to match binary version/;
|
||||
const unknownSectionError = /failed to skip unknown section at end/;
|
||||
const sectionError = /failed to start section/;
|
||||
|
||||
const I32Code = 0;
|
||||
const I64Code = 1;
|
||||
const F32Code = 2;
|
||||
const F64Code = 3;
|
||||
const I32x4Code = 4;
|
||||
const F32x4Code = 5;
|
||||
const B32x4Code = 6;
|
||||
const VoidCode = 7;
|
||||
const VoidCode = 0;
|
||||
const I32Code = 1;
|
||||
const I64Code = 2;
|
||||
const F32Code = 3;
|
||||
const F64Code = 4;
|
||||
|
||||
function toBuf(array) {
|
||||
function toU8(array) {
|
||||
for (let b of array)
|
||||
assertEq(b < 256, true);
|
||||
return Uint8Array.from(array).buffer;
|
||||
return Uint8Array.from(array);
|
||||
}
|
||||
|
||||
function varU32(u32) {
|
||||
@ -49,33 +46,33 @@ function varU32(u32) {
|
||||
|
||||
const U32MAX_LEB = [255, 255, 255, 255, 15];
|
||||
|
||||
const wasmEval = Wasm.instantiateModule;
|
||||
|
||||
assertErrorMessage(() => wasmEval(toU8([])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toU8([42])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toU8([1,2,3,4])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3])), TypeError, versionError);
|
||||
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, 1])), TypeError, versionError);
|
||||
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0])), TypeError, versionError);
|
||||
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), TypeError, versionError);
|
||||
|
||||
function moduleHeaderThen(...rest) {
|
||||
return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest];
|
||||
}
|
||||
|
||||
const wasmEval = Wasm.instantiateModule;
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf([])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([42])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([magic0, magic1, magic2])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([1,2,3,4])), TypeError, magicError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([magic0, magic1, magic2, magic3])), TypeError, versionError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([magic0, magic1, magic2, magic3, 1])), TypeError, versionError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([magic0, magic1, magic2, magic3, ver0])), TypeError, versionError);
|
||||
assertErrorMessage(() => wasmEval(toBuf([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), TypeError, versionError);
|
||||
|
||||
var o = wasmEval(toBuf(moduleHeaderThen()));
|
||||
var o = wasmEval(toU8(moduleHeaderThen()));
|
||||
assertEq(Object.getOwnPropertyNames(o).length, 0);
|
||||
|
||||
wasmEval(toBuf(moduleHeaderThen(1, 0))); // unknown section containing 0-length string
|
||||
wasmEval(toBuf(moduleHeaderThen(2, 1, 0))); // unknown section containing 1-length string ("\0")
|
||||
wasmEval(toBuf(moduleHeaderThen(1, 0, 1, 0)));
|
||||
wasmEval(toBuf(moduleHeaderThen(1, 0, 2, 1, 0)));
|
||||
wasmEval(toBuf(moduleHeaderThen(1, 0, 2, 1, 0)));
|
||||
wasmEval(toU8(moduleHeaderThen(1, 0))); // unknown section containing 0-length string
|
||||
wasmEval(toU8(moduleHeaderThen(2, 1, 0))); // unknown section containing 1-length string ("\0")
|
||||
wasmEval(toU8(moduleHeaderThen(1, 0, 1, 0)));
|
||||
wasmEval(toU8(moduleHeaderThen(1, 0, 2, 1, 0)));
|
||||
wasmEval(toU8(moduleHeaderThen(1, 0, 2, 1, 0)));
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleHeaderThen(1))), TypeError, sectionError);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleHeaderThen(0, 1))), TypeError, sectionError);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleHeaderThen(0, 0))), TypeError, unknownSectionError);
|
||||
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(1))), TypeError, sectionError);
|
||||
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1))), TypeError, sectionError);
|
||||
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 0))), TypeError, unknownSectionError);
|
||||
|
||||
function cstring(name) {
|
||||
return (name + '\0').split('').map(c => c.charCodeAt(0));
|
||||
@ -94,7 +91,7 @@ function moduleWithSections(sectionArray) {
|
||||
bytes.push(...string(section.name));
|
||||
bytes.push(...section.body);
|
||||
}
|
||||
return bytes;
|
||||
return toU8(bytes);
|
||||
}
|
||||
|
||||
function sigSection(sigs) {
|
||||
@ -121,8 +118,9 @@ function funcBody(func) {
|
||||
var body = varU32(func.locals.length);
|
||||
for (let local of func.locals)
|
||||
body.push(...varU32(local));
|
||||
body.push(...varU32(func.body.length));
|
||||
return body.concat(...func.body);
|
||||
body = body.concat(...func.body);
|
||||
body.splice(0, 0, ...varU32(body.length));
|
||||
return body;
|
||||
}
|
||||
|
||||
function bodySection(bodies) {
|
||||
@ -153,44 +151,45 @@ const v2vSig = {args:[], ret:VoidCode};
|
||||
const i2vSig = {args:[I32Code], ret:VoidCode};
|
||||
const v2vBody = funcBody({locals:[], body:[]});
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: sigId, body: U32MAX_LEB, } ]))), TypeError, /too many signatures/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: sigId, body: [1, ...U32MAX_LEB], } ]))), TypeError, /too many arguments in signature/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:VoidCode}, {args:[], ret:VoidCode}])]))), TypeError, /duplicate signature/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, body: U32MAX_LEB } ])), TypeError, /too many signatures/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, body: [1, ...U32MAX_LEB], } ])), TypeError, /too many arguments in signature/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([{args:[], ret:VoidCode}, {args:[], ret:VoidCode}])])), TypeError, /duplicate signature/);
|
||||
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([{name: sigId, body: [1]}]))), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([{name: sigId, body: [1, 1, 0]}]))), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: sigId, body: [1]}])), TypeError);
|
||||
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: sigId, body: [1, 1, 0]}])), TypeError);
|
||||
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([i2vSig])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig, i2vSig])])));
|
||||
wasmEval(moduleWithSections([sigSection([])]));
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig])]));
|
||||
wasmEval(moduleWithSections([sigSection([i2vSig])]));
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig, i2vSig])]));
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:100}])]))), TypeError, /bad expression type/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[100], ret:VoidCode}])]))), TypeError, /bad value type/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([{args:[], ret:100}])])), TypeError, /bad expression type/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([{args:[100], ret:VoidCode}])])), TypeError, /bad value type/);
|
||||
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([]), declSection([0])]))), TypeError, /signature index out of range/);
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([1])]))), TypeError, /signature index out of range/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0])]))), TypeError, /expected function bodies/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([v2vBody])])));
|
||||
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([]), declSection([0])])), TypeError, /signature index out of range/);
|
||||
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([1])])), TypeError, /signature index out of range/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0])])), TypeError, /expected function bodies/);
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([v2vBody])]));
|
||||
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), {name: importId, body:[]}]))), TypeError);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([importSection([{sigIndex:0, module:"a", func:"b"}])]))), TypeError, /signature index out of range/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:1, module:"a", func:"b"}])]))), TypeError, /signature index out of range/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), importSection([])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:0, module:"a", func:""}])])), {a:()=>{}});
|
||||
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([v2vSig]), {name: importId, body:[]}])), TypeError);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([importSection([{sigIndex:0, module:"a", func:"b"}])])), TypeError, /signature index out of range/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:1, module:"a", func:"b"}])])), TypeError, /signature index out of range/);
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig]), importSection([])]));
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:0, module:"a", func:""}])]), {a:()=>{}});
|
||||
|
||||
wasmEval(toBuf(moduleWithSections([
|
||||
wasmEval(moduleWithSections([
|
||||
sigSection([v2vSig]),
|
||||
importSection([{sigIndex:0, module:"a", func:""}]),
|
||||
declSection([0]),
|
||||
bodySection([v2vBody])])), {a:()=>{}});
|
||||
bodySection([v2vBody])
|
||||
]), {a:()=>{}});
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: dataSegmentsId, body: [], } ]))), TypeError, /data section requires a memory section/);
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: dataSegmentsId, body: [], } ])), TypeError, /data section requires a memory section/);
|
||||
|
||||
wasmEval(toBuf(moduleWithSections([tableSection([])])));
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([tableSection([0])]))), TypeError, /table element out of range/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0]), bodySection([v2vBody])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,0]), bodySection([v2vBody])])));
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,1]), bodySection([v2vBody])]))), TypeError, /table element out of range/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection([0,1,0,2]), bodySection([v2vBody, v2vBody, v2vBody])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection([0,1,2]), bodySection([v2vBody, v2vBody, v2vBody])])));
|
||||
wasmEval(moduleWithSections([tableSection([])]));
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection([0])])), TypeError, /table element out of range/);
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0]), bodySection([v2vBody])]));
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,0]), bodySection([v2vBody])]));
|
||||
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,1]), bodySection([v2vBody])])), TypeError, /table element out of range/);
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection([0,1,0,2]), bodySection([v2vBody, v2vBody, v2vBody])]));
|
||||
wasmEval(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection([0,1,2]), bodySection([v2vBody, v2vBody, v2vBody])]));
|
||||
|
@ -366,7 +366,7 @@ MSG_DEF(JSMSG_WASM_FAIL, 1, JSEXN_TYPEERR, "wasm error: {0}")
|
||||
MSG_DEF(JSMSG_WASM_DECODE_FAIL, 2, JSEXN_TYPEERR, "wasm validation error at offset {0}: {1}")
|
||||
MSG_DEF(JSMSG_WASM_TEXT_FAIL, 1, JSEXN_SYNTAXERR, "wasm text error: {0}")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IND_CALL, 0, JSEXN_ERR, "wasm indirect call signature mismatch")
|
||||
MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be an ArrayBuffer")
|
||||
MSG_DEF(JSMSG_WASM_BAD_BUF_ARG, 0, JSEXN_TYPEERR, "first argument must be a typed array")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument, if present, must be an object")
|
||||
|
||||
// Proxy
|
||||
|
@ -5069,12 +5069,8 @@ WasmLoop(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
|
||||
Rooted<TypedArrayObject*> typedArray(cx, &ret->as<TypedArrayObject>());
|
||||
if (!TypedArrayObject::ensureHasBuffer(cx, typedArray))
|
||||
return false;
|
||||
|
||||
Rooted<ArrayBufferObject*> arrayBuffer(cx, typedArray->bufferUnshared());
|
||||
RootedObject exportObj(cx);
|
||||
if (!wasm::Eval(cx, arrayBuffer, importObj, &exportObj)) {
|
||||
if (!wasm::Eval(cx, typedArray, importObj, &exportObj)) {
|
||||
// Clear any pending exceptions, we don't care about them
|
||||
cx->clearPendingException();
|
||||
}
|
||||
|
102
js/src/tests/ecma_6/Object/destructuring-shorthand-defaults.js
Normal file
102
js/src/tests/ecma_6/Object/destructuring-shorthand-defaults.js
Normal file
@ -0,0 +1,102 @@
|
||||
/* 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/. */
|
||||
|
||||
// Ensure that the syntax used in shorthand destructuring with defaults
|
||||
// e.g. |{x=1, y=2} = {}| properly raises a syntax error within an object
|
||||
// literal. As per ES6 12.2.6 Object Initializer, "NOTE 3."
|
||||
|
||||
const SYNTAX_ERROR_STMTS = [
|
||||
// expressions
|
||||
"({x={}={}}),",
|
||||
"({y={x={}={}={}={}={}={}={}={}}={}}),",
|
||||
"({a=1, b=2, c=3, x=({}={})}),",
|
||||
"({x=1, y={z={1}}})",
|
||||
"({x=1} = {y=1});",
|
||||
"({x: y={z=1}}={})",
|
||||
"({x=1}),",
|
||||
"({z=1}={}, {w=2}, {e=3})=>{};",
|
||||
"({z={x=1}})=>{};",
|
||||
"({x = ({y=1}) => y})",
|
||||
"(({x=1})) => x",
|
||||
// declarations
|
||||
"let o = {x=1};",
|
||||
"var j = {x=1};",
|
||||
"var j = {x={y=1}}={};",
|
||||
"const z = {x=1};",
|
||||
"const z = {x={y=1}}={};",
|
||||
"const {x=1};",
|
||||
"const {x={y=33}}={};",
|
||||
"var {x=1};",
|
||||
"let {x=1};",
|
||||
"let x, y, {z=1}={}, {w=2}, {e=3};",
|
||||
// array initialization
|
||||
"[{x=1, y = ({z=2} = {})}];",
|
||||
// try/catch
|
||||
"try {throw 'a';} catch ({x={y=1}}) {}",
|
||||
// if/else
|
||||
"if ({k: 1, x={y=2}={}}) {}",
|
||||
"if (false) {} else if (true) { ({x=1}) }",
|
||||
// switch
|
||||
"switch ('c') { case 'c': ({x=1}); }",
|
||||
// for
|
||||
"for ({x=1}; 1;) {1}",
|
||||
"for ({x={y=2}}; 1;) {1}",
|
||||
"for (var x = 0; x < 2; x++) { ({x=1, y=2}) }",
|
||||
"for (let x=1;{x=1};){}",
|
||||
"for (let x=1;{x={y=2}};){}",
|
||||
"for (let x=1;1;{x=1}){}",
|
||||
"for (let x=1;1;{x={y=2}}){}",
|
||||
// while
|
||||
"while ({x=1}) {1};",
|
||||
"while ({x={y=2}}={}) {1};",
|
||||
// with
|
||||
"with ({x=1}) {};",
|
||||
"with ({x={y=3}={}}) {};",
|
||||
"with (Math) { ({x=1}) };"
|
||||
]
|
||||
|
||||
for (var stmt of SYNTAX_ERROR_STMTS) {
|
||||
assertThrowsInstanceOf(() => {
|
||||
eval(stmt);
|
||||
}, SyntaxError);
|
||||
}
|
||||
|
||||
const REFERENCE_ERROR_STMTS = [
|
||||
"({x} += {});",
|
||||
"({x = 1}) = {x: 2};",
|
||||
]
|
||||
|
||||
for (var stmt of REFERENCE_ERROR_STMTS) {
|
||||
assertThrowsInstanceOf(() => {
|
||||
eval(stmt);
|
||||
}, ReferenceError);
|
||||
}
|
||||
|
||||
// A few tricky but acceptable cases:
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=932080#c2
|
||||
|
||||
assertEq((({a = 0}) => a)({}), 0);
|
||||
assertEq((({a = 0} = {}) => a)({}), 0);
|
||||
assertEq((({a = 0} = {}) => a)({a: 1}), 1);
|
||||
|
||||
{
|
||||
let x, y;
|
||||
({x=1} = {});
|
||||
assertEq(x, 1);
|
||||
({x=1} = {x: 4});
|
||||
assertEq(x, 4);
|
||||
({x=1, y=2} = {})
|
||||
assertEq(x, 1);
|
||||
assertEq(y, 2);
|
||||
}
|
||||
|
||||
{
|
||||
let {x={i=1, j=2}={}}={};
|
||||
assertDeepEq(x, ({}));
|
||||
assertEq(i, 1);
|
||||
assertEq(j, 2);
|
||||
}
|
||||
|
||||
if (typeof reportCompare == "function")
|
||||
reportCompare(true, true);
|
@ -23,7 +23,7 @@ Gecko_ChildrenCount(RawGeckoNode* aNode)
|
||||
return aNode->GetChildCount();
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
Gecko_NodeIsElement(RawGeckoNode* aNode)
|
||||
{
|
||||
return aNode->IsElement();
|
||||
@ -101,36 +101,37 @@ Gecko_ElementState(RawGeckoElement* aElement)
|
||||
((1 << (NS_EVENT_STATE_HIGHEST_SERVO_BIT + 1)) - 1);
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
Gecko_IsHTMLElementInHTMLDocument(RawGeckoElement* aElement)
|
||||
{
|
||||
return aElement->IsHTMLElement() && aElement->OwnerDoc()->IsHTMLDocument();
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
Gecko_IsLink(RawGeckoElement* aElement)
|
||||
{
|
||||
return nsCSSRuleProcessor::IsLink(aElement);
|
||||
}
|
||||
|
||||
int Gecko_IsTextNode(RawGeckoNode* aNode)
|
||||
bool
|
||||
Gecko_IsTextNode(RawGeckoNode* aNode)
|
||||
{
|
||||
return aNode->NodeInfo()->NodeType() == nsIDOMNode::TEXT_NODE;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
Gecko_IsVisitedLink(RawGeckoElement* aElement)
|
||||
{
|
||||
return aElement->StyleState().HasState(NS_EVENT_STATE_VISITED);
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
Gecko_IsUnvisitedLink(RawGeckoElement* aElement)
|
||||
{
|
||||
return aElement->StyleState().HasState(NS_EVENT_STATE_UNVISITED);
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
Gecko_IsRootElement(RawGeckoElement* aElement)
|
||||
{
|
||||
return aElement->OwnerDoc()->GetRootElement() == aElement;
|
||||
@ -189,7 +190,8 @@ void Servo_RemoveStyleSheet(RawServoStyleSheet* sheet, RawServoStyleSet* set)
|
||||
"non-MOZ_STYLO build");
|
||||
}
|
||||
|
||||
int Servo_StyleSheetHasRules(RawServoStyleSheet* sheet)
|
||||
bool
|
||||
Servo_StyleSheetHasRules(RawServoStyleSheet* sheet)
|
||||
{
|
||||
MOZ_CRASH("stylo: shouldn't be calling Servo_StyleSheetHasRules in a "
|
||||
"non-MOZ_STYLO build");
|
||||
|
@ -7,7 +7,7 @@
|
||||
#ifndef mozilla_ServoBindings_h
|
||||
#define mozilla_ServoBindings_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "stdint.h"
|
||||
|
||||
/*
|
||||
* API for Servo to access Gecko data structures. This file must compile as valid
|
||||
@ -17,7 +17,6 @@
|
||||
* Functions beginning with Servo_ are implemented in Servo and invoked from Gecko.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
class nsINode;
|
||||
typedef nsINode RawGeckoNode;
|
||||
namespace mozilla { namespace dom { class Element; } }
|
||||
@ -28,28 +27,12 @@ typedef nsIDocument RawGeckoDocument;
|
||||
struct ServoNodeData;
|
||||
struct RawServoStyleSheet;
|
||||
struct RawServoStyleSet;
|
||||
#else
|
||||
struct RawGeckoNode;
|
||||
typedef struct RawGeckoNode RawGeckoNode;
|
||||
struct RawGeckoElement;
|
||||
typedef struct RawGeckoElement RawGeckoElement;
|
||||
struct RawGeckoDocument;
|
||||
typedef struct RawGeckoDocument RawGeckoDocument;
|
||||
struct ServoNodeData;
|
||||
typedef struct ServoNodeData ServoNodeData;
|
||||
struct RawServoStyleSheet;
|
||||
typedef struct RawServoStyleSheet RawServoStyleSheet;
|
||||
struct RawServoStyleSet;
|
||||
typedef struct RawServoStyleSet RawServoStyleSet;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// DOM Traversal.
|
||||
uint32_t Gecko_ChildrenCount(RawGeckoNode* node);
|
||||
int Gecko_NodeIsElement(RawGeckoNode* node);
|
||||
bool Gecko_NodeIsElement(RawGeckoNode* node);
|
||||
RawGeckoNode* Gecko_GetParentNode(RawGeckoNode* node);
|
||||
RawGeckoNode* Gecko_GetFirstChild(RawGeckoNode* node);
|
||||
RawGeckoNode* Gecko_GetLastChild(RawGeckoNode* node);
|
||||
@ -64,12 +47,12 @@ RawGeckoElement* Gecko_GetDocumentElement(RawGeckoDocument* document);
|
||||
|
||||
// Selector Matching.
|
||||
uint8_t Gecko_ElementState(RawGeckoElement* element);
|
||||
int Gecko_IsHTMLElementInHTMLDocument(RawGeckoElement* element);
|
||||
int Gecko_IsLink(RawGeckoElement* element);
|
||||
int Gecko_IsTextNode(RawGeckoNode* node);
|
||||
int Gecko_IsVisitedLink(RawGeckoElement* element);
|
||||
int Gecko_IsUnvisitedLink(RawGeckoElement* element);
|
||||
int Gecko_IsRootElement(RawGeckoElement* element);
|
||||
bool Gecko_IsHTMLElementInHTMLDocument(RawGeckoElement* element);
|
||||
bool Gecko_IsLink(RawGeckoElement* element);
|
||||
bool Gecko_IsTextNode(RawGeckoNode* node);
|
||||
bool Gecko_IsVisitedLink(RawGeckoElement* element);
|
||||
bool Gecko_IsUnvisitedLink(RawGeckoElement* element);
|
||||
bool Gecko_IsRootElement(RawGeckoElement* element);
|
||||
|
||||
// Node data.
|
||||
ServoNodeData* Gecko_GetNodeData(RawGeckoNode* node);
|
||||
@ -85,15 +68,13 @@ void Servo_ReleaseStylesheet(RawServoStyleSheet* sheet);
|
||||
void Servo_AppendStyleSheet(RawServoStyleSheet* sheet, RawServoStyleSet* set);
|
||||
void Servo_PrependStyleSheet(RawServoStyleSheet* sheet, RawServoStyleSet* set);
|
||||
void Servo_RemoveStyleSheet(RawServoStyleSheet* sheet, RawServoStyleSet* set);
|
||||
int Servo_StyleSheetHasRules(RawServoStyleSheet* sheet);
|
||||
bool Servo_StyleSheetHasRules(RawServoStyleSheet* sheet);
|
||||
RawServoStyleSet* Servo_InitStyleSet();
|
||||
void Servo_DropStyleSet(RawServoStyleSet* set);
|
||||
|
||||
// Servo API.
|
||||
void Servo_RestyleDocument(RawGeckoDocument* doc, RawServoStyleSet* set);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // mozilla_ServoBindings_h
|
||||
|
@ -1286,7 +1286,7 @@ void SchedulableTrickleCandidate::Trickle() {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
}
|
||||
|
||||
class IceGatherTest : public StunTest {
|
||||
class WebRtcIceGatherTest : public StunTest {
|
||||
public:
|
||||
void SetUp() override {
|
||||
StunTest::SetUp();
|
||||
@ -1453,9 +1453,9 @@ class IceGatherTest : public StunTest {
|
||||
mozilla::UniquePtr<IceTestPeer> peer_;
|
||||
};
|
||||
|
||||
class IceConnectTest : public StunTest {
|
||||
class WebRtcIceConnectTest : public StunTest {
|
||||
public:
|
||||
IceConnectTest() :
|
||||
WebRtcIceConnectTest() :
|
||||
initted_(false),
|
||||
use_nat_(false),
|
||||
filtering_type_(TestNat::ENDPOINT_INDEPENDENT),
|
||||
@ -1676,7 +1676,7 @@ class IceConnectTest : public StunTest {
|
||||
p2_->Connect(p1_.get(), TRICKLE_NONE, false);
|
||||
p1_->Connect(p2_.get(), TRICKLE_NONE, true);
|
||||
test_utils_->sts_target()->Dispatch(WrapRunnable(this,
|
||||
&IceConnectTest::CloseP1),
|
||||
&WebRtcIceConnectTest::CloseP1),
|
||||
NS_DISPATCH_SYNC);
|
||||
p2_->StartChecks();
|
||||
|
||||
@ -1706,12 +1706,12 @@ class IceConnectTest : public StunTest {
|
||||
bool block_udp_;
|
||||
};
|
||||
|
||||
class PrioritizerTest : public StunTest {
|
||||
class WebRtcIcePrioritizerTest : public StunTest {
|
||||
public:
|
||||
PrioritizerTest():
|
||||
WebRtcIcePrioritizerTest():
|
||||
prioritizer_(nullptr) {}
|
||||
|
||||
~PrioritizerTest() {
|
||||
~WebRtcIcePrioritizerTest() {
|
||||
if (prioritizer_) {
|
||||
nr_interface_prioritizer_destroy(&prioritizer_);
|
||||
}
|
||||
@ -1754,9 +1754,9 @@ class PrioritizerTest : public StunTest {
|
||||
nr_interface_prioritizer *prioritizer_;
|
||||
};
|
||||
|
||||
class PacketFilterTest : public StunTest {
|
||||
class WebRtcIcePacketFilterTest : public StunTest {
|
||||
public:
|
||||
PacketFilterTest(): filter_(nullptr) {}
|
||||
WebRtcIcePacketFilterTest(): filter_(nullptr) {}
|
||||
|
||||
void SetUp() {
|
||||
StunTest::SetUp();
|
||||
@ -1771,7 +1771,7 @@ class PacketFilterTest : public StunTest {
|
||||
|
||||
void TearDown() {
|
||||
test_utils_->sts_target()->Dispatch(WrapRunnable(this,
|
||||
&PacketFilterTest::TearDown_s),
|
||||
&WebRtcIcePacketFilterTest::TearDown_s),
|
||||
NS_DISPATCH_SYNC);
|
||||
StunTest::TearDown();
|
||||
}
|
||||
@ -1819,7 +1819,7 @@ class PacketFilterTest : public StunTest {
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
|
||||
if (stun_server_hostname_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1829,7 +1829,7 @@ TEST_F(IceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerTcpHostnameNoResolver) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerTcpHostnameNoResolver) {
|
||||
if (stun_server_hostname_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1841,7 +1841,7 @@ TEST_F(IceGatherTest, TestGatherFakeStunServerTcpHostnameNoResolver) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerIpAddress) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerIpAddress) {
|
||||
if (stun_server_address_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1852,7 +1852,7 @@ TEST_F(IceGatherTest, TestGatherFakeStunServerIpAddress) {
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherStunServerIpAddressDefaultRouteOnly) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherStunServerIpAddressDefaultRouteOnly) {
|
||||
if (stun_server_address_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1865,7 +1865,7 @@ TEST_F(IceGatherTest, TestGatherStunServerIpAddressDefaultRouteOnly) {
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " host "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerHostname) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostname) {
|
||||
if (stun_server_hostname_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1876,14 +1876,14 @@ TEST_F(IceGatherTest, TestGatherFakeStunServerHostname) {
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunBogusHostname) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherFakeStunBogusHostname) {
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
|
||||
peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddress) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddress) {
|
||||
if (stun_server_address_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1896,7 +1896,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddress) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
|
||||
if (stun_server_address_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1913,7 +1913,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerHostname) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostname) {
|
||||
if (stun_server_hostname_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1926,7 +1926,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerHostname) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerHostnameTcp) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameTcp) {
|
||||
EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
|
||||
peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
|
||||
kNrIceTransportTcp);
|
||||
@ -1939,7 +1939,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerHostnameTcp) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerHostnameBothUdpTcp) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameBothUdpTcp) {
|
||||
if (stun_server_hostname_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1958,7 +1958,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerHostnameBothUdpTcp) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddressBothUdpTcp) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressBothUdpTcp) {
|
||||
if (stun_server_address_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -1977,7 +1977,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddressBothUdpTcp) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunBogusHostname) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunBogusHostname) {
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
|
||||
peer_->SetDNSResolver();
|
||||
@ -1985,7 +1985,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunBogusHostname) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDNSStunBogusHostnameTcp) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunBogusHostnameTcp) {
|
||||
EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
|
||||
peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort,
|
||||
kNrIceTransportTcp);
|
||||
@ -1994,7 +1994,7 @@ TEST_F(IceGatherTest, TestGatherDNSStunBogusHostnameTcp) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestDefaultCandidate) {
|
||||
TEST_F(WebRtcIceGatherTest, TestDefaultCandidate) {
|
||||
EnsurePeer();
|
||||
peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
|
||||
Gather();
|
||||
@ -2002,7 +2002,7 @@ TEST_F(IceGatherTest, TestDefaultCandidate) {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(peer_->GetDefaultCandidate(0, &default_candidate)));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherTurn) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherTurn) {
|
||||
EnsurePeer();
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
@ -2011,7 +2011,7 @@ TEST_F(IceGatherTest, TestGatherTurn) {
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherTurnTcp) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherTurnTcp) {
|
||||
EnsurePeer();
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
@ -2020,7 +2020,7 @@ TEST_F(IceGatherTest, TestGatherTurnTcp) {
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDisableComponent) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherDisableComponent) {
|
||||
if (stun_server_hostname_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -2039,12 +2039,12 @@ TEST_F(IceGatherTest, TestGatherDisableComponent) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherVerifyNoLoopback) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherVerifyNoLoopback) {
|
||||
Gather();
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, "127.0.0.1"));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherAllowLoopback) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherAllowLoopback) {
|
||||
// Set up peer with loopback allowed.
|
||||
peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, true);
|
||||
peer_->AddStream(1);
|
||||
@ -2052,7 +2052,7 @@ TEST_F(IceGatherTest, TestGatherAllowLoopback) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "127.0.0.1"));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherTcpDisabled) {
|
||||
TEST_F(WebRtcIceGatherTest, TestGatherTcpDisabled) {
|
||||
// Set up peer with tcp disabled.
|
||||
peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false);
|
||||
peer_->AddStream(1);
|
||||
@ -2063,25 +2063,25 @@ TEST_F(IceGatherTest, TestGatherTcpDisabled) {
|
||||
|
||||
// Verify that a bogus candidate doesn't cause crashes on the
|
||||
// main thread. See bug 856433.
|
||||
TEST_F(IceGatherTest, TestBogusCandidate) {
|
||||
TEST_F(WebRtcIceGatherTest, TestBogusCandidate) {
|
||||
Gather();
|
||||
peer_->ParseCandidate(0, kBogusIceCandidate);
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServer) {
|
||||
TEST_F(WebRtcIceGatherTest, VerifyTestStunServer) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.133", 3333);
|
||||
Gather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunTcpServer) {
|
||||
TEST_F(WebRtcIceGatherTest, VerifyTestStunTcpServer) {
|
||||
UseFakeStunTcpServerWithResponse("192.0.2.233", 3333);
|
||||
Gather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.233 3333 typ srflx",
|
||||
" tcptype "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServerV6) {
|
||||
TEST_F(WebRtcIceGatherTest, VerifyTestStunServerV6) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
@ -2091,13 +2091,13 @@ TEST_F(IceGatherTest, VerifyTestStunServerV6) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServerFQDN) {
|
||||
TEST_F(WebRtcIceGatherTest, VerifyTestStunServerFQDN) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.133", 3333, "stun.example.com");
|
||||
Gather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServerV6FQDN) {
|
||||
TEST_F(WebRtcIceGatherTest, VerifyTestStunServerV6FQDN) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
@ -2107,13 +2107,13 @@ TEST_F(IceGatherTest, VerifyTestStunServerV6FQDN) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsWildcardAddr) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunServerReturnsWildcardAddr) {
|
||||
UseFakeStunUdpServerWithResponse("0.0.0.0", 3333);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 0.0.0.0 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsWildcardAddrV6) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunServerReturnsWildcardAddrV6) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
@ -2123,19 +2123,19 @@ TEST_F(IceGatherTest, TestStunServerReturnsWildcardAddrV6) {
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " :: "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsPort0) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunServerReturnsPort0) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.133", 0);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.2.133 0 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsLoopbackAddr) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunServerReturnsLoopbackAddr) {
|
||||
UseFakeStunUdpServerWithResponse("127.0.0.133", 3333);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 127.0.0.133 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsLoopbackAddrV6) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunServerReturnsLoopbackAddrV6) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
@ -2145,7 +2145,7 @@ TEST_F(IceGatherTest, TestStunServerReturnsLoopbackAddrV6) {
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " ::1 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerTrickle) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunServerTrickle) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
|
||||
TestStunServer::GetInstance(AF_INET)->SetDropInitialPackets(3);
|
||||
Gather(0);
|
||||
@ -2156,7 +2156,7 @@ TEST_F(IceGatherTest, TestStunServerTrickle) {
|
||||
|
||||
// Test default route only with our fake STUN server and
|
||||
// apparently NATted.
|
||||
TEST_F(IceGatherTest, TestFakeStunServerNatedDefaultRouteOnly) {
|
||||
TEST_F(WebRtcIceGatherTest, TestFakeStunServerNatedDefaultRouteOnly) {
|
||||
peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false, true);
|
||||
peer_->AddStream(1);
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
|
||||
@ -2174,7 +2174,7 @@ TEST_F(IceGatherTest, TestFakeStunServerNatedDefaultRouteOnly) {
|
||||
|
||||
// Test default route only with our fake STUN server and
|
||||
// apparently non-NATted.
|
||||
TEST_F(IceGatherTest, TestFakeStunServerNoNatDefaultRouteOnly) {
|
||||
TEST_F(WebRtcIceGatherTest, TestFakeStunServerNoNatDefaultRouteOnly) {
|
||||
peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false, true);
|
||||
peer_->AddStream(1);
|
||||
UseTestStunServer();
|
||||
@ -2185,7 +2185,7 @@ TEST_F(IceGatherTest, TestFakeStunServerNoNatDefaultRouteOnly) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunTcpServerTrickle) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunTcpServerTrickle) {
|
||||
UseFakeStunTcpServerWithResponse("192.0.3.1", 3333);
|
||||
TestStunTcpServer::GetInstance(AF_INET)->SetDelay(500);
|
||||
Gather(0);
|
||||
@ -2194,7 +2194,7 @@ TEST_F(IceGatherTest, TestStunTcpServerTrickle) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunTcpAndUdpServerTrickle) {
|
||||
TEST_F(WebRtcIceGatherTest, TestStunTcpAndUdpServerTrickle) {
|
||||
UseFakeStunUdpTcpServersWithResponse("192.0.2.1", 3333, "192.0.3.1", 3333);
|
||||
TestStunServer::GetInstance(AF_INET)->SetDropInitialPackets(3);
|
||||
TestStunTcpServer::GetInstance(AF_INET)->SetDelay(500);
|
||||
@ -2206,31 +2206,31 @@ TEST_F(IceGatherTest, TestStunTcpAndUdpServerTrickle) {
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGather) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGather) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherTcp) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherTcp) {
|
||||
Init(false, true);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherAutoPrioritize) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherAutoPrioritize) {
|
||||
Init(false, false);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(IceConnectTest, TestConnect) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnect) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTcp) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTcp) {
|
||||
Init(false, true);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2242,7 +2242,7 @@ TEST_F(IceConnectTest, TestConnectTcp) {
|
||||
|
||||
//TCP SO tests works on localhost only with delay applied:
|
||||
// tc qdisc add dev lo root netem delay 10ms
|
||||
TEST_F(IceConnectTest, DISABLED_TestConnectTcpSo) {
|
||||
TEST_F(WebRtcIceConnectTest, DISABLED_TestConnectTcpSo) {
|
||||
Init(false, true);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2253,7 +2253,7 @@ TEST_F(IceConnectTest, DISABLED_TestConnectTcpSo) {
|
||||
}
|
||||
|
||||
// Disabled because this breaks with hairpinning.
|
||||
TEST_F(IceConnectTest, DISABLED_TestConnectDefaultRouteOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, DISABLED_TestConnectDefaultRouteOnly) {
|
||||
Init(false, false, true);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2262,7 +2262,7 @@ TEST_F(IceConnectTest, DISABLED_TestConnectDefaultRouteOnly) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestLoopbackOnlySortOf) {
|
||||
TEST_F(WebRtcIceConnectTest, TestLoopbackOnlySortOf) {
|
||||
Init(true, false);
|
||||
AddStream("first", 1);
|
||||
SetCandidateFilter(IsLoopbackCandidate);
|
||||
@ -2271,7 +2271,7 @@ TEST_F(IceConnectTest, TestLoopbackOnlySortOf) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectBothControllingP1Wins) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectBothControllingP1Wins) {
|
||||
AddStream("first", 1);
|
||||
p1_->SetTiebreaker(1);
|
||||
p2_->SetTiebreaker(0);
|
||||
@ -2281,7 +2281,7 @@ TEST_F(IceConnectTest, TestConnectBothControllingP1Wins) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectBothControllingP2Wins) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectBothControllingP2Wins) {
|
||||
AddStream("first", 1);
|
||||
p1_->SetTiebreaker(0);
|
||||
p2_->SetTiebreaker(1);
|
||||
@ -2291,14 +2291,14 @@ TEST_F(IceConnectTest, TestConnectBothControllingP2Wins) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectIceLiteOfferer) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectIceLiteOfferer) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
p1_->SimulateIceLite();
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestTrickleBothControllingP1Wins) {
|
||||
TEST_F(WebRtcIceConnectTest, TestTrickleBothControllingP1Wins) {
|
||||
AddStream("first", 1);
|
||||
p1_->SetTiebreaker(1);
|
||||
p2_->SetTiebreaker(0);
|
||||
@ -2312,7 +2312,7 @@ TEST_F(IceConnectTest, TestTrickleBothControllingP1Wins) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestTrickleBothControllingP2Wins) {
|
||||
TEST_F(WebRtcIceConnectTest, TestTrickleBothControllingP2Wins) {
|
||||
AddStream("first", 1);
|
||||
p1_->SetTiebreaker(0);
|
||||
p2_->SetTiebreaker(1);
|
||||
@ -2326,7 +2326,7 @@ TEST_F(IceConnectTest, TestTrickleBothControllingP2Wins) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestTrickleIceLiteOfferer) {
|
||||
TEST_F(WebRtcIceConnectTest, TestTrickleIceLiteOfferer) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
p1_->SimulateIceLite();
|
||||
@ -2337,7 +2337,7 @@ TEST_F(IceConnectTest, TestTrickleIceLiteOfferer) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherFullCone) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherFullCone) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::ENDPOINT_INDEPENDENT);
|
||||
@ -2345,7 +2345,7 @@ TEST_F(IceConnectTest, TestGatherFullCone) {
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherFullConeAutoPrioritize) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherFullConeAutoPrioritize) {
|
||||
Init(true, false);
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
@ -2355,7 +2355,7 @@ TEST_F(IceConnectTest, TestGatherFullConeAutoPrioritize) {
|
||||
}
|
||||
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectFullCone) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectFullCone) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::ENDPOINT_INDEPENDENT);
|
||||
@ -2366,7 +2366,7 @@ TEST_F(IceConnectTest, TestConnectFullCone) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectNoNatRouteOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectNoNatRouteOnly) {
|
||||
Init(false, false, true);
|
||||
AddStream("first", 1);
|
||||
UseTestStunServer();
|
||||
@ -2379,7 +2379,7 @@ TEST_F(IceConnectTest, TestConnectNoNatRouteOnly) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectFullConeDefaultRouteOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectFullConeDefaultRouteOnly) {
|
||||
Init(false, false, true);
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
@ -2391,7 +2391,7 @@ TEST_F(IceConnectTest, TestConnectFullConeDefaultRouteOnly) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherAddressRestrictedCone) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherAddressRestrictedCone) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::ADDRESS_DEPENDENT);
|
||||
@ -2399,7 +2399,7 @@ TEST_F(IceConnectTest, TestGatherAddressRestrictedCone) {
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectAddressRestrictedCone) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectAddressRestrictedCone) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::ADDRESS_DEPENDENT);
|
||||
@ -2410,7 +2410,7 @@ TEST_F(IceConnectTest, TestConnectAddressRestrictedCone) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherPortRestrictedCone) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherPortRestrictedCone) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::PORT_DEPENDENT);
|
||||
@ -2418,7 +2418,7 @@ TEST_F(IceConnectTest, TestGatherPortRestrictedCone) {
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectPortRestrictedCone) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectPortRestrictedCone) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::PORT_DEPENDENT);
|
||||
@ -2429,7 +2429,7 @@ TEST_F(IceConnectTest, TestConnectPortRestrictedCone) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherSymmetricNat) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherSymmetricNat) {
|
||||
AddStream("first", 1);
|
||||
UseNat();
|
||||
SetFilteringType(TestNat::PORT_DEPENDENT);
|
||||
@ -2437,7 +2437,7 @@ TEST_F(IceConnectTest, TestGatherSymmetricNat) {
|
||||
ASSERT_TRUE(Gather());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectSymmetricNat) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectSymmetricNat) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2455,7 +2455,7 @@ TEST_F(IceConnectTest, TestConnectSymmetricNat) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestGatherNatBlocksUDP) {
|
||||
TEST_F(WebRtcIceConnectTest, TestGatherNatBlocksUDP) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2476,7 +2476,7 @@ TEST_F(IceConnectTest, TestGatherNatBlocksUDP) {
|
||||
ASSERT_TRUE(Gather(kDefaultTimeout * 3));
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectNatBlocksUDP) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectNatBlocksUDP) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2503,13 +2503,13 @@ TEST_F(IceConnectTest, TestConnectNatBlocksUDP) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTwoComponents) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTwoComponents) {
|
||||
AddStream("first", 2);
|
||||
ASSERT_TRUE(Gather());
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTwoComponentsDisableSecond) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTwoComponentsDisableSecond) {
|
||||
AddStream("first", 2);
|
||||
ASSERT_TRUE(Gather());
|
||||
p1_->DisableComponent(0, 2);
|
||||
@ -2518,7 +2518,7 @@ TEST_F(IceConnectTest, TestConnectTwoComponentsDisableSecond) {
|
||||
}
|
||||
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectP2ThenP1) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectP2();
|
||||
@ -2527,7 +2527,7 @@ TEST_F(IceConnectTest, TestConnectP2ThenP1) {
|
||||
WaitForComplete();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectP2ThenP1Trickle) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1Trickle) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectP2();
|
||||
@ -2537,7 +2537,7 @@ TEST_F(IceConnectTest, TestConnectP2ThenP1Trickle) {
|
||||
WaitForComplete();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectP2ThenP1TrickleTwoComponents) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1TrickleTwoComponents) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 2);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2552,14 +2552,14 @@ TEST_F(IceConnectTest, TestConnectP2ThenP1TrickleTwoComponents) {
|
||||
WaitForComplete(2);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectAutoPrioritize) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectAutoPrioritize) {
|
||||
Init(false, false);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTrickleOneStreamOneComponent) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTrickleOneStreamOneComponent) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectTrickle();
|
||||
@ -2569,7 +2569,7 @@ TEST_F(IceConnectTest, TestConnectTrickleOneStreamOneComponent) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTrickleTwoStreamsOneComponent) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTrickleTwoStreamsOneComponent) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2650,7 +2650,7 @@ void DropTrickleCandidates(
|
||||
std::vector<SchedulableTrickleCandidate*>& candidates) {
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTrickleAddStreamDuringICE) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTrickleAddStreamDuringICE) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectTrickle();
|
||||
@ -2664,7 +2664,7 @@ TEST_F(IceConnectTest, TestConnectTrickleAddStreamDuringICE) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTrickleAddStreamAfterICE) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTrickleAddStreamAfterICE) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectTrickle();
|
||||
@ -2682,7 +2682,7 @@ TEST_F(IceConnectTest, TestConnectTrickleAddStreamAfterICE) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, RemoveStream) {
|
||||
TEST_F(WebRtcIceConnectTest, RemoveStream) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2699,7 +2699,7 @@ TEST_F(IceConnectTest, RemoveStream) {
|
||||
ConnectTrickle();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, P1NoTrickle) {
|
||||
TEST_F(WebRtcIceConnectTest, P1NoTrickle) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectTrickle();
|
||||
@ -2709,7 +2709,7 @@ TEST_F(IceConnectTest, P1NoTrickle) {
|
||||
ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, P2NoTrickle) {
|
||||
TEST_F(WebRtcIceConnectTest, P2NoTrickle) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectTrickle();
|
||||
@ -2719,7 +2719,7 @@ TEST_F(IceConnectTest, P2NoTrickle) {
|
||||
ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, RemoveAndAddStream) {
|
||||
TEST_F(WebRtcIceConnectTest, RemoveAndAddStream) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2741,7 +2741,7 @@ TEST_F(IceConnectTest, RemoveAndAddStream) {
|
||||
ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, RemoveStreamBeforeGather) {
|
||||
TEST_F(WebRtcIceConnectTest, RemoveStreamBeforeGather) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
ASSERT_TRUE(Gather(0));
|
||||
@ -2754,7 +2754,7 @@ TEST_F(IceConnectTest, RemoveStreamBeforeGather) {
|
||||
ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, RemoveStreamDuringGather) {
|
||||
TEST_F(WebRtcIceConnectTest, RemoveStreamDuringGather) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
RemoveStream(0);
|
||||
@ -2766,7 +2766,7 @@ TEST_F(IceConnectTest, RemoveStreamDuringGather) {
|
||||
ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, RemoveStreamDuringConnect) {
|
||||
TEST_F(WebRtcIceConnectTest, RemoveStreamDuringConnect) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2780,7 +2780,7 @@ TEST_F(IceConnectTest, RemoveStreamDuringConnect) {
|
||||
ASSERT_TRUE_WAIT(p2_->ice_complete(), 1000);
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectRealTrickleOneStreamOneComponent) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectRealTrickleOneStreamOneComponent) {
|
||||
AddStream("first", 1);
|
||||
AddStream("second", 1);
|
||||
ASSERT_TRUE(Gather(0));
|
||||
@ -2791,14 +2791,14 @@ TEST_F(IceConnectTest, TestConnectRealTrickleOneStreamOneComponent) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestSendReceive) {
|
||||
TEST_F(WebRtcIceConnectTest, TestSendReceive) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestSendReceiveTcp) {
|
||||
TEST_F(WebRtcIceConnectTest, TestSendReceiveTcp) {
|
||||
Init(false, true);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2811,7 +2811,7 @@ TEST_F(IceConnectTest, TestSendReceiveTcp) {
|
||||
|
||||
//TCP SO tests works on localhost only with delay applied:
|
||||
// tc qdisc add dev lo root netem delay 10ms
|
||||
TEST_F(IceConnectTest, DISABLED_TestSendReceiveTcpSo) {
|
||||
TEST_F(WebRtcIceConnectTest, DISABLED_TestSendReceiveTcpSo) {
|
||||
Init(false, true);
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
@ -2822,7 +2822,7 @@ TEST_F(IceConnectTest, DISABLED_TestSendReceiveTcpSo) {
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurn) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurn) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2833,7 +2833,7 @@ TEST_F(IceConnectTest, TestConnectTurn) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnWithDelay) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithDelay) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2849,7 +2849,7 @@ TEST_F(IceConnectTest, TestConnectTurnWithDelay) {
|
||||
WaitForComplete();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2866,7 +2866,7 @@ TEST_F(IceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2883,7 +2883,7 @@ TEST_F(IceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2902,7 +2902,7 @@ TEST_F(IceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
|
||||
AssertCheckingReached();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnTcp) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnTcp) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2913,7 +2913,7 @@ TEST_F(IceConnectTest, TestConnectTurnTcp) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnOnly) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2927,7 +2927,7 @@ TEST_F(IceConnectTest, TestConnectTurnOnly) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTurnTcpOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectTurnTcpOnly) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2942,7 +2942,7 @@ TEST_F(IceConnectTest, TestConnectTurnTcpOnly) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestSendReceiveTurnOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnOnly) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2957,7 +2957,7 @@ TEST_F(IceConnectTest, TestSendReceiveTurnOnly) {
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestSendReceiveTurnTcpOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnTcpOnly) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2973,7 +2973,7 @@ TEST_F(IceConnectTest, TestSendReceiveTurnTcpOnly) {
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestSendReceiveTurnBothOnly) {
|
||||
TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnBothOnly) {
|
||||
if (turn_server_.empty())
|
||||
return;
|
||||
|
||||
@ -2998,13 +2998,13 @@ TEST_F(IceConnectTest, TestSendReceiveTurnBothOnly) {
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectShutdownOneSide) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectShutdownOneSide) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
ConnectThenDelete();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestPollCandPairsBeforeConnect) {
|
||||
TEST_F(WebRtcIceConnectTest, TestPollCandPairsBeforeConnect) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
|
||||
@ -3019,7 +3019,7 @@ TEST_F(IceConnectTest, TestPollCandPairsBeforeConnect) {
|
||||
ASSERT_EQ(0U, pairs.size());
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestPollCandPairsAfterConnect) {
|
||||
TEST_F(WebRtcIceConnectTest, TestPollCandPairsAfterConnect) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
Connect();
|
||||
@ -3042,7 +3042,7 @@ TEST_F(IceConnectTest, TestPollCandPairsAfterConnect) {
|
||||
ASSERT_TRUE(ContainsSucceededPair(pairs));
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestHostCandPairingFilter) {
|
||||
TEST_F(WebRtcIceConnectTest, TestHostCandPairingFilter) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather(kDefaultTimeout, false));
|
||||
SetCandidateFilter(IsIpv4Candidate);
|
||||
@ -3070,7 +3070,7 @@ TEST_F(IceConnectTest, TestHostCandPairingFilter) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestSrflxCandPairingFilter) {
|
||||
TEST_F(WebRtcIceConnectTest, TestSrflxCandPairingFilter) {
|
||||
if (stun_server_address_.empty()) {
|
||||
return;
|
||||
}
|
||||
@ -3112,7 +3112,7 @@ TEST_F(IceConnectTest, TestSrflxCandPairingFilter) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestPollCandPairsDuringConnect) {
|
||||
TEST_F(WebRtcIceConnectTest, TestPollCandPairsDuringConnect) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
|
||||
@ -3137,7 +3137,7 @@ TEST_F(IceConnectTest, TestPollCandPairsDuringConnect) {
|
||||
ASSERT_TRUE(ContainsSucceededPair(pairs2));
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestRLogRingBuffer) {
|
||||
TEST_F(WebRtcIceConnectTest, TestRLogRingBuffer) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather());
|
||||
|
||||
@ -3178,7 +3178,7 @@ TEST_F(IceConnectTest, TestRLogRingBuffer) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PrioritizerTest, TestPrioritizer) {
|
||||
TEST_F(WebRtcIcePrioritizerTest, TestPrioritizer) {
|
||||
SetPriorizer(::mozilla::CreateInterfacePrioritizer());
|
||||
|
||||
AddInterface("0", NR_INTERFACE_TYPE_VPN, 100); // unknown vpn
|
||||
@ -3209,17 +3209,17 @@ TEST_F(PrioritizerTest, TestPrioritizer) {
|
||||
HasLowerPreference("5", "4");
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestSendNonStunPacket) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestSendNonStunPacket) {
|
||||
const unsigned char data[] = "12345abcde";
|
||||
TestOutgoing(data, sizeof(data), 123, 45, false);
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestRecvNonStunPacket) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestRecvNonStunPacket) {
|
||||
const unsigned char data[] = "12345abcde";
|
||||
TestIncoming(data, sizeof(data), 123, 45, false);
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestSendStunPacket) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestSendStunPacket) {
|
||||
nr_stun_message *msg;
|
||||
ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
|
||||
msg->header.type = NR_STUN_MSG_BINDING_REQUEST;
|
||||
@ -3228,7 +3228,7 @@ TEST_F(PacketFilterTest, TestSendStunPacket) {
|
||||
ASSERT_EQ(0, nr_stun_message_destroy(&msg));
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestRecvStunPacketWithoutAPendingId) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithoutAPendingId) {
|
||||
nr_stun_message *msg;
|
||||
ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
|
||||
|
||||
@ -3245,7 +3245,7 @@ TEST_F(PacketFilterTest, TestRecvStunPacketWithoutAPendingId) {
|
||||
ASSERT_EQ(0, nr_stun_message_destroy(&msg));
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestRecvStunPacketWithoutAPendingAddress) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithoutAPendingAddress) {
|
||||
nr_stun_message *msg;
|
||||
ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
|
||||
|
||||
@ -3261,7 +3261,7 @@ TEST_F(PacketFilterTest, TestRecvStunPacketWithoutAPendingAddress) {
|
||||
ASSERT_EQ(0, nr_stun_message_destroy(&msg));
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestRecvStunPacketWithPendingIdAndAddress) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestRecvStunPacketWithPendingIdAndAddress) {
|
||||
nr_stun_message *msg;
|
||||
ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
|
||||
|
||||
@ -3295,7 +3295,7 @@ TEST_F(PacketFilterTest, TestRecvStunPacketWithPendingIdAndAddress) {
|
||||
ASSERT_EQ(0, nr_stun_message_destroy(&msg));
|
||||
}
|
||||
|
||||
TEST_F(PacketFilterTest, TestSendNonRequestStunPacket) {
|
||||
TEST_F(WebRtcIcePacketFilterTest, TestSendNonRequestStunPacket) {
|
||||
nr_stun_message *msg;
|
||||
ASSERT_EQ(0, nr_stun_build_req_no_auth(NULL, &msg));
|
||||
|
||||
@ -3320,7 +3320,7 @@ TEST_F(PacketFilterTest, TestSendNonRequestStunPacket) {
|
||||
ASSERT_EQ(0, nr_stun_message_destroy(&msg));
|
||||
}
|
||||
|
||||
TEST(InternalsTest, TestAddBogusAttribute) {
|
||||
TEST(WebRtcIceInternalsTest, TestAddBogusAttribute) {
|
||||
nr_stun_message *req;
|
||||
ASSERT_EQ(0, nr_stun_message_create(&req));
|
||||
Data *data;
|
||||
|
@ -4,8 +4,8 @@ set -x -e
|
||||
|
||||
# Inputs, with defaults
|
||||
|
||||
# mozharness builds use three repositories: gecko (source), mozharness (build
|
||||
# scripts) and tools (miscellaneous) for each, specify *_REPOSITORY. If the
|
||||
# mozharness builds use two repositories: gecko (source)
|
||||
# and build-tools (miscellaneous) for each, specify *_REPOSITORY. If the
|
||||
# revision is not in the standard repo for the codebase, specify *_BASE_REPO as
|
||||
# the canonical repo to clone and *_HEAD_REPO as the repo containing the
|
||||
# desired revision. For Mercurial clones, only *_HEAD_REV is required; for Git
|
||||
|
15
testing/docker/desktop-l10n/Dockerfile
Normal file
15
testing/docker/desktop-l10n/Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM taskcluster/centos6-build-upd:0.1.3.20160122142300
|
||||
MAINTAINER Varun Joshi <varunj.1011@gmail.com>
|
||||
|
||||
ADD bin /home/worker/bin
|
||||
ADD .hgrc /home/worker/.hgrc
|
||||
RUN chmod +x /home/worker/bin/*
|
||||
|
||||
# Generate machine uuid file (like how desktop-build does)
|
||||
RUN dbus-uuidgen --ensure=/var/lib/dbus/machine-id
|
||||
|
||||
ADD oauth.txt /home/worker
|
||||
ADD buildprops.json /home/worker
|
||||
ENV MOZ_AUTOMATION=1
|
||||
|
||||
CMD ["/bin/bash", "--login"]
|
26
testing/docker/desktop-l10n/bin/build.sh
Executable file
26
testing/docker/desktop-l10n/bin/build.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#! /bin/bash -vex
|
||||
|
||||
set -x -e -v
|
||||
|
||||
# TODO: when bug 1093833 is solved and tasks can run as non-root, reduce this
|
||||
# to a simple fail-if-root check
|
||||
if [ $(id -u) = 0 ]; then
|
||||
# each of the caches we have mounted are owned by root, so update that ownership
|
||||
# to 'worker'
|
||||
for cache in /home/worker/.tc-vcs /home/worker/workspace /home/worker/tooltool-cache; do
|
||||
# -R probably isn't necessary forever, but it fixes some poisoned
|
||||
# caches for now
|
||||
chown -R worker:worker $cache
|
||||
done
|
||||
|
||||
# ..then drop privileges by re-running this script
|
||||
exec su worker /home/worker/bin/build.sh
|
||||
fi
|
||||
|
||||
####
|
||||
# The default build works for any fx_desktop_build based mozharness job:
|
||||
# via linux-build.sh
|
||||
####
|
||||
|
||||
. $HOME/bin/checkout-sources.sh
|
||||
. $HOME/bin/l10n.sh
|
62
testing/docker/desktop-l10n/bin/checkout-sources.sh
Executable file
62
testing/docker/desktop-l10n/bin/checkout-sources.sh
Executable file
@ -0,0 +1,62 @@
|
||||
#! /bin/bash -vex
|
||||
|
||||
set -x -e
|
||||
|
||||
# Inputs, with defaults
|
||||
|
||||
# mozharness builds use two repositories: gecko (source)
|
||||
# and build-tools (miscellaneous) for each, specify *_REPOSITORY. If the
|
||||
# revision is not in the standard repo for the codebase, specify *_BASE_REPO as
|
||||
# the canonical repo to clone and *_HEAD_REPO as the repo containing the
|
||||
# desired revision. For Mercurial clones, only *_HEAD_REV is required; for Git
|
||||
# clones, specify the branch name to fetch as *_HEAD_REF and the desired sha1
|
||||
# as *_HEAD_REV.
|
||||
|
||||
: GECKO_REPOSITORY ${GECKO_REPOSITORY:=https://hg.mozilla.org/mozilla-central}
|
||||
: GECKO_BASE_REPOSITORY ${GECKO_BASE_REPOSITORY:=${GECKO_REPOSITORY}}
|
||||
: GECKO_HEAD_REPOSITORY ${GECKO_HEAD_REPOSITORY:=${GECKO_REPOSITORY}}
|
||||
: GECKO_HEAD_REV ${GECKO_HEAD_REV:=default}
|
||||
: GECKO_HEAD_REF ${GECKO_HEAD_REF:=${GECKO_HEAD_REV}}
|
||||
|
||||
: TOOLS_REPOSITORY ${TOOLS_REPOSITORY:=https://hg.mozilla.org/build/tools}
|
||||
: TOOLS_BASE_REPOSITORY ${TOOLS_BASE_REPOSITORY:=${TOOLS_REPOSITORY}}
|
||||
: TOOLS_HEAD_REPOSITORY ${TOOLS_HEAD_REPOSITORY:=${TOOLS_REPOSITORY}}
|
||||
: TOOLS_HEAD_REV ${TOOLS_HEAD_REV:=default}
|
||||
: TOOLS_HEAD_REF ${TOOLS_HEAD_REF:=${TOOLS_HEAD_REV}}
|
||||
: TOOLS_DISABLE ${TOOLS_DISABLE:=false}
|
||||
|
||||
: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
|
||||
|
||||
set -v
|
||||
|
||||
# check out tools where mozharness expects it to be ($PWD/build/tools and $WORKSPACE/build/tools)
|
||||
if [ ! "$TOOLS_DISABLE" = true ]
|
||||
then
|
||||
tc-vcs checkout $WORKSPACE/build/tools $TOOLS_BASE_REPOSITORY $TOOLS_HEAD_REPOSITORY $TOOLS_HEAD_REV $TOOLS_HEAD_REF
|
||||
|
||||
if [ ! -d build ]; then
|
||||
mkdir -p build
|
||||
ln -s $WORKSPACE/build/tools build/tools
|
||||
fi
|
||||
fi
|
||||
|
||||
# desktop_l10n.py expects /builds/tooltool.py to be present
|
||||
if ! [ -f /builds/tooltool.py ]
|
||||
then
|
||||
git clone https://github.com/mozilla/build-tooltool
|
||||
cp build-tooltool/tooltool.py /builds
|
||||
fi
|
||||
|
||||
# TODO - include tools repository in EXTRA_CHECKOUT_REPOSITORIES list
|
||||
for extra_repo in $EXTRA_CHECKOUT_REPOSITORIES; do
|
||||
BASE_REPO="${extra_repo}_BASE_REPOSITORY"
|
||||
HEAD_REPO="${extra_repo}_HEAD_REPOSITORY"
|
||||
HEAD_REV="${extra_repo}_HEAD_REV"
|
||||
HEAD_REF="${extra_repo}_HEAD_REF"
|
||||
DEST_DIR="${extra_repo}_DEST_DIR"
|
||||
|
||||
tc-vcs checkout ${!DEST_DIR} ${!BASE_REPO} ${!HEAD_REPO} ${!HEAD_REV} ${!HEAD_REF}
|
||||
done
|
||||
|
||||
export GECKO_DIR=$WORKSPACE/build/mozilla-central
|
||||
tc-vcs checkout $GECKO_DIR $GECKO_BASE_REPOSITORY $GECKO_HEAD_REPOSITORY $GECKO_HEAD_REV $GECKO_HEAD_REF
|
9
testing/docker/desktop-l10n/buildprops.json
Normal file
9
testing/docker/desktop-l10n/buildprops.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"properties": {
|
||||
"buildername": ""
|
||||
},
|
||||
"sourcestamp": {
|
||||
"changes": []
|
||||
},
|
||||
"comments": "TaskCluster Job"
|
||||
}
|
2
testing/docker/desktop-l10n/oauth.txt
Normal file
2
testing/docker/desktop-l10n/oauth.txt
Normal file
@ -0,0 +1,2 @@
|
||||
taskcluster_clientId = None
|
||||
taskcluster_accessToken = None
|
@ -94,6 +94,7 @@ config = {
|
||||
},
|
||||
},
|
||||
'mozilla-beta': {
|
||||
'enable_release_promotion': 1,
|
||||
'repo_path': 'releases/mozilla-beta',
|
||||
# TODO I think we can remove update_channel since we don't run
|
||||
# nightlies for mozilla-beta
|
||||
@ -102,6 +103,21 @@ config = {
|
||||
'use_branch_in_symbols_extra_buildid': False,
|
||||
'stage_server': 'upload.ffxbld.productdelivery.prod.mozaws.net',
|
||||
'platform_overrides': {
|
||||
'linux': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/linux32/beta',
|
||||
},
|
||||
'linux64': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/linux64/beta',
|
||||
},
|
||||
'macosx64': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/macosx-universal/beta',
|
||||
},
|
||||
'win32': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/win32/beta',
|
||||
},
|
||||
'win64': {
|
||||
'src_mozconfig': 'browser/config/mozconfigs/win64/beta',
|
||||
},
|
||||
'linux-debug': {
|
||||
'update_channel': 'default',
|
||||
},
|
||||
|
44
testing/mozharness/configs/single_locale/mozilla-beta.py
Normal file
44
testing/mozharness/configs/single_locale/mozilla-beta.py
Normal file
@ -0,0 +1,44 @@
|
||||
config = {
|
||||
"nightly_build": True,
|
||||
"branch": "mozilla-beta",
|
||||
"en_us_binary_url": "http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-beta/",
|
||||
"update_channel": "beta",
|
||||
"latest_mar_dir": '/pub/mozilla.org/firefox/nightly/latest-mozilla-beta-l10n',
|
||||
|
||||
# l10n
|
||||
"hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-beta",
|
||||
|
||||
# mar
|
||||
# No nightly on beta, using aurora mar tools
|
||||
"mar_tools_url": "http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-aurora/mar-tools/%(platform)s",
|
||||
|
||||
# repositories
|
||||
"mozilla_dir": "mozilla-beta",
|
||||
"repos": [{
|
||||
"vcs": "hg",
|
||||
"repo": "https://hg.mozilla.org/build/tools",
|
||||
"revision": "default",
|
||||
"dest": "tools",
|
||||
}, {
|
||||
"vcs": "hgtool",
|
||||
"repo": "https://hg.mozilla.org/releases/mozilla-beta",
|
||||
"revision": "default",
|
||||
"dest": "mozilla-beta",
|
||||
}, {
|
||||
"vcs": "hgtool",
|
||||
"repo": "https://hg.mozilla.org/build/compare-locales",
|
||||
"revision": "RELEASE_AUTOMATION"
|
||||
}],
|
||||
# purge options
|
||||
'purge_minsize': 12,
|
||||
'is_automation': True,
|
||||
'default_actions': [
|
||||
"clobber",
|
||||
"pull",
|
||||
"list-locales",
|
||||
"setup",
|
||||
"repack",
|
||||
"taskcluster-upload",
|
||||
"summary",
|
||||
],
|
||||
}
|
@ -1576,15 +1576,20 @@ SpecialPowersAPI.prototype = {
|
||||
getService(Components.interfaces.nsICategoryManager).
|
||||
deleteCategoryEntry(category, entry, persists);
|
||||
},
|
||||
|
||||
openDialog: function(win, args) {
|
||||
return win.openDialog.apply(win, args);
|
||||
},
|
||||
// This is a blocking call which creates and spins a native event loop
|
||||
spinEventLoop: function(win) {
|
||||
// simply do a sync XHR back to our windows location.
|
||||
var syncXHR = new win.XMLHttpRequest();
|
||||
syncXHR.open('GET', win.location, false);
|
||||
syncXHR.send();
|
||||
},
|
||||
|
||||
// :jdm gets credit for this. ex: getPrivilegedProps(window, 'location.href');
|
||||
getPrivilegedProps: function(obj, props) {
|
||||
var parts = props.split('.');
|
||||
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var p = parts[i];
|
||||
if (obj[p]) {
|
||||
|
@ -5,54 +5,69 @@
|
||||
|
||||
[XMLHttpRequest: responseXML MIME type tests ('', should parse)]
|
||||
expected:
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
|
||||
[XMLHttpRequest: responseXML MIME type tests ('bogus', should parse)]
|
||||
expected:
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
|
||||
[XMLHttpRequest: responseXML MIME type tests ('bogus+xml', should parse)]
|
||||
expected:
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
|
||||
[XMLHttpRequest: responseXML MIME type tests ('application', should parse)]
|
||||
expected:
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
|
||||
|
@ -2,15 +2,19 @@
|
||||
type: testharness
|
||||
[XMLHttpRequest: send() - Redirects (bogus Location header) (302: mailto:someone@example.org)]
|
||||
expected:
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.2") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.1.7601") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and e10s and (os == "win") and (version == "6.2.9200") and (processor == "x86_64") and (bits == 64): FAIL
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
expected: TIMEOUT
|
||||
[In-policy async video src]
|
||||
expected:
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
||||
[in-policy async video src w/redir]
|
||||
@ -11,11 +13,15 @@
|
||||
|
||||
[In-policy async video source element]
|
||||
expected:
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL
|
||||
|
||||
[In-policy async video source element w/redir]
|
||||
expected:
|
||||
if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): NOTRUN
|
||||
if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): NOTRUN
|
||||
if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): NOTRUN
|
||||
if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): NOTRUN
|
||||
|
||||
|
@ -156,7 +156,15 @@ function backgroundScript() {
|
||||
}).then(results => {
|
||||
browser.test.assertTrue(results.length >= 9, "At least as many bookmarks as added were returned by search({})");
|
||||
|
||||
return browser.bookmarks.getSubTree(createdFolderId);
|
||||
return Promise.resolve().then(() => {
|
||||
return browser.bookmarks.remove(createdFolderId);
|
||||
}).then(expectedError, error => {
|
||||
browser.test.assertTrue(
|
||||
error.message.includes("Cannot remove a non-empty folder"),
|
||||
"Expected error thrown when trying to remove a non-empty folder"
|
||||
);
|
||||
return browser.bookmarks.getSubTree(createdFolderId);
|
||||
});
|
||||
});
|
||||
}).then(results => {
|
||||
browser.test.assertEq(1, results.length, "Expected number of nodes returned by getSubTree");
|
||||
@ -334,9 +342,37 @@ function backgroundScript() {
|
||||
browser.test.assertEq("Toolbar Item", results[3].title, "Bookmark has the expected title");
|
||||
browser.test.assertEq("Menu Item", results[4].title, "Bookmark has the expected title");
|
||||
|
||||
return browser.bookmarks.search({});
|
||||
}).then(results => {
|
||||
let startBookmarkCount = results.length;
|
||||
return browser.bookmarks.search({title: "Mozilla Folder"}).then(result => {
|
||||
return browser.bookmarks.removeTree(result[0].id);
|
||||
}).then(() => {
|
||||
return browser.bookmarks.search({}).then(results => {
|
||||
browser.test.assertEq(
|
||||
startBookmarkCount - 4,
|
||||
results.length,
|
||||
"Expected number of results returned after removeTree");
|
||||
});
|
||||
});
|
||||
}).then(() => {
|
||||
return browser.bookmarks.create({title: "Empty Folder"});
|
||||
}).then(result => {
|
||||
let emptyFolderId = result.id;
|
||||
browser.test.assertEq("Empty Folder", result.title, "Folder has the expected title");
|
||||
return browser.bookmarks.remove(emptyFolderId).then(() => {
|
||||
return browser.bookmarks.get(emptyFolderId).then(expectedError, error => {
|
||||
browser.test.assertTrue(
|
||||
error.message.includes("Bookmark not found"),
|
||||
"Expected error thrown when trying to get a removed folder"
|
||||
);
|
||||
});
|
||||
});
|
||||
}).then(() => {
|
||||
return browser.test.notifyPass("bookmarks");
|
||||
}).catch(error => {
|
||||
browser.test.fail(`Error: ${String(error)} :: ${error.stack}`);
|
||||
browser.test.notifyFail("bookmarks");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -132,12 +132,108 @@ function backgroundScript() {
|
||||
sendHeaders: [],
|
||||
responseStarted: [],
|
||||
completed: []};
|
||||
let testHeaders = {
|
||||
request: {
|
||||
added: {
|
||||
"X-WebRequest-request": "text",
|
||||
"X-WebRequest-request-binary": "binary",
|
||||
},
|
||||
modified: {
|
||||
"User-Agent": "WebRequest",
|
||||
},
|
||||
deleted: [
|
||||
"Referer",
|
||||
],
|
||||
},
|
||||
response: {
|
||||
added: {
|
||||
"X-WebRequest-response": "text",
|
||||
"X-WebRequest-response-binary": "binary",
|
||||
},
|
||||
modified: {
|
||||
"Server": "WebRequest",
|
||||
},
|
||||
deleted: [
|
||||
"Connection",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
function checkResourceType(type) {
|
||||
let key = type.toUpperCase();
|
||||
browser.test.assertTrue(key in browser.webRequest.ResourceType, `valid resource type ${key}`);
|
||||
}
|
||||
|
||||
function processHeaders(phase, details) {
|
||||
let headers = details[`${phase}Headers`];
|
||||
browser.test.assertTrue(Array.isArray(headers), `${phase}Headers array present`);
|
||||
|
||||
let processedMark = "WebRequest-processed";
|
||||
if (headers.find(h => h.name === processedMark)) {
|
||||
// This may happen because of redirections or cache
|
||||
browser.test.log(`${phase}Headers in ${details.requestId} already processed`);
|
||||
return null;
|
||||
}
|
||||
headers.push({name: processedMark, value: "1"});
|
||||
|
||||
let {added, modified, deleted} = testHeaders[phase];
|
||||
|
||||
for (let name in added) {
|
||||
browser.test.assertTrue(!headers.find(h => h.name === name), `header ${name} to be added not present yet in ${phase}Headers`);
|
||||
let header = {name: name};
|
||||
if (name.endsWith("-binary")) {
|
||||
header.binaryValue = Array.from(added[name], c => c.charCodeAt(0));
|
||||
} else {
|
||||
header.value = added[name];
|
||||
}
|
||||
headers.push(header);
|
||||
}
|
||||
|
||||
let modifiedAny = false;
|
||||
for (let header of headers.filter(h => h.name in modified)) {
|
||||
header.value = modified[header.name];
|
||||
modifiedAny = true;
|
||||
}
|
||||
browser.test.assertTrue(modifiedAny, `at least one ${phase}Headers element to modify`);
|
||||
|
||||
let deletedAny = false;
|
||||
for (let j = headers.length; j-- > 0;) {
|
||||
if (deleted.includes(headers[j].name)) {
|
||||
headers.splice(j, 1);
|
||||
deletedAny = true;
|
||||
}
|
||||
}
|
||||
browser.test.assertTrue(deletedAny, `at least one ${phase}Headers element to delete`);
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
function checkHeaders(phase, details) {
|
||||
if (!/^https?:/.test(details.url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let headers = details[`${phase}Headers`];
|
||||
browser.test.assertTrue(Array.isArray(headers), `valid ${phase}Headers array`);
|
||||
|
||||
let {added, modified, deleted} = testHeaders[phase];
|
||||
for (let name in added) {
|
||||
browser.test.assertTrue(headers.some(h => h.name === name && h.value === added[name]), `header ${name} correctly injected in ${phase}Headers`);
|
||||
}
|
||||
|
||||
let modifiedAny = false;
|
||||
for (let header of headers.filter(h => h.name in modified)) {
|
||||
let {name, value} = header;
|
||||
browser.test.assertTrue(value === modified[name], `header "${name}: ${value}" matches modified value ("${modified[name]}")`);
|
||||
modifiedAny = true;
|
||||
}
|
||||
browser.test.assertTrue(modifiedAny, `at least one modified ${phase}Headers element`);
|
||||
|
||||
for (let name of deleted) {
|
||||
browser.test.assertFalse(headers.some(h => h.name === name), `deleted header ${name} still found in ${phase}Headers`);
|
||||
}
|
||||
}
|
||||
|
||||
function onBeforeRequest(details) {
|
||||
browser.test.log(`onBeforeRequest ${details.requestId} ${details.url}`);
|
||||
|
||||
@ -181,6 +277,7 @@ function backgroundScript() {
|
||||
browser.test.log(`onBeforeSendHeaders ${details.url}`);
|
||||
checkRequestId(details);
|
||||
checkResourceType(details.type);
|
||||
processHeaders("request", details);
|
||||
if (shouldRecord(details.url)) {
|
||||
recorded.beforeSendHeaders.push(details.url);
|
||||
|
||||
@ -193,7 +290,7 @@ function backgroundScript() {
|
||||
if (details.url.indexOf("_redirect.") != -1) {
|
||||
return {redirectUrl: details.url.replace("_redirect.", "_good.")};
|
||||
}
|
||||
return {};
|
||||
return {requestHeaders: details.requestHeaders};
|
||||
}
|
||||
|
||||
function onBeforeRedirect(details) {
|
||||
@ -218,24 +315,28 @@ function backgroundScript() {
|
||||
}
|
||||
|
||||
function onRecord(kind, details) {
|
||||
browser.test.log(`${kind} ${details.url}`);
|
||||
browser.test.log(`${kind} ${details.requestId} ${details.url}`);
|
||||
checkResourceType(details.type);
|
||||
checkRequestId(details, kind);
|
||||
if (shouldRecord(details.url)) {
|
||||
if (kind in recorded && shouldRecord(details.url)) {
|
||||
recorded[kind].push(details.url);
|
||||
}
|
||||
}
|
||||
|
||||
let completedUrls = {
|
||||
responseStarted: new Set(),
|
||||
completed: new Set(),
|
||||
};
|
||||
function onSendHeaders(details) {
|
||||
onRecord("sendHeaders", details);
|
||||
checkHeaders("request", details);
|
||||
}
|
||||
|
||||
let completedUrls = {};
|
||||
|
||||
function checkIpAndRecord(kind, details) {
|
||||
onRecord(kind, details);
|
||||
|
||||
// When resources are cached, the ip property is not present,
|
||||
// so only check for the ip property the first time around.
|
||||
if (!(kind in completedUrls)) {
|
||||
completedUrls[kind] = new Set();
|
||||
}
|
||||
if (checkCompleted && !completedUrls[kind].has(details.url)) {
|
||||
// We can only tell IPs for HTTP requests.
|
||||
if (/^https?:/.test(details.url)) {
|
||||
@ -245,12 +346,25 @@ function backgroundScript() {
|
||||
}
|
||||
}
|
||||
|
||||
function onHeadersReceived(details) {
|
||||
checkIpAndRecord("headersReceived", details);
|
||||
processHeaders("response", details);
|
||||
browser.test.log(`After processing response headers: ${details.responseHeaders.toSource()}`);
|
||||
return {responseHeaders: details.responseHeaders};
|
||||
}
|
||||
|
||||
function onCompleted(details) {
|
||||
checkIpAndRecord("completed", details);
|
||||
checkHeaders("response", details);
|
||||
}
|
||||
|
||||
browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, {urls: ["<all_urls>"]}, ["blocking"]);
|
||||
browser.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, {urls: ["<all_urls>"]}, ["blocking"]);
|
||||
browser.webRequest.onSendHeaders.addListener(onRecord.bind(null, "sendHeaders"), {urls: ["<all_urls>"]});
|
||||
browser.webRequest.onBeforeSendHeaders.addListener(onBeforeSendHeaders, {urls: ["<all_urls>"]}, ["blocking", "requestHeaders"]);
|
||||
browser.webRequest.onSendHeaders.addListener(onSendHeaders, {urls: ["<all_urls>"]}, ["requestHeaders"]);
|
||||
browser.webRequest.onBeforeRedirect.addListener(onBeforeRedirect, {urls: ["<all_urls>"]});
|
||||
browser.webRequest.onHeadersReceived.addListener(onHeadersReceived, {urls: ["<all_urls>"]}, ["blocking", "responseHeaders"]);
|
||||
browser.webRequest.onResponseStarted.addListener(checkIpAndRecord.bind(null, "responseStarted"), {urls: ["<all_urls>"]});
|
||||
browser.webRequest.onCompleted.addListener(checkIpAndRecord.bind(null, "completed"), {urls: ["<all_urls>"]});
|
||||
browser.webRequest.onCompleted.addListener(onCompleted, {urls: ["<all_urls>"]}, ["responseHeaders"]);
|
||||
|
||||
function onTestMessage(msg) {
|
||||
if (msg == "skipCompleted") {
|
||||
|
@ -372,13 +372,18 @@ var Bookmarks = Object.freeze({
|
||||
* @param guidOrInfo
|
||||
* The globally unique identifier of the item to remove, or an
|
||||
* object representing it, as defined above.
|
||||
* @param {Object} [options={}]
|
||||
* Additional options that can be passed to the function.
|
||||
* Currently supports preventRemovalOfNonEmptyFolders which
|
||||
* will cause an exception to be thrown if attempting to remove
|
||||
* a folder that is not empty.
|
||||
*
|
||||
* @return {Promise} resolved when the removal is complete.
|
||||
* @resolves to an object representing the removed bookmark.
|
||||
* @rejects if the provided guid doesn't match any existing bookmark.
|
||||
* @throws if the arguments are invalid.
|
||||
*/
|
||||
remove(guidOrInfo) {
|
||||
remove(guidOrInfo, options={}) {
|
||||
let info = guidOrInfo;
|
||||
if (!info)
|
||||
throw new Error("Input should be a valid object");
|
||||
@ -400,7 +405,7 @@ var Bookmarks = Object.freeze({
|
||||
if (!item)
|
||||
throw new Error("No bookmarks found for the provided GUID.");
|
||||
|
||||
item = yield removeBookmark(item);
|
||||
item = yield removeBookmark(item, options);
|
||||
|
||||
// Notify onItemRemoved to listeners.
|
||||
let observers = PlacesUtils.bookmarks.getObservers();
|
||||
@ -1068,7 +1073,7 @@ function fetchBookmarksByParent(info) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Remove implementation.
|
||||
|
||||
function removeBookmark(item) {
|
||||
function removeBookmark(item, options) {
|
||||
return PlacesUtils.withConnectionWrapper("Bookmarks.jsm: updateBookmark",
|
||||
Task.async(function*(db) {
|
||||
|
||||
@ -1076,8 +1081,12 @@ function removeBookmark(item) {
|
||||
|
||||
yield db.executeTransaction(function* transaction() {
|
||||
// If it's a folder, remove its contents first.
|
||||
if (item.type == Bookmarks.TYPE_FOLDER)
|
||||
if (item.type == Bookmarks.TYPE_FOLDER) {
|
||||
if (options.preventRemovalOfNonEmptyFolders && item._childCount > 0) {
|
||||
throw new Error("Cannot remove a non-empty folder.");
|
||||
}
|
||||
yield removeFoldersContents(db, [item.guid]);
|
||||
}
|
||||
|
||||
// Remove annotations first. If it's a tag, we can avoid paying that cost.
|
||||
if (!isUntagging) {
|
||||
|
@ -55,7 +55,7 @@ add_task(function* remove_roots_fail() {
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* remove_normal_folder_undes_root_succeeds() {
|
||||
add_task(function* remove_normal_folder_under_root_succeeds() {
|
||||
let folder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.rootGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER });
|
||||
checkBookmarkObject(folder);
|
||||
@ -151,6 +151,7 @@ add_task(function* test_nested_contents_removed() {
|
||||
Assert.strictEqual((yield PlacesUtils.bookmarks.fetch(folder2.guid)), null);
|
||||
Assert.strictEqual((yield PlacesUtils.bookmarks.fetch(sep.guid)), null);
|
||||
});
|
||||
|
||||
add_task(function* remove_folder_empty_title() {
|
||||
let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
@ -182,6 +183,17 @@ add_task(function* remove_separator() {
|
||||
Assert.ok(!("title" in bm2));
|
||||
});
|
||||
|
||||
add_task(function* test_nested_content_fails_when_not_allowed() {
|
||||
let folder1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
let folder2 = yield PlacesUtils.bookmarks.insert({ parentGuid: folder1.guid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "a folder" });
|
||||
Assert.rejects(PlacesUtils.bookmarks.remove(folder1, {preventRemovalOfNonEmptyFolders: true}),
|
||||
/Cannot remove a non-empty folder./);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
@ -340,6 +340,36 @@ HttpObserverManager = {
|
||||
return headers;
|
||||
},
|
||||
|
||||
replaceHeaders(headers, originalNames, setHeader) {
|
||||
let failures = new Set();
|
||||
// Start by clearing everything.
|
||||
for (let name of originalNames) {
|
||||
try {
|
||||
setHeader(name, "");
|
||||
} catch (e) {
|
||||
// Let's collect physiological failures in order
|
||||
// to know what is worth reporting.
|
||||
failures.add(name);
|
||||
}
|
||||
}
|
||||
try {
|
||||
for (let {name, value, binaryValue} of headers) {
|
||||
try {
|
||||
if (Array.isArray(binaryValue)) {
|
||||
value = String.fromCharCode.apply(String, binaryValue);
|
||||
}
|
||||
setHeader(name, value);
|
||||
} catch (e) {
|
||||
if (!failures.has(name)) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
switch (topic) {
|
||||
@ -370,8 +400,8 @@ HttpObserverManager = {
|
||||
loadInfo.externalContentPolicyType :
|
||||
Ci.nsIContentPolicy.TYPE_OTHER;
|
||||
|
||||
let requestHeaders;
|
||||
let responseHeaders;
|
||||
let requestHeaderNames;
|
||||
let responseHeaderNames;
|
||||
|
||||
let includeStatus = kind === "headersReceived" ||
|
||||
kind === "onBeforeRedirect" ||
|
||||
@ -405,16 +435,12 @@ HttpObserverManager = {
|
||||
Object.assign(data, extraData);
|
||||
}
|
||||
if (opts.requestHeaders) {
|
||||
if (!requestHeaders) {
|
||||
requestHeaders = this.getHeaders(channel, "visitRequestHeaders");
|
||||
}
|
||||
data.requestHeaders = requestHeaders;
|
||||
data.requestHeaders = this.getHeaders(channel, "visitRequestHeaders");
|
||||
requestHeaderNames = data.requestHeaders.map(h => h.name);
|
||||
}
|
||||
if (opts.responseHeaders) {
|
||||
if (!responseHeaders) {
|
||||
responseHeaders = this.getHeaders(channel, "visitResponseHeaders");
|
||||
}
|
||||
data.responseHeaders = responseHeaders;
|
||||
data.responseHeaders = this.getHeaders(channel, "visitResponseHeaders");
|
||||
responseHeaderNames = data.responseHeaders.map(h => h.name);
|
||||
}
|
||||
if (includeStatus) {
|
||||
data.statusCode = channel.responseStatus;
|
||||
@ -439,24 +465,16 @@ HttpObserverManager = {
|
||||
return false;
|
||||
}
|
||||
if (opts.requestHeaders && result.requestHeaders) {
|
||||
// Start by clearing everything.
|
||||
for (let {name} of requestHeaders) {
|
||||
channel.setRequestHeader(name, "", false);
|
||||
}
|
||||
|
||||
for (let {name, value} of result.requestHeaders) {
|
||||
channel.setRequestHeader(name, value, false);
|
||||
}
|
||||
this.replaceHeaders(
|
||||
result.requestHeaders, requestHeaderNames,
|
||||
(name, value) => channel.setRequestHeader(name, value, false)
|
||||
);
|
||||
}
|
||||
if (opts.responseHeaders && result.responseHeaders) {
|
||||
// Start by clearing everything.
|
||||
for (let {name} of responseHeaders) {
|
||||
channel.setResponseHeader(name, "", false);
|
||||
}
|
||||
|
||||
for (let {name, value} of result.responseHeaders) {
|
||||
channel.setResponseHeader(name, value, false);
|
||||
}
|
||||
this.replaceHeaders(
|
||||
result.responseHeaders, responseHeaderNames,
|
||||
(name, value) => channel.setResponseHeader(name, value, false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,7 @@ skip-if = true # Bug 1084646
|
||||
[browser_navigateaway.js]
|
||||
[browser_navigateaway2.js]
|
||||
[browser_navigateaway3.js]
|
||||
skip-if = (os == "mac" || os == "win") # Bug 1198261
|
||||
[browser_navigateaway4.js]
|
||||
[browser_offline.js]
|
||||
[browser_relative.js]
|
||||
|
Loading…
Reference in New Issue
Block a user