mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
Merge m-c to birch
This commit is contained in:
commit
16f24f3138
@ -556,10 +556,13 @@ pref("javascript.options.mem.log", false);
|
||||
// Increase mark slice time from 10ms to 30ms
|
||||
pref("javascript.options.mem.gc_incremental_slice_ms", 30);
|
||||
|
||||
pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 150);
|
||||
// Increase time to get more high frequency GC on benchmarks from 1000ms to 1500ms
|
||||
pref("javascript.options.mem.gc_high_frequency_time_limit_ms", 1500);
|
||||
|
||||
pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 300);
|
||||
pref("javascript.options.mem.gc_high_frequency_heap_growth_min", 120);
|
||||
pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 40);
|
||||
pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 10);
|
||||
pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 0);
|
||||
pref("javascript.options.mem.gc_low_frequency_heap_growth", 120);
|
||||
pref("javascript.options.mem.high_water_mark", 6);
|
||||
pref("javascript.options.mem.gc_allocation_threshold_mb", 1);
|
||||
|
@ -284,7 +284,7 @@ documenttab[selected] .documenttab-selection {
|
||||
list-style-image: url(chrome://browser/skin/images/appbar-forward@1.4x.png);
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
/* URL bar */
|
||||
#urlbar-container {
|
||||
border: @metro_border_thick@ solid @urlbar_border_color@;
|
||||
|
37
client.py
37
client.py
@ -95,6 +95,31 @@ def toggle_trailing_blank_line(depname):
|
||||
# adding blank line
|
||||
open(depname, "ab").write("\n")
|
||||
|
||||
def get_trailing_blank_line_state(depname):
|
||||
lines = open(depname, "r").readlines()
|
||||
if not lines:
|
||||
print >>sys.stderr, "unexpected short file"
|
||||
return "no blank line"
|
||||
|
||||
if not lines[-1].strip():
|
||||
return "has blank line"
|
||||
else:
|
||||
return "no blank line"
|
||||
|
||||
def update_nspr_or_nss(tag, depfile, destination, hgpath):
|
||||
print "reverting to HG version of %s to get its blank line state" % depfile
|
||||
check_call_noisy([options.hg, 'revert', depfile])
|
||||
old_state = get_trailing_blank_line_state(depfile)
|
||||
print "old state of %s is: %s" % (depfile, old_state)
|
||||
do_hg_replace(destination, hgpath, tag, HG_EXCLUSIONS, options.hg)
|
||||
new_state = get_trailing_blank_line_state(depfile)
|
||||
print "new state of %s is: %s" % (depfile, new_state)
|
||||
if old_state == new_state:
|
||||
print "toggling blank line in: ", depfile
|
||||
toggle_trailing_blank_line(depfile)
|
||||
tag_file = destination + "/TAG-INFO"
|
||||
print >>file(tag_file, "w"), tag
|
||||
|
||||
o = OptionParser(usage="client.py [options] update_nspr tagname | update_nss tagname | update_libffi tagname | update_webidlparser tagname")
|
||||
o.add_option("--skip-mozilla", dest="skip_mozilla",
|
||||
action="store_true", default=False,
|
||||
@ -119,16 +144,12 @@ if action in ('checkout', 'co'):
|
||||
pass
|
||||
elif action in ('update_nspr'):
|
||||
tag, = args[1:]
|
||||
do_hg_replace('nsprpub', 'https://hg.mozilla.org/projects/nspr',
|
||||
tag, HG_EXCLUSIONS, options.hg)
|
||||
print >>file("nsprpub/TAG-INFO", "w"), tag
|
||||
toggle_trailing_blank_line("nsprpub/config/prdepend.h")
|
||||
depfile = "nsprpub/config/prdepend.h"
|
||||
update_nspr_or_nss(tag, depfile, 'nsprpub', 'https://hg.mozilla.org/projects/nspr')
|
||||
elif action in ('update_nss'):
|
||||
tag, = args[1:]
|
||||
do_hg_replace('security/nss', 'https://hg.mozilla.org/projects/nss',
|
||||
tag, HG_EXCLUSIONS, options.hg)
|
||||
print >>file("security/nss/TAG-INFO", "w"), tag
|
||||
toggle_trailing_blank_line("security/nss/coreconf/coreconf.dep")
|
||||
depfile = "security/nss/coreconf/coreconf.dep"
|
||||
update_nspr_or_nss(tag, depfile, 'security/nss', 'https://hg.mozilla.org/projects/nss')
|
||||
elif action in ('update_libffi'):
|
||||
tag, = args[1:]
|
||||
if not options.cvsroot:
|
||||
|
@ -1182,23 +1182,14 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# need 3 separate lines for OS/2
|
||||
%:: %.pl
|
||||
$(RM) $@
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
|
||||
%:: %.sh
|
||||
$(RM) $@
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
|
||||
# Cancel these implicit rules
|
||||
#
|
||||
%: %,v
|
||||
|
||||
%: RCS/%,v
|
||||
|
||||
%: RCS/%
|
||||
|
||||
%: s.%
|
||||
|
||||
%: SCCS/s.%
|
||||
|
@ -444,7 +444,7 @@ ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDa
|
||||
nsDOMTokenList* classList = mImageContent->AsElement()->GetClassList();
|
||||
mozilla::ErrorResult rv;
|
||||
if (aType == imgINotificationObserver::DECODE_COMPLETE) {
|
||||
if (mImageContent) {
|
||||
if (mImageContent && !nsContentUtils::IsChildOfSameType(this)) {
|
||||
// Update the background-color of the image only after the
|
||||
// image has been decoded to prevent flashes of just the
|
||||
// background-color.
|
||||
@ -455,7 +455,7 @@ ImageDocument::Notify(imgIRequest* aRequest, int32_t aType, const nsIntRect* aDa
|
||||
|
||||
if (aType == imgINotificationObserver::DISCARD) {
|
||||
// mImageContent can be null if the document is already destroyed
|
||||
if (mImageContent) {
|
||||
if (mImageContent && !nsContentUtils::IsChildOfSameType(this)) {
|
||||
// Remove any decoded-related styling when the image is unloaded.
|
||||
classList->Remove(NS_LITERAL_STRING("decoded"), rv);
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
|
||||
|
@ -18,7 +18,6 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGAnimatedLength)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAnimatedLength)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedLength)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsIDOMSVGAnimatedLength.h"
|
||||
|
||||
class nsSVGLength2;
|
||||
class nsIDOMSVGLength;
|
||||
@ -16,7 +15,7 @@ class nsIDOMSVGLength;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class SVGAnimatedLength MOZ_FINAL : public nsIDOMSVGAnimatedLength,
|
||||
class SVGAnimatedLength MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
@ -29,12 +28,6 @@ public:
|
||||
|
||||
~SVGAnimatedLength();
|
||||
|
||||
NS_IMETHOD GetBaseVal(nsIDOMSVGLength **aBaseVal) MOZ_OVERRIDE
|
||||
{ *aBaseVal = BaseVal().get(); return NS_OK; }
|
||||
|
||||
NS_IMETHOD GetAnimVal(nsIDOMSVGLength **aAnimVal) MOZ_OVERRIDE
|
||||
{ *aAnimVal = AnimVal().get(); return NS_OK; }
|
||||
|
||||
// WebIDL
|
||||
nsSVGElement* GetParentObject() { return mSVGElement; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "nsISVGPoint.h"
|
||||
#include "nsSVGTextContainerFrame.h"
|
||||
#include "nsSVGTextFrame2.h"
|
||||
#include "nsIDOMSVGAnimatedLength.h"
|
||||
#include "mozilla/dom/SVGIRect.h"
|
||||
#include "nsIDOMSVGAnimatedEnum.h"
|
||||
|
||||
|
@ -471,14 +471,6 @@ nsSVGLength2::SetAnimValue(float aValue, nsSVGElement *aSVGElement)
|
||||
aSVGElement);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGLength2::ToDOMAnimatedLength(nsIDOMSVGAnimatedLength **aResult,
|
||||
nsSVGElement *aSVGElement)
|
||||
{
|
||||
*aResult = ToDOMAnimatedLength(aSVGElement).get();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<SVGAnimatedLength>
|
||||
nsSVGLength2::ToDOMAnimatedLength(nsSVGElement* aSVGElement)
|
||||
{
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsCoord.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIDOMSVGAnimatedLength.h"
|
||||
#include "nsIDOMSVGLength.h"
|
||||
#include "nsISMILAttr.h"
|
||||
#include "nsMathUtils.h"
|
||||
@ -89,9 +88,6 @@ public:
|
||||
// useable, and represents the default base value of the attribute.
|
||||
bool IsExplicitlySet() const
|
||||
{ return mIsAnimated || mIsBaseSet; }
|
||||
|
||||
nsresult ToDOMAnimatedLength(nsIDOMSVGAnimatedLength **aResult,
|
||||
nsSVGElement* aSVGElement);
|
||||
|
||||
already_AddRefed<mozilla::dom::SVGAnimatedLength>
|
||||
ToDOMAnimatedLength(nsSVGElement* aSVGElement);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "Connection.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#ifdef MOZ_B2G_RIL
|
||||
#include "IccManager.h"
|
||||
#include "MobileConnection.h"
|
||||
|
@ -7,7 +7,6 @@
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMSVGAnimatedEnum.idl',
|
||||
'nsIDOMSVGAnimatedInteger.idl',
|
||||
'nsIDOMSVGAnimatedLength.idl',
|
||||
'nsIDOMSVGAnimatedNumber.idl',
|
||||
'nsIDOMSVGElement.idl',
|
||||
'nsIDOMSVGLength.idl',
|
||||
|
@ -1,16 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIDOMSVGLength;
|
||||
|
||||
[scriptable, uuid(a52f0322-7f4d-418d-af6d-a7b14abd5cdf)]
|
||||
interface nsIDOMSVGAnimatedLength : nsISupports
|
||||
{
|
||||
readonly attribute nsIDOMSVGLength baseVal;
|
||||
readonly attribute nsIDOMSVGLength animVal;
|
||||
};
|
||||
|
@ -11,6 +11,11 @@ relativesrcdir = @relativesrcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_FILES = \
|
||||
test_dataChannel_basicAudio.html \
|
||||
test_dataChannel_basicAudioVideo.html \
|
||||
test_dataChannel_basicAudioVideoCombined.html \
|
||||
test_dataChannel_basicDataOnly.html \
|
||||
test_dataChannel_basicVideo.html \
|
||||
test_dataChannel_noOffer.html \
|
||||
test_getUserMedia_exceptions.html \
|
||||
test_getUserMedia_basicAudio.html \
|
||||
@ -50,6 +55,7 @@ MOCHITEST_FILES = \
|
||||
head.js \
|
||||
mediaStreamPlayback.js \
|
||||
pc.js \
|
||||
templates.js \
|
||||
$(NULL)
|
||||
|
||||
# The following tests are leaking and cannot be run by default yet
|
||||
|
@ -165,6 +165,29 @@ function checkMediaStreamTracks(constraints, mediaStream) {
|
||||
mediaStream.getVideoTracks());
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the contents of a blob as text
|
||||
*
|
||||
* @param {Blob} blob
|
||||
The blob to retrieve the contents from
|
||||
* @param {Function} onSuccess
|
||||
Callback with the blobs content as parameter
|
||||
*/
|
||||
function getBlobContent(blob, onSuccess) {
|
||||
var reader = new FileReader();
|
||||
|
||||
// Listen for 'onloadend' which will always be called after a success or failure
|
||||
reader.onloadend = function (event) {
|
||||
onSuccess(event.target.result);
|
||||
};
|
||||
|
||||
reader.readAsText(blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a callback function fired only under unexpected circumstances
|
||||
* while running the tests. The generated function kills off the test as well
|
||||
|
@ -11,11 +11,13 @@
|
||||
* @param {object} framework
|
||||
* A back reference to the framework which makes use of the class. It's
|
||||
* getting passed in as parameter to each command callback.
|
||||
* @param {Array[]} [commandList=[]]
|
||||
* Default commands to set during initialization
|
||||
*/
|
||||
function CommandChain(framework) {
|
||||
function CommandChain(framework, commandList) {
|
||||
this._framework = framework;
|
||||
|
||||
this._commands = [ ];
|
||||
this._commands = commandList || [ ];
|
||||
this._current = 0;
|
||||
|
||||
this.onFinished = null;
|
||||
@ -225,119 +227,14 @@ CommandChain.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default list of commands to execute for a PeerConnection test.
|
||||
*/
|
||||
var commandsPeerConnection = [
|
||||
[
|
||||
'PC_LOCAL_GUM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
test.pcRemote.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_CHECK_INITIAL_SIGNALINGSTATE',
|
||||
function (test) {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Initial local signalingState is 'stable'");
|
||||
is(test.pcRemote.signalingState, "stable",
|
||||
"Initial remote signalingState is 'stable'");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
function (test) {
|
||||
test.createOffer(test.pcLocal, function () {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Local create offer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcLocal, test.pcLocal._last_offer, function () {
|
||||
is(test.pcLocal.signalingState, "have-local-offer",
|
||||
"signalingState after local setLocalDescription is 'have-local-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcRemote, test.pcLocal._last_offer, function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer",
|
||||
"signalingState after remote setRemoteDescription is 'have-remote-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CREATE_ANSWER',
|
||||
function (test) {
|
||||
test.createAnswer(test.pcRemote, function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer",
|
||||
"Remote createAnswer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcLocal, test.pcRemote._last_answer, function () {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"signalingState after local setRemoteDescription is 'stable'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer, function () {
|
||||
is(test.pcRemote.signalingState, "stable",
|
||||
"signalingState after remote setLocalDescription is 'stable'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_MEDIA',
|
||||
function (test) {
|
||||
test.pcLocal.checkMedia(test.pcRemote.constraints);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_MEDIA',
|
||||
function (test) {
|
||||
test.pcRemote.checkMedia(test.pcLocal.constraints);
|
||||
test.next();
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* This class handles tests for peer connections.
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} [options={}]
|
||||
* Optional options for the peer connection test
|
||||
* @param {object} [options.commands=commandsPeerConnection]
|
||||
* Commands to run for the test
|
||||
* @param {object} [options.config_pc1=undefined]
|
||||
* Configuration for the local peer connection instance
|
||||
* @param {object} [options.config_pc2=undefined]
|
||||
@ -347,13 +244,15 @@ var commandsPeerConnection = [
|
||||
function PeerConnectionTest(options) {
|
||||
// If no options are specified make it an empty object
|
||||
options = options || { };
|
||||
options.commands = options.commands || commandsPeerConnection;
|
||||
|
||||
this.pcLocal = new PeerConnectionWrapper('pcLocal', options.config_pc1);
|
||||
this.pcRemote = new PeerConnectionWrapper('pcRemote', options.config_pc2 || options.config_pc1);
|
||||
|
||||
this.connected = false;
|
||||
|
||||
// Create command chain instance and assign default commands
|
||||
this.chain = new CommandChain(this);
|
||||
this.chain.commands = commandsPeerConnection;
|
||||
this.chain = new CommandChain(this, options.commands);
|
||||
|
||||
var self = this;
|
||||
this.chain.onFinished = function () {
|
||||
@ -361,6 +260,24 @@ function PeerConnectionTest(options) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the peer connection if it is active
|
||||
*
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when the peer connection has been closed successfully
|
||||
*/
|
||||
PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
|
||||
info("Closing peer connections. Connection state=" + this.connected);
|
||||
|
||||
// There is no onclose event for the remote peer existent yet. So close it
|
||||
// side-by-side with the local peer.
|
||||
this.pcLocal.close();
|
||||
this.pcRemote.close();
|
||||
this.connected = false;
|
||||
|
||||
onSuccess();
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the next command.
|
||||
*/
|
||||
@ -504,23 +421,368 @@ PeerConnectionTest.prototype.run = function PCT_run() {
|
||||
* Clean up the objects used by the test
|
||||
*/
|
||||
PeerConnectionTest.prototype.teardown = function PCT_teardown() {
|
||||
if (this.pcLocal) {
|
||||
this.pcLocal.close();
|
||||
this.pcLocal = null;
|
||||
}
|
||||
this.close(function () {
|
||||
info("Test finished");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
};
|
||||
|
||||
if (this.pcRemote) {
|
||||
this.pcRemote.close();
|
||||
this.pcRemote = null;
|
||||
}
|
||||
/**
|
||||
* This class handles tests for data channels.
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} [options={}]
|
||||
* Optional options for the peer connection test
|
||||
* @param {object} [options.commands=commandsDataChannel]
|
||||
* Commands to run for the test
|
||||
* @param {object} [options.config_pc1=undefined]
|
||||
* Configuration for the local peer connection instance
|
||||
* @param {object} [options.config_pc2=undefined]
|
||||
* Configuration for the remote peer connection instance. If not defined
|
||||
* the configuration from the local instance will be used
|
||||
*/
|
||||
function DataChannelTest(options) {
|
||||
options = options || { };
|
||||
options.commands = options.commands || commandsDataChannel;
|
||||
|
||||
info("Test finished");
|
||||
SimpleTest.finish();
|
||||
PeerConnectionTest.call(this, options);
|
||||
}
|
||||
|
||||
DataChannelTest.prototype = Object.create(PeerConnectionTest.prototype, {
|
||||
close : {
|
||||
/**
|
||||
* Close the open data channels, followed by the underlying peer connection
|
||||
*
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when the connection has been closed
|
||||
*/
|
||||
value : function DCT_close(onSuccess) {
|
||||
var self = this;
|
||||
|
||||
function _closeChannels() {
|
||||
var length = self.pcLocal.dataChannels.length;
|
||||
|
||||
if (length > 0) {
|
||||
self.closeDataChannel(length - 1, function () {
|
||||
_closeChannels();
|
||||
});
|
||||
}
|
||||
else {
|
||||
PeerConnectionTest.prototype.close.call(self, onSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
_closeChannels();
|
||||
}
|
||||
},
|
||||
|
||||
closeDataChannel : {
|
||||
/**
|
||||
* Close the specified data channel
|
||||
*
|
||||
* @param {Number} index
|
||||
* Index of the data channel to close on both sides
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when the data channel has been closed
|
||||
*/
|
||||
value : function DCT_closeDataChannel(index, onSuccess) {
|
||||
var localChannel = this.pcLocal.dataChannels[index];
|
||||
var remoteChannel = this.pcRemote.dataChannels[index];
|
||||
|
||||
var self = this;
|
||||
|
||||
// Register handler for remote channel, cause we have to wait until
|
||||
// the current close operation has been finished.
|
||||
remoteChannel.onclose = function () {
|
||||
self.pcRemote.dataChannels.splice(index, 1);
|
||||
|
||||
onSuccess(remoteChannel);
|
||||
};
|
||||
|
||||
localChannel.close();
|
||||
this.pcLocal.dataChannels.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
createDataChannel : {
|
||||
/**
|
||||
* Create a data channel
|
||||
*
|
||||
* @param {Dict} options
|
||||
* Options for the data channel (see nsIPeerConnection)
|
||||
* @param {Function} onSuccess
|
||||
* Callback when the creation was successful
|
||||
*/
|
||||
value : function DCT_createDataChannel(options, onSuccess) {
|
||||
var localChannel = null;
|
||||
var remoteChannel = null;
|
||||
var self = this;
|
||||
|
||||
// Method to synchronize all asynchronous events.
|
||||
function check_next_test() {
|
||||
if (self.connected && localChannel && remoteChannel) {
|
||||
onSuccess(localChannel, remoteChannel);
|
||||
}
|
||||
}
|
||||
|
||||
// Register handlers for the remote peer
|
||||
this.pcRemote.registerDataChannelOpenEvents(function (channel) {
|
||||
remoteChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
|
||||
// Creat the datachannel and handle the local 'onopen' event
|
||||
this.pcLocal.createDataChannel(options, function (channel) {
|
||||
localChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
send : {
|
||||
/**
|
||||
* Send data (message or blob) to the other peer
|
||||
*
|
||||
* @param {String|Blob} data
|
||||
* Data to send to the other peer. For Blobs the MIME type will be lost.
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when data has been sent
|
||||
* @param {Object} [options={ }]
|
||||
* Options to specify the data channels to be used
|
||||
* @param {DataChannelWrapper} [options.sourceChannel=pcLocal.dataChannels[length - 1]]
|
||||
* Data channel to use for sending the message
|
||||
* @param {DataChannelWrapper} [options.targetChannel=pcRemote.dataChannels[length - 1]]
|
||||
* Data channel to use for receiving the message
|
||||
*/
|
||||
value : function DCT_send(data, onSuccess, options) {
|
||||
options = options || { };
|
||||
source = options.sourceChannel ||
|
||||
this.pcLocal.dataChannels[this.pcLocal.dataChannels.length - 1];
|
||||
target = options.targetChannel ||
|
||||
this.pcRemote.dataChannels[this.pcRemote.dataChannels.length - 1];
|
||||
|
||||
// Register event handler for the target channel
|
||||
target.onmessage = function (recv_data) {
|
||||
onSuccess(target, recv_data);
|
||||
};
|
||||
|
||||
source.send(data);
|
||||
}
|
||||
},
|
||||
|
||||
setLocalDescription : {
|
||||
/**
|
||||
* Sets the local description for the specified peer connection instance
|
||||
* and automatically handles the failure case. In case for the final call
|
||||
* it will setup the requested datachannel.
|
||||
*
|
||||
* @param {PeerConnectionWrapper} peer
|
||||
The peer connection wrapper to run the command on
|
||||
* @param {mozRTCSessionDescription} desc
|
||||
* Session description for the local description request
|
||||
* @param {function} onSuccess
|
||||
* Callback to execute if the local description was set successfully
|
||||
*/
|
||||
value : function DCT_setLocalDescription(peer, desc, onSuccess) {
|
||||
// If the peer has a remote offer we are in the final call, and have
|
||||
// to wait for the datachannel connection to be open. It will also set
|
||||
// the local description internally.
|
||||
if (peer.signalingState === 'have-remote-offer') {
|
||||
this.waitForInitialDataChannel(peer, desc, onSuccess);
|
||||
}
|
||||
else {
|
||||
PeerConnectionTest.prototype.setLocalDescription.call(this, peer,
|
||||
desc, onSuccess);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
waitForInitialDataChannel : {
|
||||
/**
|
||||
* Create an initial data channel before the peer connection has been connected
|
||||
*
|
||||
* @param {PeerConnectionWrapper} peer
|
||||
The peer connection wrapper to run the command on
|
||||
* @param {mozRTCSessionDescription} desc
|
||||
* Session description for the local description request
|
||||
* @param {Function} onSuccess
|
||||
* Callback when the creation was successful
|
||||
*/
|
||||
value : function DCT_waitForInitialDataChannel(peer, desc, onSuccess) {
|
||||
var self = this;
|
||||
|
||||
var targetPeer = peer;
|
||||
var targetChannel = null;
|
||||
|
||||
var sourcePeer = (peer == this.pcLocal) ? this.pcRemote : this.pcLocal;
|
||||
var sourceChannel = null;
|
||||
|
||||
// Method to synchronize all asynchronous events which current happen
|
||||
// due to a non-predictable flow. With bug 875346 fixed we will be able
|
||||
// to simplify this code.
|
||||
function check_next_test() {
|
||||
if (self.connected && sourceChannel && targetChannel) {
|
||||
onSuccess(sourceChannel, targetChannel);
|
||||
}
|
||||
}
|
||||
|
||||
// Register 'onopen' handler for the first local data channel
|
||||
sourcePeer.dataChannels[0].onopen = function (channel) {
|
||||
sourceChannel = channel;
|
||||
check_next_test();
|
||||
};
|
||||
|
||||
// Register handlers for the target peer
|
||||
targetPeer.registerDataChannelOpenEvents(function (channel) {
|
||||
targetChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
|
||||
PeerConnectionTest.prototype.setLocalDescription.call(this, targetPeer, desc,
|
||||
function () {
|
||||
self.connected = true;
|
||||
check_next_test();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* This class acts as a wrapper around a DataChannel instance.
|
||||
*
|
||||
* @param dataChannel
|
||||
* @param peerConnectionWrapper
|
||||
* @constructor
|
||||
*/
|
||||
function DataChannelWrapper(dataChannel, peerConnectionWrapper) {
|
||||
this._channel = dataChannel;
|
||||
this._pc = peerConnectionWrapper;
|
||||
|
||||
info("Creating " + this);
|
||||
|
||||
/**
|
||||
* Setup appropriate callbacks
|
||||
*/
|
||||
|
||||
this.onclose = unexpectedEventAndFinish(this, 'onclose');
|
||||
this.onerror = unexpectedEventAndFinish(this, 'onerror');
|
||||
this.onmessage = unexpectedEventAndFinish(this, 'onmessage');
|
||||
this.onopen = unexpectedEventAndFinish(this, 'onopen');
|
||||
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Callback for native data channel 'onclose' events. If no custom handler
|
||||
* has been specified via 'this.onclose', a failure will be raised if an
|
||||
* event of this type gets caught.
|
||||
*/
|
||||
this._channel.onclose = function () {
|
||||
info(self + ": 'onclose' event fired");
|
||||
|
||||
self.onclose(self);
|
||||
self.onclose = unexpectedEventAndFinish(self, 'onclose');
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for native data channel 'onmessage' events. If no custom handler
|
||||
* has been specified via 'this.onmessage', a failure will be raised if an
|
||||
* event of this type gets caught.
|
||||
*
|
||||
* @param {Object} event
|
||||
* Event data which includes the sent message
|
||||
*/
|
||||
this._channel.onmessage = function (event) {
|
||||
info(self + ": 'onmessage' event fired for '" + event.data + "'");
|
||||
|
||||
self.onmessage(event.data);
|
||||
self.onmessage = unexpectedEventAndFinish(self, 'onmessage');
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for native data channel 'onopen' events. If no custom handler
|
||||
* has been specified via 'this.onopen', a failure will be raised if an
|
||||
* event of this type gets caught.
|
||||
*/
|
||||
this._channel.onopen = function () {
|
||||
info(self + ": 'onopen' event fired");
|
||||
|
||||
self.onopen(self);
|
||||
self.onopen = unexpectedEventAndFinish(self, 'onopen');
|
||||
};
|
||||
}
|
||||
|
||||
DataChannelWrapper.prototype = {
|
||||
/**
|
||||
* Returns the binary type of the channel
|
||||
*
|
||||
* @returns {String} The binary type
|
||||
*/
|
||||
get binaryType() {
|
||||
return this._channel.binaryType;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the binary type of the channel
|
||||
*
|
||||
* @param {String} type
|
||||
* The new binary type of the channel
|
||||
*/
|
||||
set binaryType(type) {
|
||||
this._channel.binaryType = type;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the label of the underlying data channel
|
||||
*
|
||||
* @returns {String} The label
|
||||
*/
|
||||
get label() {
|
||||
return this._channel.label;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the readyState bit of the data channel
|
||||
*
|
||||
* @returns {String} The state of the channel
|
||||
*/
|
||||
get readyState() {
|
||||
return this._channel.readyState;
|
||||
},
|
||||
|
||||
/**
|
||||
* Close the data channel
|
||||
*/
|
||||
close : function () {
|
||||
info(this + ": Closing channel");
|
||||
this._channel.close();
|
||||
},
|
||||
|
||||
/**
|
||||
* Send data through the data channel
|
||||
*
|
||||
* @param {String|Object} data
|
||||
* Data which has to be sent through the data channel
|
||||
*/
|
||||
send: function DCW_send(data) {
|
||||
info(this + ": Sending data '" + data + "'");
|
||||
this._channel.send(data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the string representation of the class
|
||||
*
|
||||
* @returns {String} The string representation
|
||||
*/
|
||||
toString: function DCW_toString() {
|
||||
return "DataChannelWrapper (" + this._pc.label + '_' + this._channel.label + ")";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This class handles acts as a wrapper around a PeerConnection instance.
|
||||
* This class acts as a wrapper around a PeerConnection instance.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} label
|
||||
@ -536,21 +798,46 @@ function PeerConnectionWrapper(label, configuration) {
|
||||
this.offerConstraints = {};
|
||||
this.streams = [ ];
|
||||
|
||||
info("Creating new PeerConnectionWrapper: " + this);
|
||||
this.dataChannels = [ ];
|
||||
|
||||
info("Creating " + this);
|
||||
this._pc = new mozRTCPeerConnection(this.configuration);
|
||||
|
||||
/**
|
||||
* Setup callback handlers
|
||||
*/
|
||||
|
||||
this.ondatachannel = unexpectedEventAndFinish(this, 'ondatachannel');
|
||||
this.onsignalingstatechange = unexpectedEventAndFinish(this, 'onsignalingstatechange');
|
||||
|
||||
|
||||
/**
|
||||
* Callback for native peer connection 'onaddstream' events.
|
||||
*
|
||||
* @param {Object} event
|
||||
* Event data which includes the stream to be added
|
||||
*/
|
||||
var self = this;
|
||||
this._pc.onaddstream = function (event) {
|
||||
// Bug 834835: Assume type is video until we get get{Audio,Video}Tracks.
|
||||
info(self + ": 'onaddstream' event fired for " + event.stream);
|
||||
|
||||
// TODO: Bug 834835 - Assume type is video until we get get{Audio,Video}Tracks.
|
||||
self.attachMedia(event.stream, 'video', 'remote');
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for native peer connection 'ondatachannel' events. If no custom handler
|
||||
* has been specified via 'this.ondatachannel', a failure will be raised if an
|
||||
* event of this type gets caught.
|
||||
*
|
||||
* @param {Object} event
|
||||
* Event data which includes the newly created data channel
|
||||
*/
|
||||
this._pc.ondatachannel = function (event) {
|
||||
info(self + ": 'ondatachannel' event fired for " + event.channel.label);
|
||||
|
||||
self.ondatachannel(new DataChannelWrapper(event.channel, self));
|
||||
self.ondatachannel = unexpectedEventAndFinish(self, 'ondatachannel');
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for native peer connection 'onsignalingstatechange' events. If no
|
||||
@ -589,6 +876,15 @@ PeerConnectionWrapper.prototype = {
|
||||
this._pc.localDescription = desc;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the readyState.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
get readyState() {
|
||||
return this._pc.readyState;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the remote description.
|
||||
*
|
||||
@ -678,6 +974,32 @@ PeerConnectionWrapper.prototype = {
|
||||
_getAllUserMedia(this.constraints, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new data channel instance
|
||||
*
|
||||
* @param {Object} options
|
||||
* Options which get forwarded to nsIPeerConnection.createDataChannel
|
||||
* @param {function} [onCreation=undefined]
|
||||
* Callback to execute when the local data channel has been created
|
||||
* @returns {DataChannelWrapper} The created data channel
|
||||
*/
|
||||
createDataChannel : function PCW_createDataChannel(options, onCreation) {
|
||||
var label = 'channel_' + this.dataChannels.length;
|
||||
info(this + ": Create data channel '" + label);
|
||||
|
||||
var channel = this._pc.createDataChannel(label, options);
|
||||
var wrapper = new DataChannelWrapper(channel, this);
|
||||
|
||||
if (onCreation) {
|
||||
wrapper.onopen = function () {
|
||||
onCreation(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
this.dataChannels.push(wrapper);
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates an offer and automatically handles the failure case.
|
||||
*
|
||||
@ -827,7 +1149,7 @@ PeerConnectionWrapper.prototype = {
|
||||
is(this._pc.localStreams.length, this.constraints.length,
|
||||
this + ' has ' + this.constraints.length + ' local streams');
|
||||
|
||||
// TODO: change this when multiple incoming streams are allowed.
|
||||
// TODO: change this when multiple incoming streams are supported (bug 834835)
|
||||
is(this._pc.remoteStreams.length, 1,
|
||||
this + ' has ' + 1 + ' remote streams');
|
||||
},
|
||||
@ -841,13 +1163,34 @@ PeerConnectionWrapper.prototype = {
|
||||
try {
|
||||
this._pc.close();
|
||||
info(this + ": Closed connection.");
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
info(this + ": Failure in closing connection - " + e.message);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the string representation of the object
|
||||
* Register all events during the setup of the data channel
|
||||
*
|
||||
* @param {Function} onDataChannelOpened
|
||||
* Callback to execute when the data channel has been opened
|
||||
*/
|
||||
registerDataChannelOpenEvents : function (onDataChannelOpened) {
|
||||
info(this + ": Register callbacks for 'ondatachannel' and 'onopen'");
|
||||
|
||||
this.ondatachannel = function (targetChannel) {
|
||||
targetChannel.onopen = function (targetChannel) {
|
||||
onDataChannelOpened(targetChannel);
|
||||
};
|
||||
|
||||
this.dataChannels.push(targetChannel);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the string representation of the class
|
||||
*
|
||||
* @returns {String} The string representation
|
||||
*/
|
||||
toString : function PCW_toString() {
|
||||
return "PeerConnectionWrapper (" + this.label + ")";
|
||||
|
320
dom/media/tests/mochitest/templates.js
Normal file
320
dom/media/tests/mochitest/templates.js
Normal file
@ -0,0 +1,320 @@
|
||||
/**
|
||||
* Default list of commands to execute for a PeerConnection test.
|
||||
*/
|
||||
var commandsPeerConnection = [
|
||||
[
|
||||
'PC_LOCAL_GUM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
test.pcRemote.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_CHECK_INITIAL_SIGNALINGSTATE',
|
||||
function (test) {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Initial local signalingState is 'stable'");
|
||||
is(test.pcRemote.signalingState, "stable",
|
||||
"Initial remote signalingState is 'stable'");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
function (test) {
|
||||
test.createOffer(test.pcLocal, function () {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Local create offer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcLocal, test.pcLocal._last_offer, function () {
|
||||
is(test.pcLocal.signalingState, "have-local-offer",
|
||||
"signalingState after local setLocalDescription is 'have-local-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcRemote, test.pcLocal._last_offer, function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer",
|
||||
"signalingState after remote setRemoteDescription is 'have-remote-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CREATE_ANSWER',
|
||||
function (test) {
|
||||
test.createAnswer(test.pcRemote, function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer",
|
||||
"Remote createAnswer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcLocal, test.pcRemote._last_answer, function () {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"signalingState after local setRemoteDescription is 'stable'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer, function () {
|
||||
is(test.pcRemote.signalingState, "stable",
|
||||
"signalingState after remote setLocalDescription is 'stable'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_MEDIA',
|
||||
function (test) {
|
||||
test.pcLocal.checkMedia(test.pcRemote.constraints);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_MEDIA',
|
||||
function (test) {
|
||||
test.pcRemote.checkMedia(test.pcLocal.constraints);
|
||||
test.next();
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Default list of commands to execute for a Datachannel test.
|
||||
*/
|
||||
var commandsDataChannel = [
|
||||
[
|
||||
'PC_LOCAL_GUM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
test.pcRemote.getAllUserMedia(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_CHECK_INITIAL_SIGNALINGSTATE',
|
||||
function (test) {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Initial local signalingState is stable");
|
||||
is(test.pcRemote.signalingState, "stable",
|
||||
"Initial remote signalingState is stable");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_DATA_CHANNEL',
|
||||
function (test) {
|
||||
var channel = test.pcLocal.createDataChannel({});
|
||||
|
||||
is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
|
||||
is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
|
||||
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Create datachannel does not change signaling state");
|
||||
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
function (test) {
|
||||
test.pcLocal.createOffer(function (offer) {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"Local create offer does not change signaling state");
|
||||
ok(offer.sdp.contains("m=application"),
|
||||
"m=application is contained in the SDP");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcLocal, test.pcLocal._last_offer, function () {
|
||||
is(test.pcLocal.signalingState, "have-local-offer",
|
||||
"signalingState after local setLocalDescription is 'have-local-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcRemote, test.pcLocal._last_offer, function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer",
|
||||
"signalingState after remote setRemoteDescription is 'have-remote-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CREATE_ANSWER',
|
||||
function (test) {
|
||||
test.createAnswer(test.pcRemote, function () {
|
||||
is(test.pcRemote.signalingState, "have-remote-offer",
|
||||
"Remote create offer does not change signaling state");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcLocal, test.pcRemote._last_answer, function () {
|
||||
is(test.pcLocal.signalingState, "stable",
|
||||
"signalingState after local setRemoteDescription is 'stable'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer,
|
||||
function (sourceChannel, targetChannel) {
|
||||
is(sourceChannel.readyState, "open", test.pcLocal + " is in state: 'open'");
|
||||
is(targetChannel.readyState, "open", test.pcRemote + " is in state: 'open'");
|
||||
|
||||
is(test.pcRemote.signalingState, "stable",
|
||||
"signalingState after remote setLocalDescription is 'stable'");
|
||||
test.next();
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_MEDIA',
|
||||
function (test) {
|
||||
test.pcLocal.checkMedia(test.pcRemote.constraints);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_MEDIA',
|
||||
function (test) {
|
||||
test.pcRemote.checkMedia(test.pcLocal.constraints);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE',
|
||||
function (test) {
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(data, message, "Message correctly transmitted from pcLocal to pcRemote.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_BLOB',
|
||||
function (test) {
|
||||
var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
|
||||
var blob = new Blob(contents, { "type" : "text/plain" });
|
||||
|
||||
test.send(blob, function (channel, data) {
|
||||
ok(data instanceof Blob, "Received data is of instance Blob");
|
||||
is(data.size, blob.size, "Received data has the correct size.");
|
||||
|
||||
getBlobContent(data, function (recv_contents) {
|
||||
is(recv_contents, contents, "Received data has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'CREATE_SECOND_DATA_CHANNEL',
|
||||
function (test) {
|
||||
test.createDataChannel({ }, function (sourceChannel, targetChannel) {
|
||||
is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
|
||||
is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
|
||||
|
||||
is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
|
||||
is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL',
|
||||
function (test) {
|
||||
var channels = test.pcRemote.dataChannels;
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(channels.indexOf(channel), channels.length - 1, "Last channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_FIRST_CHANNEL',
|
||||
function (test) {
|
||||
var message = "Message through 1st channel";
|
||||
var options = {
|
||||
sourceChannel: test.pcLocal.dataChannels[0],
|
||||
targetChannel: test.pcRemote.dataChannels[0]
|
||||
};
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(test.pcRemote.dataChannels.indexOf(channel), 0, "1st channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
}, options);
|
||||
}
|
||||
],
|
||||
[
|
||||
'CLOSE_LAST_OPENED_DATA_CHANNEL',
|
||||
function (test) {
|
||||
var channels = test.pcRemote.dataChannels;
|
||||
|
||||
test.closeDataChannel(channels.length - 1, function (channel) {
|
||||
is(channel.readyState, "closed", "Channel is in state: 'closed'");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
28
dom/media/tests/mochitest/test_dataChannel_basicAudio.html
Normal file
28
dom/media/tests/mochitest/test_dataChannel_basicAudio.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "796895",
|
||||
title: "Basic data channel audio connection"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new DataChannelTest();
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.run();
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "796891",
|
||||
title: "Basic data channel audio/video connection"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new DataChannelTest();
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "796891",
|
||||
title: "Basic data channel audio/video connection"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new DataChannelTest();
|
||||
test.setMediaConstraints([{audio: true, video: true}],
|
||||
[{audio: true, video: true}]);
|
||||
test.run();
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "796894",
|
||||
title: "Basic datachannel only connection"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new DataChannelTest();
|
||||
|
||||
// TODO: Add back once bug 873049 has been fixed
|
||||
test.chain.remove("PC_LOCAL_CHECK_MEDIA");
|
||||
test.chain.remove("PC_REMOTE_CHECK_MEDIA");
|
||||
|
||||
test.run();
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
28
dom/media/tests/mochitest/test_dataChannel_basicVideo.html
Normal file
28
dom/media/tests/mochitest/test_dataChannel_basicVideo.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "796889",
|
||||
title: "Basic data channel video connection"
|
||||
});
|
||||
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new DataChannelTest();
|
||||
test.setMediaConstraints([{video: true}], [{video: true}]);
|
||||
test.run();
|
||||
}, true);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
@ -19,8 +20,8 @@
|
||||
var test;
|
||||
runTest(function () {
|
||||
test = new PeerConnectionTest();
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.setMediaConstraints([{audio: true, video: true}],
|
||||
[{audio: true, video: true}]);
|
||||
test.run();
|
||||
});
|
||||
</script>
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -5,6 +5,7 @@
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -5,6 +5,7 @@
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -5,6 +5,7 @@
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -5,6 +5,7 @@
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
|
@ -40,6 +40,14 @@ struct ViewTransform {
|
||||
gfx3DMatrix::ScalingMatrix(mScale.scale, mScale.scale, 1);
|
||||
}
|
||||
|
||||
bool operator==(const ViewTransform& rhs) const {
|
||||
return mTranslation == rhs.mTranslation && mScale == rhs.mScale;
|
||||
}
|
||||
|
||||
bool operator!=(const ViewTransform& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
LayerPoint mTranslation;
|
||||
LayoutDeviceToScreenScale mScale;
|
||||
};
|
||||
|
@ -106,6 +106,21 @@ static float gYSkateSizeMultiplier = 3.5f;
|
||||
static float gXStationarySizeMultiplier = 1.5f;
|
||||
static float gYStationarySizeMultiplier = 2.5f;
|
||||
|
||||
static TimeStamp sFrameTime;
|
||||
|
||||
static TimeStamp
|
||||
GetFrameTime() {
|
||||
if (sFrameTime.IsNull()) {
|
||||
return TimeStamp::Now();
|
||||
}
|
||||
return sFrameTime;
|
||||
}
|
||||
|
||||
void
|
||||
AsyncPanZoomController::SetFrameTime(const TimeStamp& aTime) {
|
||||
sFrameTime = aTime;
|
||||
}
|
||||
|
||||
static void ReadAZPCPrefs()
|
||||
{
|
||||
Preferences::AddIntVarCache(&gPanRepaintInterval, "gfx.azpc.pan_repaint_interval", gPanRepaintInterval);
|
||||
@ -154,10 +169,10 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon
|
||||
mMinZoom(MIN_ZOOM),
|
||||
mMaxZoom(MAX_ZOOM),
|
||||
mMonitor("AsyncPanZoomController"),
|
||||
mLastSampleTime(TimeStamp::Now()),
|
||||
mLastSampleTime(GetFrameTime()),
|
||||
mState(NOTHING),
|
||||
mPreviousPaintStartTime(TimeStamp::Now()),
|
||||
mLastAsyncScrollTime(TimeStamp::Now()),
|
||||
mPreviousPaintStartTime(GetFrameTime()),
|
||||
mLastAsyncScrollTime(GetFrameTime()),
|
||||
mLastAsyncScrollOffset(0, 0),
|
||||
mCurrentAsyncScrollOffset(0, 0),
|
||||
mAsyncScrollTimeoutTask(nullptr),
|
||||
@ -763,7 +778,7 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
|
||||
ScrollBy(CSSPoint::FromUnknownPoint(displacement));
|
||||
ScheduleComposite();
|
||||
|
||||
TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime;
|
||||
TimeDuration timePaintDelta = GetFrameTime() - mPreviousPaintStartTime;
|
||||
if (timePaintDelta.ToMilliseconds() > gPanRepaintInterval) {
|
||||
RequestContentRepaint();
|
||||
}
|
||||
@ -800,7 +815,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) {
|
||||
mX.GetDisplacementForDuration(inverseResolution.scale, aDelta),
|
||||
mY.GetDisplacementForDuration(inverseResolution.scale, aDelta)
|
||||
)));
|
||||
TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime;
|
||||
TimeDuration timePaintDelta = GetFrameTime() - mPreviousPaintStartTime;
|
||||
if (timePaintDelta.ToMilliseconds() > gFlingRepaintInterval) {
|
||||
RequestContentRepaint();
|
||||
}
|
||||
@ -817,10 +832,7 @@ void AsyncPanZoomController::SetCompositorParent(CompositorParent* aCompositorPa
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
|
||||
CSSPoint newOffset = mFrameMetrics.mScrollOffset + aOffset;
|
||||
FrameMetrics metrics(mFrameMetrics);
|
||||
metrics.mScrollOffset = newOffset;
|
||||
mFrameMetrics = metrics;
|
||||
mFrameMetrics.mScrollOffset += aOffset;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScaleWithFocus(float aZoom,
|
||||
@ -994,7 +1006,7 @@ void AsyncPanZoomController::ScheduleComposite() {
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::RequestContentRepaint() {
|
||||
mPreviousPaintStartTime = TimeStamp::Now();
|
||||
mPreviousPaintStartTime = GetFrameTime();
|
||||
|
||||
double estimatedPaintSum = 0.0;
|
||||
for (uint32_t i = 0; i < mPreviousPaintDurations.Length(); i++) {
|
||||
@ -1199,7 +1211,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr
|
||||
}
|
||||
|
||||
mPreviousPaintDurations.AppendElement(
|
||||
TimeStamp::Now() - mPreviousPaintStartTime);
|
||||
GetFrameTime() - mPreviousPaintStartTime);
|
||||
} else {
|
||||
// No paint was requested, but we got one anyways. One possible cause of this
|
||||
// is that content could have fired a scrollTo(). In this case, we should take
|
||||
@ -1366,7 +1378,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
||||
mStartZoomToMetrics = mFrameMetrics;
|
||||
mEndZoomToMetrics.mScrollOffset = zoomToRect.TopLeft();
|
||||
|
||||
mAnimationStartTime = TimeStamp::Now();
|
||||
mAnimationStartTime = GetFrameTime();
|
||||
|
||||
ScheduleComposite();
|
||||
}
|
||||
|
@ -251,6 +251,13 @@ public:
|
||||
*/
|
||||
nsEventStatus HandleInputEvent(const InputData& aEvent);
|
||||
|
||||
/**
|
||||
* Sync panning and zooming animation using a fixed frame time.
|
||||
* This will ensure that we animate the APZC correctly with other external
|
||||
* animations to the same timestamp.
|
||||
*/
|
||||
static void SetFrameTime(const TimeStamp& aMilliseconds);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Helper method for touches beginning. Sets everything up for panning and any
|
||||
|
@ -196,6 +196,12 @@ void RgnRectMemoryAllocatorDTOR(void *priv)
|
||||
|
||||
nsresult nsRegion::InitStatic()
|
||||
{
|
||||
if (gRectPoolTlsIndex.initialized()) {
|
||||
// It's ok to call InitStatic if we called ShutdownStatic first
|
||||
MOZ_ASSERT(gRectPoolTlsIndex.get() == nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return gRectPoolTlsIndex.init() ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ LOCAL_INCLUDES = \
|
||||
GTEST_CPPSRCS = \
|
||||
TestLayers.cpp \
|
||||
TestTiledLayerBuffer.cpp \
|
||||
TestAsyncPanZoomController.cpp \
|
||||
$(NULL)
|
||||
|
||||
# Because of gkmedia on windows we wont find these
|
||||
@ -40,4 +41,5 @@ GTEST_CPPSRCS += \
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
||||
|
196
gfx/tests/gtest/TestAsyncPanZoomController.cpp
Normal file
196
gfx/tests/gtest/TestAsyncPanZoomController.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
|
||||
#include "mozilla/layers/AsyncPanZoomController.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/GeckoContentController.h"
|
||||
#include "Layers.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
using ::testing::_;
|
||||
|
||||
class MockContentController : public GeckoContentController {
|
||||
public:
|
||||
MOCK_METHOD1(RequestContentRepaint, void(const FrameMetrics&));
|
||||
MOCK_METHOD1(HandleDoubleTap, void(const CSSIntPoint&));
|
||||
MOCK_METHOD1(HandleSingleTap, void(const CSSIntPoint&));
|
||||
MOCK_METHOD1(HandleLongTap, void(const CSSIntPoint&));
|
||||
MOCK_METHOD2(SendAsyncScrollDOMEvent, void(const CSSRect &aContentRect, const CSSSize &aScrollableSize));
|
||||
MOCK_METHOD2(PostDelayedTask, void(Task* aTask, int aDelayMs));
|
||||
};
|
||||
|
||||
class TestContainerLayer : public ContainerLayer {
|
||||
public:
|
||||
TestContainerLayer()
|
||||
: ContainerLayer(nullptr, nullptr)
|
||||
{}
|
||||
void RemoveChild(Layer* aChild) {}
|
||||
void InsertAfter(Layer* aChild, Layer* aAfter) {}
|
||||
void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) {}
|
||||
void RepositionChild(Layer* aChild, Layer* aAfter) {}
|
||||
};
|
||||
|
||||
static
|
||||
FrameMetrics TestFrameMetrics() {
|
||||
FrameMetrics fm;
|
||||
|
||||
fm.mDisplayPort = CSSRect(0, 0, 10, 10);
|
||||
fm.mCompositionBounds = ScreenIntRect(0, 0, 10, 10);
|
||||
fm.mCriticalDisplayPort = CSSRect(0, 0, 10, 10);
|
||||
fm.mScrollableRect = CSSRect(0, 0, 100, 100);
|
||||
fm.mViewport = CSSRect(0, 0, 10, 10);
|
||||
|
||||
return fm;
|
||||
}
|
||||
|
||||
static
|
||||
void ApzcPan(AsyncPanZoomController* apzc, int& aTime, int aTouchStartY, int aTouchEndY) {
|
||||
|
||||
const int TIME_BETWEEN_TOUCH_EVENT = 100;
|
||||
const int OVERCOME_TOUCH_TOLERANCE = 100;
|
||||
MultiTouchInput mti;
|
||||
nsEventStatus status;
|
||||
|
||||
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_START, aTime);
|
||||
aTime += TIME_BETWEEN_TOUCH_EVENT;
|
||||
// Make sure the move is large enough to not be handled as a tap
|
||||
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, aTouchStartY+OVERCOME_TOUCH_TOLERANCE), ScreenSize(0, 0), 0, 0));
|
||||
status = apzc->HandleInputEvent(mti);
|
||||
EXPECT_EQ(status, nsEventStatus_eConsumeNoDefault);
|
||||
// APZC should be in TOUCHING state
|
||||
|
||||
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, aTime);
|
||||
aTime += TIME_BETWEEN_TOUCH_EVENT;
|
||||
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, aTouchStartY), ScreenSize(0, 0), 0, 0));
|
||||
status = apzc->HandleInputEvent(mti);
|
||||
EXPECT_EQ(status, nsEventStatus_eConsumeNoDefault);
|
||||
// APZC should be in PANNING, otherwise status != ConsumeNoDefault
|
||||
|
||||
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_MOVE, aTime);
|
||||
aTime += TIME_BETWEEN_TOUCH_EVENT;
|
||||
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, aTouchEndY), ScreenSize(0, 0), 0, 0));
|
||||
status = apzc->HandleInputEvent(mti);
|
||||
EXPECT_EQ(status, nsEventStatus_eConsumeNoDefault);
|
||||
|
||||
mti = MultiTouchInput(MultiTouchInput::MULTITOUCH_END, aTime);
|
||||
aTime += TIME_BETWEEN_TOUCH_EVENT;
|
||||
mti.mTouches.AppendElement(SingleTouchData(0, ScreenIntPoint(10, aTouchEndY), ScreenSize(0, 0), 0, 0));
|
||||
status = apzc->HandleInputEvent(mti);
|
||||
}
|
||||
|
||||
TEST(AsyncPanZoomController, Constructor) {
|
||||
// RefCounted class can't live in the stack
|
||||
nsRefPtr<MockContentController> mcc = new MockContentController();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = new AsyncPanZoomController(mcc);
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
}
|
||||
|
||||
TEST(AsyncPanZoomController, SimpleTransform) {
|
||||
TimeStamp testStartTime = TimeStamp::Now();
|
||||
// RefCounted class can't live in the stack
|
||||
nsRefPtr<MockContentController> mcc = new MockContentController();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = new AsyncPanZoomController(mcc);
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
|
||||
TestContainerLayer layer;
|
||||
ScreenPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &layer, &viewTransformOut, pointOut);
|
||||
|
||||
EXPECT_EQ(pointOut, ScreenPoint());
|
||||
EXPECT_EQ(viewTransformOut, ViewTransform());
|
||||
}
|
||||
|
||||
TEST(AsyncPanZoomController, Pan) {
|
||||
TimeStamp testStartTime = TimeStamp::Now();
|
||||
AsyncPanZoomController::SetFrameTime(testStartTime);
|
||||
|
||||
nsRefPtr<MockContentController> mcc = new MockContentController();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = new AsyncPanZoomController(mcc);
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_)).Times(4);
|
||||
EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
|
||||
|
||||
int time = 0;
|
||||
int touchStart = 50;
|
||||
int touchEnd = 10;
|
||||
TestContainerLayer layer;
|
||||
ScreenPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
|
||||
// Pan down
|
||||
ApzcPan(apzc, time, touchStart, touchEnd);
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &layer, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(pointOut, ScreenPoint(0, -(touchEnd-touchStart)));
|
||||
EXPECT_NE(viewTransformOut, ViewTransform());
|
||||
|
||||
// Pan back
|
||||
ApzcPan(apzc, time, touchEnd, touchStart);
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &layer, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(pointOut, ScreenPoint());
|
||||
EXPECT_EQ(viewTransformOut, ViewTransform());
|
||||
}
|
||||
|
||||
TEST(AsyncPanZoomController, Fling) {
|
||||
TimeStamp testStartTime = TimeStamp::Now();
|
||||
AsyncPanZoomController::SetFrameTime(testStartTime);
|
||||
|
||||
nsRefPtr<MockContentController> mcc = new MockContentController();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = new AsyncPanZoomController(mcc);
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_)).Times(2);
|
||||
EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
|
||||
|
||||
int time = 0;
|
||||
int touchStart = 50;
|
||||
int touchEnd = 10;
|
||||
TestContainerLayer layer;
|
||||
ScreenPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
|
||||
// Fling down. Each step scroll further down
|
||||
ApzcPan(apzc, time, touchStart, touchEnd);
|
||||
ScreenPoint lastPoint;
|
||||
for (int i = 1; i < 50; i+=1) {
|
||||
apzc->SampleContentTransformForFrame(testStartTime+TimeDuration::FromMilliseconds(i), &layer, &viewTransformOut, pointOut);
|
||||
printf("Time %f, y position %f\n", (float)i, pointOut.y);
|
||||
EXPECT_GT(pointOut.y, lastPoint.y);
|
||||
lastPoint = pointOut;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AsyncPanZoomController, OverScrollPanning) {
|
||||
TimeStamp testStartTime = TimeStamp::Now();
|
||||
AsyncPanZoomController::SetFrameTime(testStartTime);
|
||||
|
||||
nsRefPtr<MockContentController> mcc = new MockContentController();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = new AsyncPanZoomController(mcc);
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_)).Times(3);
|
||||
EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
|
||||
|
||||
// Pan sufficiently to hit overscroll behavior
|
||||
int time = 0;
|
||||
int touchStart = 500;
|
||||
int touchEnd = 10;
|
||||
TestContainerLayer layer;
|
||||
ScreenPoint pointOut;
|
||||
ViewTransform viewTransformOut;
|
||||
|
||||
// Pan down
|
||||
ApzcPan(apzc, time, touchStart, touchEnd);
|
||||
apzc->SampleContentTransformForFrame(testStartTime+TimeDuration::FromMilliseconds(1000), &layer, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(pointOut, ScreenPoint(0, 90));
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
TEST(Moz2D, Point) {
|
||||
TestBase* test = new TestPoint();
|
||||
int failures = 0;
|
||||
int totalTests = test->RunTests(&failures);
|
||||
test->RunTests(&failures);
|
||||
delete test;
|
||||
|
||||
ASSERT_EQ(failures, 0);
|
||||
@ -20,7 +20,7 @@ TEST(Moz2D, Point) {
|
||||
TEST(Moz2D, Scaling) {
|
||||
TestBase* test = new TestScaling();
|
||||
int failures = 0;
|
||||
int totalTests = test->RunTests(&failures);
|
||||
test->RunTests(&failures);
|
||||
delete test;
|
||||
|
||||
ASSERT_EQ(failures, 0);
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
#include "nsIDOMSVGAnimatedLength.h"
|
||||
#include "nsIDOMSVGLength.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIObserverService.h"
|
||||
@ -86,14 +85,12 @@ SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension,
|
||||
NS_ENSURE_TRUE(domAnimLength, false);
|
||||
|
||||
// Get the animated value from the object
|
||||
nsRefPtr<nsIDOMSVGLength> domLength;
|
||||
nsresult rv = domAnimLength->GetAnimVal(getter_AddRefs(domLength));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
nsRefPtr<nsIDOMSVGLength> domLength = domAnimLength->AnimVal();
|
||||
NS_ENSURE_TRUE(domLength, false);
|
||||
|
||||
// Check if it's a percent value (and fail if so)
|
||||
uint16_t unitType;
|
||||
rv = domLength->GetUnitType(&unitType);
|
||||
nsresult rv = domLength->GetUnitType(&unitType);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
if (unitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
|
||||
return false;
|
||||
|
@ -907,18 +907,19 @@ js::testingFunc_inParallelSection(JSContext *cx, unsigned argc, jsval *vp)
|
||||
|
||||
static JSObject *objectMetadataFunction = NULL;
|
||||
|
||||
static JSObject *
|
||||
ShellObjectMetadataCallback(JSContext *cx)
|
||||
static bool
|
||||
ShellObjectMetadataCallback(JSContext *cx, JSObject **pmetadata)
|
||||
{
|
||||
Value thisv = UndefinedValue();
|
||||
|
||||
RootedValue rval(cx);
|
||||
if (!Invoke(cx, thisv, ObjectValue(*objectMetadataFunction), 0, NULL, rval.address())) {
|
||||
cx->clearPendingException();
|
||||
return NULL;
|
||||
}
|
||||
if (!Invoke(cx, thisv, ObjectValue(*objectMetadataFunction), 0, NULL, rval.address()))
|
||||
return false;
|
||||
|
||||
return rval.isObject() ? &rval.toObject() : NULL;
|
||||
if (rval.isObject())
|
||||
*pmetadata = &rval.toObject();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -1182,23 +1182,14 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# need 3 separate lines for OS/2
|
||||
%:: %.pl
|
||||
$(RM) $@
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
|
||||
%:: %.sh
|
||||
$(RM) $@
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
|
||||
# Cancel these implicit rules
|
||||
#
|
||||
%: %,v
|
||||
|
||||
%: RCS/%,v
|
||||
|
||||
%: RCS/%
|
||||
|
||||
%: s.%
|
||||
|
||||
%: SCCS/s.%
|
||||
|
@ -2318,6 +2318,10 @@ typename ParseHandler::Node
|
||||
Parser<ParseHandler>::functionStmt()
|
||||
{
|
||||
JS_ASSERT(tokenStream.currentToken().type == TOK_FUNCTION);
|
||||
|
||||
TokenStream::Position start(keepAtoms);
|
||||
tokenStream.tell(&start);
|
||||
|
||||
RootedPropertyName name(context);
|
||||
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) {
|
||||
name = tokenStream.currentToken().name();
|
||||
@ -2327,9 +2331,6 @@ Parser<ParseHandler>::functionStmt()
|
||||
return null();
|
||||
}
|
||||
|
||||
TokenStream::Position start(keepAtoms);
|
||||
tokenStream.positionAfterLastFunctionKeyword(start);
|
||||
|
||||
/* We forbid function statements in strict mode code. */
|
||||
if (!pc->atBodyLevel() && pc->sc->needStrictChecks() &&
|
||||
!report(ParseStrictError, pc->sc->strict, null(), JSMSG_STRICT_FUNCTION_STATEMENT))
|
||||
@ -2345,7 +2346,7 @@ Parser<ParseHandler>::functionExpr()
|
||||
RootedPropertyName name(context);
|
||||
JS_ASSERT(tokenStream.currentToken().type == TOK_FUNCTION);
|
||||
TokenStream::Position start(keepAtoms);
|
||||
tokenStream.positionAfterLastFunctionKeyword(start);
|
||||
tokenStream.tell(&start);
|
||||
if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME)
|
||||
name = tokenStream.currentToken().name();
|
||||
else
|
||||
@ -2752,16 +2753,12 @@ Parser<ParseHandler>::bindVarOrConst(JSContext *cx, BindData<ParseHandler> *data
|
||||
/*
|
||||
* This definition isn't being added to the parse context's
|
||||
* declarations, so make sure to indicate the need to deoptimize
|
||||
* the script's arguments object.
|
||||
* the script's arguments object. Mark the function as if it
|
||||
* contained a debugger statement, which will deoptimize arguments
|
||||
* as much as possible.
|
||||
*/
|
||||
HandlePropertyName arguments = cx->names().arguments;
|
||||
if (name == arguments) {
|
||||
Node pn = parser->newName(arguments);
|
||||
if (!pc->define(parser->context, arguments, pn, Definition::VAR))
|
||||
return false;
|
||||
funbox->setArgumentsHasLocalBinding();
|
||||
funbox->setDefinitelyNeedsArgsObj();
|
||||
}
|
||||
if (name == cx->names().arguments)
|
||||
funbox->setHasDebuggerStatement();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class AnyContextFlags
|
||||
// - direct eval
|
||||
// - function::
|
||||
// - with
|
||||
// since both effectively allow any name to be accessed. Non-exmaples are:
|
||||
// since both effectively allow any name to be accessed. Non-examples are:
|
||||
// - upvars of nested functions
|
||||
// - function statement
|
||||
// since the set of assigned name is known dynamically. 'with' could be in
|
||||
|
@ -284,7 +284,6 @@ TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
|
||||
originPrincipals(JSScript::normalizeOriginPrincipals(options.principals,
|
||||
options.originPrincipals)),
|
||||
strictModeGetter(smg),
|
||||
lastFunctionKeyword(keepAtoms),
|
||||
tokenSkip(cx, &tokens),
|
||||
linebaseSkip(cx, &linebase),
|
||||
prevLinebaseSkip(cx, &prevLinebase)
|
||||
@ -574,17 +573,9 @@ void
|
||||
TokenStream::seek(const Position &pos, const TokenStream &other)
|
||||
{
|
||||
srcCoords.fill(other.srcCoords);
|
||||
lastFunctionKeyword = other.lastFunctionKeyword;
|
||||
seek(pos);
|
||||
}
|
||||
|
||||
void
|
||||
TokenStream::positionAfterLastFunctionKeyword(Position &pos)
|
||||
{
|
||||
JS_ASSERT(lastFunctionKeyword.buf > userbuf.base());
|
||||
PodAssign(&pos, &lastFunctionKeyword);
|
||||
}
|
||||
|
||||
bool
|
||||
TokenStream::reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, unsigned errorNumber,
|
||||
va_list args)
|
||||
@ -1172,11 +1163,8 @@ TokenStream::getTokenInternal()
|
||||
tt = TOK_NAME;
|
||||
if (!checkForKeyword(chars, length, &tt, &tp->t_op))
|
||||
goto error;
|
||||
if (tt != TOK_NAME) {
|
||||
if (tt == TOK_FUNCTION)
|
||||
tell(&lastFunctionKeyword);
|
||||
if (tt != TOK_NAME)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -660,7 +660,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||
void tell(Position *);
|
||||
void seek(const Position &pos);
|
||||
void seek(const Position &pos, const TokenStream &other);
|
||||
void positionAfterLastFunctionKeyword(Position &pos);
|
||||
|
||||
size_t positionToOffset(const Position &pos) const {
|
||||
return pos.buf - userbuf.base();
|
||||
@ -920,7 +919,6 @@ class MOZ_STACK_CLASS TokenStream
|
||||
JSContext *const cx;
|
||||
JSPrincipals *const originPrincipals;
|
||||
StrictModeGetter *strictModeGetter; /* used to test for strict mode */
|
||||
Position lastFunctionKeyword; /* used as a starting point for reparsing strict functions */
|
||||
|
||||
/*
|
||||
* The tokens array stores pointers to JSAtoms. These are rooted by the
|
||||
|
@ -787,8 +787,9 @@ ion::BuildDominatorTree(MIRGraph &graph)
|
||||
block->setDomIndex(index);
|
||||
|
||||
if (!worklist.append(block->immediatelyDominatedBlocksBegin(),
|
||||
block->immediatelyDominatedBlocksEnd()))
|
||||
block->immediatelyDominatedBlocksEnd())) {
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
@ -1358,8 +1359,9 @@ ion::EliminateRedundantChecks(MIRGraph &graph)
|
||||
|
||||
// Add all immediate dominators to the front of the worklist.
|
||||
if (!worklist.append(block->immediatelyDominatedBlocksBegin(),
|
||||
block->immediatelyDominatedBlocksEnd()))
|
||||
block->immediatelyDominatedBlocksEnd())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (MDefinitionIterator iter(block); iter; ) {
|
||||
bool eliminated = false;
|
||||
|
@ -197,6 +197,10 @@ IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes,
|
||||
DebugOnly<bool> appendOk = targets.append(obj);
|
||||
JS_ASSERT(appendOk);
|
||||
} else {
|
||||
/* Temporarily disable heavyweight-function inlining. */
|
||||
targets.clear();
|
||||
return true;
|
||||
#if 0
|
||||
types::TypeObject *typeObj = calleeTypes->getTypeObject(i);
|
||||
JS_ASSERT(typeObj);
|
||||
if (!typeObj->isFunction() || !typeObj->interpretedFunction) {
|
||||
@ -209,6 +213,7 @@ IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes,
|
||||
JS_ASSERT(appendOk);
|
||||
|
||||
*gotLambda = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -717,7 +717,10 @@ MacroAssembler::performOsr()
|
||||
bind(&isFunction);
|
||||
{
|
||||
// Function - create the callee token, then get the script.
|
||||
orPtr(Imm32(CalleeToken_Function), calleeToken);
|
||||
|
||||
// Skip the or-ing of CalleeToken_Function into calleeToken since it is zero.
|
||||
JS_ASSERT(CalleeToken_Function == 0);
|
||||
|
||||
loadPtr(Address(script, JSFunction::offsetOfNativeOrScript()), script);
|
||||
}
|
||||
|
||||
|
@ -229,11 +229,9 @@ void
|
||||
MDefinition::printOpcode(FILE *fp)
|
||||
{
|
||||
PrintOpcodeName(fp, op());
|
||||
fprintf(fp, " ");
|
||||
for (size_t j = 0; j < numOperands(); j++) {
|
||||
fprintf(fp, " ");
|
||||
getOperand(j)->printName(fp);
|
||||
if (j != numOperands() - 1)
|
||||
fprintf(fp, " ");
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,6 +442,21 @@ MConstant::printOpcode(FILE *fp)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MControlInstruction::printOpcode(FILE *fp)
|
||||
{
|
||||
MDefinition::printOpcode(fp);
|
||||
for (size_t j = 0; j < numSuccessors(); j++)
|
||||
fprintf(fp, " block%d", getSuccessor(j)->id());
|
||||
}
|
||||
|
||||
void
|
||||
MCompare::printOpcode(FILE *fp)
|
||||
{
|
||||
MDefinition::printOpcode(fp);
|
||||
fprintf(fp, " %s", js_CodeName[jsop()]);
|
||||
}
|
||||
|
||||
void
|
||||
MConstantElements::printOpcode(FILE *fp)
|
||||
{
|
||||
|
@ -814,6 +814,8 @@ class MControlInstruction : public MInstruction
|
||||
bool isControlInstruction() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void printOpcode(FILE *fp);
|
||||
};
|
||||
|
||||
class MTableSwitch
|
||||
@ -1907,6 +1909,8 @@ class MCompare
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
||||
void printOpcode(FILE *fp);
|
||||
|
||||
protected:
|
||||
bool congruentTo(MDefinition *const &ins) const {
|
||||
if (!MBinaryInstruction::congruentTo(ins))
|
||||
|
@ -1063,3 +1063,28 @@ MBasicBlock::immediateDominatorBranch(BranchDirection *pdirection)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
MIRGraph::dump(FILE *fp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
for (MBasicBlockIterator iter(begin()); iter != end(); iter++) {
|
||||
iter->dump(fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MBasicBlock::dump(FILE *fp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
for (MPhiIterator iter(phisBegin()); iter != phisEnd(); iter++) {
|
||||
iter->printOpcode(fp);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
for (MInstructionIterator iter(begin()); iter != end(); iter++) {
|
||||
iter->printOpcode(fp);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -468,6 +468,8 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
|
||||
|
||||
void dumpStack(FILE *fp);
|
||||
|
||||
void dump(FILE *fp);
|
||||
|
||||
// Track bailouts by storing the current pc in MIR instruction added at this
|
||||
// cycle. This is also used for tracking calls when profiling.
|
||||
void updateTrackedPc(jsbytecode *pc) {
|
||||
@ -666,6 +668,8 @@ class MIRGraph
|
||||
// lazilly insert an MParSlice instruction in the entry block and
|
||||
// return the definition.
|
||||
MDefinition *parSlice();
|
||||
|
||||
void dump(FILE *fp);
|
||||
};
|
||||
|
||||
class MDefinitionIterator
|
||||
|
@ -191,8 +191,11 @@ ComparePolicy::adjustInputs(MInstruction *def)
|
||||
convert = MToDouble::NonNullNonStringPrimitives;
|
||||
else if (compare->compareType() == MCompare::Compare_DoubleMaybeCoerceRHS && i == 1)
|
||||
convert = MToDouble::NonNullNonStringPrimitives;
|
||||
if (convert == MToDouble::NumbersOnly && in->type() == MIRType_Boolean)
|
||||
if (in->type() == MIRType_Null ||
|
||||
(in->type() == MIRType_Boolean && convert == MToDouble::NumbersOnly))
|
||||
{
|
||||
in = boxAt(def, in);
|
||||
}
|
||||
replace = MToDouble::New(in, convert);
|
||||
break;
|
||||
}
|
||||
|
@ -367,8 +367,9 @@ ValueNumberer::eliminateRedundancies()
|
||||
|
||||
// Add all immediate dominators to the front of the worklist.
|
||||
if (!worklist.append(block->immediatelyDominatedBlocksBegin(),
|
||||
block->immediatelyDominatedBlocksEnd()))
|
||||
block->immediatelyDominatedBlocksEnd())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// For each instruction, attempt to look up a dominating definition.
|
||||
for (MDefinitionIterator iter(block); iter; ) {
|
||||
|
12
js/src/jit-test/tests/asm.js/bug885976.js
Normal file
12
js/src/jit-test/tests/asm.js/bug885976.js
Normal file
@ -0,0 +1,12 @@
|
||||
// |jit-test| error: TypeError
|
||||
function test(stdlib, foreign) {
|
||||
"use asm"
|
||||
var ff = foreign.ff
|
||||
function f(y) {
|
||||
y = +y;
|
||||
ff(0);
|
||||
}
|
||||
return f;
|
||||
};
|
||||
f = test(this, {ff: Object.preventExtensions});
|
||||
f();
|
13
js/src/jit-test/tests/basic/bug864099.js
Normal file
13
js/src/jit-test/tests/basic/bug864099.js
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
a = (function() {
|
||||
with({}) var x, arguments, arguments
|
||||
})()
|
||||
|
||||
b = (function() {
|
||||
with({}) {
|
||||
var x = Math, arguments
|
||||
({
|
||||
get: (1 for (x in [])),
|
||||
})
|
||||
}
|
||||
})()
|
7
js/src/jit-test/tests/basic/bug884920.js
Normal file
7
js/src/jit-test/tests/basic/bug884920.js
Normal file
@ -0,0 +1,7 @@
|
||||
// |jit-test| error:SyntaxError
|
||||
|
||||
function testcase({}, a = b, ... x) {
|
||||
"use strict";
|
||||
function f() { };
|
||||
with ( f(3) );
|
||||
}
|
@ -6,14 +6,17 @@ assertEq(getObjectMetadata(x).y, 0);
|
||||
incallback = false;
|
||||
count = 0;
|
||||
|
||||
setObjectMetadataCallback(function(obj) {
|
||||
function callback(obj) {
|
||||
if (incallback)
|
||||
return null;
|
||||
return null;
|
||||
incallback = true;
|
||||
var res = {count:++count, location:Error().stack};
|
||||
incallback = false;
|
||||
return res;
|
||||
});
|
||||
}
|
||||
callback({});
|
||||
|
||||
setObjectMetadataCallback(callback);
|
||||
|
||||
function Foo() {
|
||||
this.x = 0;
|
||||
|
12
js/src/jit-test/tests/ion/bug863261.js
Normal file
12
js/src/jit-test/tests/ion/bug863261.js
Normal file
@ -0,0 +1,12 @@
|
||||
// |jit-test| error: InternalError: too much recursion
|
||||
function TestCase(d) {
|
||||
toPrinted(d)
|
||||
}
|
||||
function toPrinted(value) {}
|
||||
function reportCompare (expected, actual, description) {
|
||||
if (typeof description == "undefined")
|
||||
toPrinted(expected);
|
||||
new TestCase(description);
|
||||
reportCompare();
|
||||
}
|
||||
reportCompare(Math['LN2'], Math['LN2'], 0);
|
20
js/src/jit-test/tests/ion/bug863755.js
Normal file
20
js/src/jit-test/tests/ion/bug863755.js
Normal file
@ -0,0 +1,20 @@
|
||||
function TestCase( e, a) {
|
||||
getTestCaseResult(e, a);
|
||||
}
|
||||
function getTestCaseResult(expected, actual) {}
|
||||
var msPerSecond = 1000;
|
||||
var TIME_0000 = (function () { })();
|
||||
var now = new Date();
|
||||
var TIME_NOW = now.valueOf();
|
||||
function msFromTime(t) {
|
||||
var ms = t % msPerSecond;
|
||||
return ((ms < 0) ? msPerSecond + ms : ms );
|
||||
}
|
||||
new TestCase(false, eval("true, false"));
|
||||
addTestCase( TIME_NOW );
|
||||
addTestCase( TIME_0000 );
|
||||
function addTestCase( t ) {
|
||||
for ( m = 0; m <= 1000; m+=100 ) {
|
||||
new TestCase(msFromTime(t), (new Date(t)).getMilliseconds());
|
||||
}
|
||||
}
|
10
js/src/jit-test/tests/ion/bug872331.js
Normal file
10
js/src/jit-test/tests/ion/bug872331.js
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
function d(t) {
|
||||
if (t >= undefined) {}
|
||||
}
|
||||
function s() {
|
||||
d(null);
|
||||
}
|
||||
d(3);
|
||||
s();
|
||||
s();
|
@ -2803,8 +2803,12 @@ js_InitArrayClass(JSContext *cx, HandleObject obj)
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
JSObject *metadata = NULL;
|
||||
if (!NewObjectMetadata(cx, &metadata))
|
||||
return NULL;
|
||||
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &ArrayClass, TaggedProto(proto),
|
||||
proto->getParent(), NewObjectMetadata(cx),
|
||||
proto->getParent(), metadata,
|
||||
gc::FINALIZE_OBJECT0));
|
||||
|
||||
RootedObject arrayProto(cx, JSObject::createArray(cx, gc::FINALIZE_OBJECT4, gc::TenuredHeap, shape, type, 0));
|
||||
@ -2898,12 +2902,16 @@ NewArray(JSContext *cx, uint32_t length, JSObject *protoArg, NewObjectKind newKi
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
JSObject *metadata = NULL;
|
||||
if (!NewObjectMetadata(cx, &metadata))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Get a shape with zero fixed slots, regardless of the size class.
|
||||
* See JSObject::createArray.
|
||||
*/
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &ArrayClass, TaggedProto(proto),
|
||||
cx->global(), NewObjectMetadata(cx), gc::FINALIZE_OBJECT0));
|
||||
cx->global(), metadata, gc::FINALIZE_OBJECT0));
|
||||
if (!shape)
|
||||
return NULL;
|
||||
|
||||
|
@ -1730,8 +1730,8 @@ assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id);
|
||||
inline void assertEnteredPolicy(JSContext *cx, JSObject *obj, jsid id) {};
|
||||
#endif
|
||||
|
||||
typedef JSObject *
|
||||
(* ObjectMetadataCallback)(JSContext *cx);
|
||||
typedef bool
|
||||
(* ObjectMetadataCallback)(JSContext *cx, JSObject **pmetadata);
|
||||
|
||||
/*
|
||||
* Specify a callback to invoke when creating each JS object in the current
|
||||
|
@ -703,7 +703,7 @@ UseNewTypeForClone(JSFunction *fun)
|
||||
return true;
|
||||
|
||||
if (fun->isArrow())
|
||||
return true;
|
||||
return false;
|
||||
|
||||
if (fun->hasSingletonType())
|
||||
return false;
|
||||
|
@ -378,8 +378,12 @@ NewPropertyIteratorObject(JSContext *cx, unsigned flags)
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
JSObject *metadata = NULL;
|
||||
if (!NewObjectMetadata(cx, &metadata))
|
||||
return NULL;
|
||||
|
||||
Class *clasp = &PropertyIteratorObject::class_;
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, NULL, NULL, NewObjectMetadata(cx),
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, NULL, NULL, metadata,
|
||||
ITERATOR_FINALIZE_KIND));
|
||||
if (!shape)
|
||||
return NULL;
|
||||
|
@ -1250,8 +1250,12 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
|
||||
|
||||
RootedTypeObject type(cx, type_);
|
||||
|
||||
JSObject *metadata = NULL;
|
||||
if (!NewObjectMetadata(cx, &metadata))
|
||||
return NULL;
|
||||
|
||||
RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, TaggedProto(type->proto),
|
||||
parent, NewObjectMetadata(cx), kind));
|
||||
parent, metadata, kind));
|
||||
if (!shape)
|
||||
return NULL;
|
||||
|
||||
@ -1548,7 +1552,9 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject
|
||||
}
|
||||
|
||||
if (res && cx->typeInferenceEnabled()) {
|
||||
JSScript *script = callee->as<JSFunction>().nonLazyScript();
|
||||
JSScript *script = callee->as<JSFunction>().getOrCreateScript(cx);
|
||||
if (!script)
|
||||
return NULL;
|
||||
TypeScript::SetThis(cx, script, types::Type::ObjectType(res));
|
||||
}
|
||||
|
||||
|
@ -1662,18 +1662,19 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
|
||||
JSObject **ctorp = NULL,
|
||||
gc::AllocKind ctorKind = JSFunction::FinalizeKind);
|
||||
|
||||
static JS_ALWAYS_INLINE JSObject *
|
||||
NewObjectMetadata(JSContext *cx)
|
||||
static JS_ALWAYS_INLINE bool
|
||||
NewObjectMetadata(JSContext *cx, JSObject **pmetadata)
|
||||
{
|
||||
// The metadata callback is invoked before each created object, except when
|
||||
// analysis is active as the callback may reenter JS.
|
||||
JS_ASSERT(!*pmetadata);
|
||||
if (JS_UNLIKELY((size_t)cx->compartment()->objectMetadataCallback) &&
|
||||
!cx->compartment()->activeAnalysis)
|
||||
{
|
||||
gc::AutoSuppressGC suppress(cx);
|
||||
return cx->compartment()->objectMetadataCallback(cx);
|
||||
return cx->compartment()->objectMetadataCallback(cx, pmetadata);
|
||||
}
|
||||
return NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -2425,6 +2425,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
||||
dst->funNeedsDeclEnvObject = src->funNeedsDeclEnvObject;
|
||||
dst->funHasAnyAliasedFormal = src->funHasAnyAliasedFormal;
|
||||
dst->hasSingletons = src->hasSingletons;
|
||||
dst->treatAsRunOnce = src->treatAsRunOnce;
|
||||
dst->isGenerator = src->isGenerator;
|
||||
dst->isGeneratorExp = src->isGeneratorExp;
|
||||
|
||||
|
@ -210,6 +210,22 @@ skip script test262/ch07/7.9/S7.9_A7_T7.js
|
||||
skip script test262/ch07/7.9/S7.9_A9_T6.js
|
||||
skip script test262/ch07/7.9/S7.9_A9_T7.js
|
||||
skip script test262/ch07/7.9/S7.9_A9_T8.js
|
||||
skip script test262/ch08/8.2/S8.2_A2.js
|
||||
skip script test262/ch08/8.3/S8.3_A2.1.js
|
||||
skip script test262/ch08/8.3/S8.3_A2.2.js
|
||||
skip script test262/ch08/8.4/S8.4_A13_T1.js
|
||||
skip script test262/ch08/8.4/S8.4_A13_T2.js
|
||||
skip script test262/ch08/8.4/S8.4_A13_T3.js
|
||||
skip script test262/ch08/8.4/S8.4_A14_T1.js
|
||||
skip script test262/ch08/8.4/S8.4_A14_T2.js
|
||||
skip script test262/ch08/8.4/S8.4_A14_T3.js
|
||||
skip script test262/ch08/8.4/S8.4_A7.1.js
|
||||
skip script test262/ch08/8.4/S8.4_A7.2.js
|
||||
skip script test262/ch08/8.4/S8.4_A7.3.js
|
||||
skip script test262/ch08/8.4/S8.4_A7.4.js
|
||||
skip script test262/ch08/8.6/8.6.2/S8.6.2_A7.js
|
||||
skip script test262/ch08/8.7/S8.7.2_A1_T1.js
|
||||
skip script test262/ch08/8.7/S8.7.2_A1_T2.js
|
||||
skip script test262/ch11/11.1/11.1.1/S11.1.1_A1.js
|
||||
skip script test262/ch11/11.2/11.2.4/S11.2.4_A1.3_T1.js
|
||||
skip script test262/ch11/11.3/11.3.1/11.3.1-2-1gs.js
|
||||
@ -351,6 +367,8 @@ skip script test262/ch07/7.8/7.8.3/7.8.3-2gs.js
|
||||
skip script test262/ch07/7.8/7.8.3/7.8.3-3gs.js
|
||||
skip script test262/ch07/7.8/7.8.4/7.8.4-1gs.js
|
||||
skip script test262/ch07/7.8/7.8.5/7.8.5-1gs.js
|
||||
skip script test262/ch08/8.7/8.7.2/8.7.2-3-a-1gs.js
|
||||
skip script test262/ch08/8.7/8.7.2/8.7.2-3-a-2gs.js
|
||||
skip script test262/ch10/10.1/10.1.1/10.1.1-2gs.js
|
||||
skip script test262/ch10/10.1/10.1.1/10.1.1-5gs.js
|
||||
skip script test262/ch10/10.1/10.1.1/10.1.1-8gs.js
|
||||
@ -374,3 +392,5 @@ skip script test262/ch13/13.1/13.1-5gs.js
|
||||
skip script test262/ch13/13.1/13.1-8gs.js
|
||||
skip script test262/ch13/13.1/13.1-13gs.js
|
||||
skip script test262/ch13/13.2/13.2-19-b-3gs.js
|
||||
skip script test262/ch14/14.1/14.1-4gs.js
|
||||
skip script test262/ch14/14.1/14.1-5gs.js
|
||||
|
13
js/src/tests/test262/ch08/8.1/S8.1_A1_T1.js
Normal file
13
js/src/tests/test262/ch08/8.1/S8.1_A1_T1.js
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* The Undefined type has one value, called undefined
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A1_T1.js
|
||||
* @description Checking if execution of "var x = undefined" passes
|
||||
*/
|
||||
|
||||
// CHECK#1
|
||||
var x = undefined;
|
||||
|
25
js/src/tests/test262/ch08/8.1/S8.1_A1_T2.js
Normal file
25
js/src/tests/test262/ch08/8.1/S8.1_A1_T2.js
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* The Undefined type has one value, called undefined
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A1_T2.js
|
||||
* @description Check typeof(undefined) and typeof(void 0)
|
||||
*/
|
||||
|
||||
// CHECK#1
|
||||
if (!(typeof(undefined) === "undefined")) {
|
||||
ERROR('#1: typeof(undefined) === "undefined". Actual: ' + (typeof(undefined)));
|
||||
}
|
||||
|
||||
// CHECK#2
|
||||
if (!(typeof(void 0) === "undefined")) {
|
||||
ERROR('#2: typeof(void 0) === "undefined". Actual: ' + (typeof(void 0)));
|
||||
}
|
||||
|
||||
// CHECK#3
|
||||
if (!(undefined === void 0)) {
|
||||
ERROR('#3: undefined === void 0');
|
||||
}
|
||||
|
36
js/src/tests/test262/ch08/8.1/S8.1_A2_T1.js
Normal file
36
js/src/tests/test262/ch08/8.1/S8.1_A2_T1.js
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* Any variable that has not been assigned a value has the value undefined
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A2_T1.js
|
||||
* @description Check that var x have value and type undefined
|
||||
*/
|
||||
|
||||
var x;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// CHECK#1
|
||||
if (!(x === undefined)) {
|
||||
$ERROR('#1: var x; x === undefined. Actual: ' + (x));
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// CHECK#2
|
||||
if (!(typeof(x) === "undefined")) {
|
||||
$ERROR('#2: var x; typeof(x) === "undefined". Actual: ' + (typeof(x)));
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// CHECK#3
|
||||
if (!(x === void 0)) {
|
||||
$ERROR('#3: var x; x === void 0. Actual: ' + (x));
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
27
js/src/tests/test262/ch08/8.1/S8.1_A2_T2.js
Normal file
27
js/src/tests/test262/ch08/8.1/S8.1_A2_T2.js
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* Any variable that has not been assigned a value has the value undefined
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A2_T2.js
|
||||
* @description Function return undefined
|
||||
*/
|
||||
|
||||
// CHECK#1
|
||||
function test1(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
if (!(test1() === void 0)) {
|
||||
$ERROR('#1: function test1(x){return x} test1() === void 0. Actual: ' + (test1()));
|
||||
}
|
||||
|
||||
// CHECK#2
|
||||
function test2() {
|
||||
}
|
||||
|
||||
if (!(test2() === void 0)) {
|
||||
$ERROR('#2: function test2(){} test2() === void 0. Actual: ' + (test2()));
|
||||
}
|
||||
|
16
js/src/tests/test262/ch08/8.1/S8.1_A3.js
Normal file
16
js/src/tests/test262/ch08/8.1/S8.1_A3.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* undefined is not a keyword
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A3.js
|
||||
* @description Create variable named undefined
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// CHECK1#
|
||||
var undefined = 1;
|
||||
//
|
||||
//////////////////////////////////////////////////////////
|
||||
|
16
js/src/tests/test262/ch08/8.1/S8.1_A4.js
Normal file
16
js/src/tests/test262/ch08/8.1/S8.1_A4.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* If property of object not exist, return undefined
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A4.js
|
||||
* @description Check value of not existed property
|
||||
*/
|
||||
|
||||
// CHECK#1
|
||||
if ((new Object()).newProperty !== undefined) {
|
||||
$ERROR('#1: (new Object()).newProperty === undefined. Actual: ' + ((new Object()).newProperty));
|
||||
}
|
||||
|
||||
|
23
js/src/tests/test262/ch08/8.1/S8.1_A5.js
Normal file
23
js/src/tests/test262/ch08/8.1/S8.1_A5.js
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2009 the Sputnik authors. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/**
|
||||
* Function argument that isn't provided has a value of undefined
|
||||
*
|
||||
* @path ch08/8.1/S8.1_A5.js
|
||||
* @description Call function without provided argument
|
||||
*/
|
||||
|
||||
///////////////////////////////////////
|
||||
//
|
||||
function test(arg) {
|
||||
// Check and make sure that arg is not undefined
|
||||
if (typeof(arg) !== "undefined") {
|
||||
$ERROR('#1: Function argument that isn\'t provided has a value of undefined. Actual: ' + (typeof(arg)));
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
//
|
||||
////////////////////////////////////////
|
||||
|
0
js/src/tests/test262/ch08/8.1/browser.js
Normal file
0
js/src/tests/test262/ch08/8.1/browser.js
Normal file
0
js/src/tests/test262/ch08/8.1/shell.js
Normal file
0
js/src/tests/test262/ch08/8.1/shell.js
Normal file
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_1.js
Normal file
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_1.js
Normal file
@ -0,0 +1,17 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_1.js
|
||||
* @description Properties - [[HasOwnProperty]] (property does not exist)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = {};
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
18
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_10.js
Normal file
18
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_10.js
Normal file
@ -0,0 +1,18 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_10.js
|
||||
* @description Properties - [[HasOwnProperty]] (writable, configurable, non-enumerable own value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = {};
|
||||
Object.defineProperty(o, "foo", {value: 42, writable:true, configurable:true});
|
||||
return o.hasOwnProperty("foo");
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
18
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_11.js
Normal file
18
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_11.js
Normal file
@ -0,0 +1,18 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_11.js
|
||||
* @description Properties - [[HasOwnProperty]] (writable, configurable, enumerable own value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = {};
|
||||
Object.defineProperty(o, "foo", {value: 42, writable:true, enumerable:true, configurable:true});
|
||||
return o.hasOwnProperty("foo");
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_12.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_12.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_12.js
|
||||
* @description Properties - [[HasOwnProperty]] (non-writable, non-configurable, non-enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_13.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_13.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_13.js
|
||||
* @description Properties - [[HasOwnProperty]] (non-writable, non-configurable, enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, enumerable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_14.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_14.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_14.js
|
||||
* @description Properties - [[HasOwnProperty]] (non-writable, configurable, non-enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, configurable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_15.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_15.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_15.js
|
||||
* @description Properties - [[HasOwnProperty]] (writable, non-configurable, non-enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, writable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_16.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_16.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_16.js
|
||||
* @description Properties - [[HasOwnProperty]] (non-writable, configurable, enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, configurable:true, enumerable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_17.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_17.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_17.js
|
||||
* @description Properties - [[HasOwnProperty]] (writable, non-configurable, enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, writable:true, enumerable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_18.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_18.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_18.js
|
||||
* @description Properties - [[HasOwnProperty]] (writable, configurable, non-enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, writable:true, configurable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_19.js
Normal file
19
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_19.js
Normal file
@ -0,0 +1,19 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_19.js
|
||||
* @description Properties - [[HasOwnProperty]] (writable, configurable, enumerable inherited value property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = {};
|
||||
Object.defineProperty(base, "foo", {value: 42, writable:true, enumerable:true, configurable:true});
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_2.js
Normal file
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_2.js
Normal file
@ -0,0 +1,17 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_2.js
|
||||
* @description Properties - [[HasOwnProperty]] (old style own property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = {foo: 42};
|
||||
return o.hasOwnProperty("foo");
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_20.js
Normal file
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_20.js
Normal file
@ -0,0 +1,17 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_20.js
|
||||
* @description Properties - [[HasOwnProperty]] (literal own getter property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = { get foo() { return 42;} };
|
||||
return o.hasOwnProperty("foo");
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_21.js
Normal file
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_21.js
Normal file
@ -0,0 +1,17 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_21.js
|
||||
* @description Properties - [[HasOwnProperty]] (literal own setter property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = { set foo(x) {;} };
|
||||
return o.hasOwnProperty("foo");
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_22.js
Normal file
17
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_22.js
Normal file
@ -0,0 +1,17 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_22.js
|
||||
* @description Properties - [[HasOwnProperty]] (literal own getter/setter property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var o = { get foo() { return 42;}, set foo(x) {;} };
|
||||
return o.hasOwnProperty("foo");
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
18
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_23.js
Normal file
18
js/src/tests/test262/ch08/8.12/8.12.1/8.12.1-1_23.js
Normal file
@ -0,0 +1,18 @@
|
||||
/// Copyright (c) 2012 Ecma International. All rights reserved.
|
||||
/// Ecma International makes this code available under the terms and conditions set
|
||||
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
|
||||
/// "Use Terms"). Any redistribution of this code must retain the above
|
||||
/// copyright and this notice and otherwise comply with the Use Terms.
|
||||
/**
|
||||
* @path ch08/8.12/8.12.1/8.12.1-1_23.js
|
||||
* @description Properties - [[HasOwnProperty]] (literal inherited getter property)
|
||||
*/
|
||||
|
||||
function testcase() {
|
||||
|
||||
var base = { get foo() { return 42;} };
|
||||
var o = Object.create(base);
|
||||
return o.hasOwnProperty("foo")===false;
|
||||
|
||||
}
|
||||
runTestCase(testcase);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user