mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team.
This commit is contained in:
commit
9888e14228
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "a96d83d7e0bbd6b3fb8ecb78712c924ba8094659",
|
||||
"revision": "4f6313014c286e7940eb23dc8637395dc1eb0bd7",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ class Automation(object):
|
||||
startupinfo=None,
|
||||
creationflags=0):
|
||||
args = automationutils.wrapCommand(args)
|
||||
print "args: %s" % args
|
||||
_log.info("INFO | automation.py | Launching: %s", subprocess.list2cmdline(args))
|
||||
subprocess.Popen.__init__(self, args, bufsize, executable,
|
||||
stdin, stdout, stderr,
|
||||
preexec_fn, close_fds,
|
||||
|
@ -48,6 +48,22 @@ public interface Actions {
|
||||
*/
|
||||
void sendGeckoEvent(String geckoEvent, String data);
|
||||
|
||||
/**
|
||||
* Sends a preferences get event to Gecko.
|
||||
*
|
||||
* @param requestId The id of this request.
|
||||
* @param prefNames The preferences being requested.
|
||||
*/
|
||||
void sendPreferencesGetEvent(int requestId, String[] prefNames);
|
||||
|
||||
/**
|
||||
* Sends a preferences observe event to Gecko.
|
||||
*
|
||||
* @param requestId The id of this request.
|
||||
* @param prefNames The preferences being requested.
|
||||
*/
|
||||
void sendPreferencesObserveEvent(int requestId, String[] prefNames);
|
||||
|
||||
/**
|
||||
* Listens for a gecko event to be sent from the Gecko instance.
|
||||
* The returned object can be used to test if the event has been
|
||||
|
@ -71,11 +71,13 @@ public class FennecMochitestAssert implements Assert {
|
||||
public String mName;
|
||||
public String mDiag;
|
||||
public boolean mTodo;
|
||||
public testInfo(boolean r, String n, String d, boolean t) {
|
||||
public boolean mInfo;
|
||||
public testInfo(boolean r, String n, String d, boolean t, boolean i) {
|
||||
mResult = r;
|
||||
mName = n;
|
||||
mDiag = d;
|
||||
mTodo = t;
|
||||
mInfo = i;
|
||||
}
|
||||
|
||||
}
|
||||
@ -96,7 +98,9 @@ public class FennecMochitestAssert implements Assert {
|
||||
String message = Integer.toString(mLineNumber++) + " INFO " + resultString + " | " + mLogTestName + " | " + diag;
|
||||
dumpLog(message);
|
||||
|
||||
if (test.mTodo) {
|
||||
if (test.mInfo) {
|
||||
// do not count TEST-INFO messages
|
||||
} else if (test.mTodo) {
|
||||
mTodo++;
|
||||
} else if (isError) {
|
||||
mFailed++;
|
||||
@ -132,7 +136,7 @@ public class FennecMochitestAssert implements Assert {
|
||||
}
|
||||
|
||||
public void ok(boolean condition, String name, String diag) {
|
||||
testInfo test = new testInfo(condition, name, diag, false);
|
||||
testInfo test = new testInfo(condition, name, diag, false, false);
|
||||
_logMochitestResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
|
||||
mTestList.add(test);
|
||||
}
|
||||
@ -189,7 +193,7 @@ public class FennecMochitestAssert implements Assert {
|
||||
}
|
||||
|
||||
public void todo(boolean condition, String name, String diag) {
|
||||
testInfo test = new testInfo(condition, name, diag, true);
|
||||
testInfo test = new testInfo(condition, name, diag, true, false);
|
||||
_logMochitestResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
|
||||
mTestList.add(test);
|
||||
}
|
||||
@ -242,7 +246,7 @@ public class FennecMochitestAssert implements Assert {
|
||||
}
|
||||
|
||||
public void info(String name, String message) {
|
||||
testInfo test = new testInfo(true, name, message, false);
|
||||
testInfo test = new testInfo(true, name, message, false, true);
|
||||
_logMochitestResult(test, "TEST-INFO", "INFO FAILED?");
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ public class FennecNativeActions implements Actions {
|
||||
private Method mRegisterEventListener;
|
||||
private Method mUnregisterEventListener;
|
||||
private Method mBroadcastEvent;
|
||||
private Method mPreferencesGetEvent;
|
||||
private Method mPreferencesObserveEvent;
|
||||
private Method mSetDrawListener;
|
||||
private Method mQuerySql;
|
||||
private Object mRobocopApi;
|
||||
@ -66,6 +68,8 @@ public class FennecNativeActions implements Actions {
|
||||
mRegisterEventListener = mApiClass.getMethod("registerEventListener", String.class, mEventListenerClass);
|
||||
mUnregisterEventListener = mApiClass.getMethod("unregisterEventListener", String.class, mEventListenerClass);
|
||||
mBroadcastEvent = mApiClass.getMethod("broadcastEvent", String.class, String.class);
|
||||
mPreferencesGetEvent = mApiClass.getMethod("preferencesGetEvent", Integer.TYPE, String[].class);
|
||||
mPreferencesObserveEvent = mApiClass.getMethod("preferencesObserveEvent", Integer.TYPE, String[].class);
|
||||
mSetDrawListener = mApiClass.getMethod("setDrawListener", mDrawListenerClass);
|
||||
mQuerySql = mApiClass.getMethod("querySql", String.class, String.class);
|
||||
|
||||
@ -265,6 +269,24 @@ public class FennecNativeActions implements Actions {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPreferencesEvent(Method method, int requestId, String[] prefNames) {
|
||||
try {
|
||||
method.invoke(mRobocopApi, requestId, prefNames);
|
||||
} catch (IllegalAccessException e) {
|
||||
FennecNativeDriver.log(LogLevel.ERROR, e);
|
||||
} catch (InvocationTargetException e) {
|
||||
FennecNativeDriver.log(LogLevel.ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPreferencesGetEvent(int requestId, String[] prefNames) {
|
||||
sendPreferencesEvent(mPreferencesGetEvent, requestId, prefNames);
|
||||
}
|
||||
|
||||
public void sendPreferencesObserveEvent(int requestId, String[] prefNames) {
|
||||
sendPreferencesEvent(mPreferencesObserveEvent, requestId, prefNames);
|
||||
}
|
||||
|
||||
class DrawListenerProxy implements InvocationHandler {
|
||||
private final PaintExpecter mPaintExpecter;
|
||||
|
||||
|
@ -8,9 +8,7 @@
|
||||
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsINode;
|
||||
class nsIContent;
|
||||
#include "nsIContent.h"
|
||||
|
||||
// IID for the nsINodeList interface
|
||||
#define NS_INODELIST_IID \
|
||||
|
@ -23,12 +23,6 @@ class nsIAtom;
|
||||
class nsINodeInfo;
|
||||
class nsIDocument;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
* Structure used as a key for caching Attrs in nsDOMAttributeMap's mAttributeCache.
|
||||
*/
|
||||
@ -211,5 +205,9 @@ private:
|
||||
already_AddRefed<Attr> RemoveAttribute(nsINodeInfo* aNodeInfo);
|
||||
};
|
||||
|
||||
// XXX khuey yes this is crazy. The bindings code needs to see this include,
|
||||
// but if we pull it in at the top of the file we get a circular include
|
||||
// problem.
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
#endif /* nsDOMAttributeMap_h */
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "nsIHTMLCollection.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
class nsGenericHTMLElement;
|
||||
class nsIDocument;
|
||||
class nsINode;
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsSVGElement.h"
|
||||
|
||||
class nsSVGElement;
|
||||
class nsSVGViewBox;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -11,8 +11,7 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
class nsSVGElement;
|
||||
#include "nsSVGElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
// Alignment Types
|
||||
|
@ -549,9 +549,15 @@ nsXULElement::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
|
||||
bool shouldFocus = false;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// on Mac, mouse interactions only focus the element if it's a list
|
||||
if (aWithMouse && IsNonList(mNodeInfo))
|
||||
// on Mac, mouse interactions only focus the element if it's a list,
|
||||
// or if it's a remote target, since the remote target must handle
|
||||
// the focus.
|
||||
if (aWithMouse &&
|
||||
IsNonList(mNodeInfo) &&
|
||||
!nsEventStateManager::IsRemoteTarget(this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMXULControlElement> xulControl = do_QueryObject(this);
|
||||
|
@ -69,6 +69,12 @@ this.PermissionsTable = { geolocation: {
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read"]
|
||||
},
|
||||
"device-storage:crashes": {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read"]
|
||||
},
|
||||
"device-storage:pictures": {
|
||||
app: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
|
@ -16,10 +16,10 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
class nsGlobalWindow;
|
||||
class nsIWebBrowserChrome;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -11,13 +11,13 @@
|
||||
class nsIDOMCRMFObject;
|
||||
#endif
|
||||
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#define NS_DOMCRYPTO_CID \
|
||||
{0x929d9320, 0x251e, 0x11d4, { 0x8a, 0x7c, 0x00, 0x60, 0x08, 0xc8, 0x44, 0xc3} }
|
||||
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
@ -11,8 +11,7 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -102,9 +102,6 @@ nsDOMScriptObjectFactory::Observe(nsISupports *aSubject,
|
||||
if (cache)
|
||||
cache->Flush();
|
||||
#endif
|
||||
|
||||
nsGlobalWindow::ShutDown();
|
||||
nsDOMClassInfo::ShutDown();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
class nsMimeType;
|
||||
class nsPluginElement;
|
||||
|
||||
|
@ -11,9 +11,9 @@
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
||||
class nsITimedChannel;
|
||||
class nsIDOMWindow;
|
||||
class nsPerformance;
|
||||
class JSObject;
|
||||
struct JSContext;
|
||||
|
@ -6097,9 +6097,11 @@ class CGUnionStruct(CGThing):
|
||||
if self.type.hasNullableType:
|
||||
enumValues.append("eNull")
|
||||
methods.append(ClassMethod("IsNull", "bool", [], const=True, inline=True,
|
||||
body="return mType == eNull;"))
|
||||
body="return mType == eNull;",
|
||||
bodyInHeader=True))
|
||||
methods.append(ClassMethod("SetNull", "void", [], inline=True,
|
||||
body="mType = eNull;"))
|
||||
body="mType = eNull;",
|
||||
bodyInHeader=True))
|
||||
destructorCases.append(CGCase("eNull", None))
|
||||
toJSValCases.append(CGCase("eNull", CGGeneric("rval.setNull();\n"
|
||||
"return true;")))
|
||||
@ -8618,6 +8620,26 @@ class CGBindingRoot(CGThing):
|
||||
jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
|
||||
isJSImplemented=True)
|
||||
|
||||
# Python can't modify closed-over variables directly, so sneak
|
||||
# our mutable value in as an entry in a dictionary.
|
||||
needsDOMQS = { "value": any(d.hasXPConnectImpls for d in descriptors) }
|
||||
# Only mainthread things can have hasXPConnectImpls
|
||||
provider = config.getDescriptorProvider(False)
|
||||
def checkForXPConnectImpls(type, descriptor=None, dictionary=None):
|
||||
if needsDOMQS["value"]:
|
||||
return
|
||||
type = type.unroll()
|
||||
if not type.isInterface() or not type.isGeckoInterface():
|
||||
return
|
||||
try:
|
||||
typeDesc = provider.getDescriptor(type.inner.identifier.name)
|
||||
except NoSuchDescriptorError:
|
||||
return
|
||||
needsDOMQS["value"] = typeDesc.hasXPConnectImpls
|
||||
|
||||
callForEachType(descriptors + callbackDescriptors, dictionaries,
|
||||
mainCallbacks, checkForXPConnectImpls)
|
||||
|
||||
descriptorsWithPrototype = filter(lambda d: d.interface.hasInterfacePrototypeObject(),
|
||||
descriptors)
|
||||
traitsClasses = [CGPrototypeTraitsClass(d) for d in descriptorsWithPrototype]
|
||||
@ -8703,9 +8725,6 @@ class CGBindingRoot(CGThing):
|
||||
'mozilla/dom/Nullable.h',
|
||||
'PrimitiveConversions.h',
|
||||
'WrapperFactory.h',
|
||||
# Have to include nsDOMQS.h to get fast arg unwrapping
|
||||
# for old-binding things with castability.
|
||||
'nsDOMQS.h'
|
||||
] + (['WorkerPrivate.h',
|
||||
'nsThreadUtils.h'] if hasWorkerStuff else [])
|
||||
+ (['mozilla/Preferences.h'] if requiresPreferences else [])
|
||||
@ -8714,6 +8733,8 @@ class CGBindingRoot(CGThing):
|
||||
+ (['nsCxPusher.h'] if dictionaries else [])
|
||||
+ (['AccessCheck.h'] if hasChromeOnly else [])
|
||||
+ (['xpcprivate.h'] if isEventTarget else [])
|
||||
+ (['nsPIDOMWindow.h'] if len(jsImplemented) != 0 else [])
|
||||
+ (['nsDOMQS.h'] if needsDOMQS["value"] else [])
|
||||
+ (['AtomList.h'] if requiresAtoms else []),
|
||||
prefix,
|
||||
curr,
|
||||
|
@ -20,8 +20,7 @@
|
||||
#include "nsIDOMCameraManager.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define DEVICESTORAGE_MUSIC "music"
|
||||
#define DEVICESTORAGE_APPS "apps"
|
||||
#define DEVICESTORAGE_SDCARD "sdcard"
|
||||
#define DEVICESTORAGE_CRASHES "crashes"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -181,9 +181,10 @@ public:
|
||||
nsCOMPtr<nsIFile> pictures;
|
||||
nsCOMPtr<nsIFile> videos;
|
||||
nsCOMPtr<nsIFile> music;
|
||||
nsCOMPtr<nsIFile> apps;
|
||||
nsCOMPtr<nsIFile> sdcard;
|
||||
#endif
|
||||
nsCOMPtr<nsIFile> apps;
|
||||
nsCOMPtr<nsIFile> crashes;
|
||||
nsCOMPtr<nsIFile> temp;
|
||||
};
|
||||
|
||||
@ -268,8 +269,9 @@ DeviceStorageTypeChecker::Check(const nsAString& aType, nsIDOMBlob* aBlob)
|
||||
}
|
||||
|
||||
if (aType.EqualsLiteral(DEVICESTORAGE_APPS) ||
|
||||
aType.EqualsLiteral(DEVICESTORAGE_SDCARD)) {
|
||||
// Apps and sdcard have no restriction on mime types
|
||||
aType.EqualsLiteral(DEVICESTORAGE_SDCARD) ||
|
||||
aType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
|
||||
// Apps, crashes and sdcard have no restriction on mime types
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -282,8 +284,9 @@ DeviceStorageTypeChecker::Check(const nsAString& aType, nsIFile* aFile)
|
||||
NS_ASSERTION(aFile, "Calling Check without a file");
|
||||
|
||||
if (aType.EqualsLiteral(DEVICESTORAGE_APPS) ||
|
||||
aType.EqualsLiteral(DEVICESTORAGE_SDCARD)) {
|
||||
// apps have no restrictions on what file extensions used.
|
||||
aType.EqualsLiteral(DEVICESTORAGE_SDCARD) ||
|
||||
aType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
|
||||
// Apps, crashes and sdcard have no restrictions on what file extensions used.
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -362,7 +365,8 @@ DeviceStorageTypeChecker::GetPermissionForType(const nsAString& aType,
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_VIDEOS) &&
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_MUSIC) &&
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_APPS) &&
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_SDCARD)) {
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_SDCARD) &&
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
|
||||
// unknown type
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -402,11 +406,12 @@ bool
|
||||
DeviceStorageTypeChecker::IsVolumeBased(const nsAString& aType)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// The apps aren't stored in the same place as the media, so
|
||||
// The apps and crashes aren't stored in the same place as the media, so
|
||||
// we only ever return a single apps object, and not an array
|
||||
// with one per volume (as is the case for the remaining
|
||||
// storage types).
|
||||
return !aType.EqualsLiteral(DEVICESTORAGE_APPS);
|
||||
return !aType.EqualsLiteral(DEVICESTORAGE_APPS) &&
|
||||
!aType.EqualsLiteral(DEVICESTORAGE_CRASHES);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
@ -571,6 +576,9 @@ DeviceStorageFile::Init()
|
||||
NS_ASSERTION(typeChecker, "DeviceStorageTypeChecker is null");
|
||||
}
|
||||
|
||||
// Directories which don't depend on a volume should be calculated once
|
||||
// here. Directories which depend on the root directory of a volume
|
||||
// should be calculated in DeviceStorageFile::GetRootDirectoryForType.
|
||||
static void
|
||||
InitDirs()
|
||||
{
|
||||
@ -619,11 +627,17 @@ InitDirs()
|
||||
getter_AddRefs(sDirs->music));
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_NewLocalFile(NS_LITERAL_STRING("/data"),
|
||||
false,
|
||||
getter_AddRefs(sDirs->apps));
|
||||
#else
|
||||
dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(sDirs->apps));
|
||||
if (sDirs->apps) {
|
||||
sDirs->apps->AppendRelativeNativePath(NS_LITERAL_CSTRING("webapps"));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Eventually, on desktop, we want to do something smarter -- for example,
|
||||
// detect when an sdcard is inserted, and use that instead of this.
|
||||
@ -634,6 +648,21 @@ InitDirs()
|
||||
}
|
||||
#endif // !MOZ_WIDGET_GONK
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
NS_GetSpecialDirectory("UAppData", getter_AddRefs(sDirs->crashes));
|
||||
if (sDirs->crashes) {
|
||||
sDirs->crashes->Append(NS_LITERAL_STRING("Crash Reports"));
|
||||
}
|
||||
} else {
|
||||
// NS_GetSpecialDirectory("UAppData") fails in content processes because
|
||||
// gAppData from toolkit/xre/nsAppRunner.cpp is not initialized.
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_NewLocalFile(NS_LITERAL_STRING("/data/b2g/mozilla/Crash Reports"),
|
||||
false,
|
||||
getter_AddRefs(sDirs->crashes));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mozilla::Preferences::GetBool("device.storage.testing", false)) {
|
||||
dirService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(sDirs->temp));
|
||||
@ -663,6 +692,9 @@ DeviceStorageFile::GetFullPath(nsAString &aFullPath)
|
||||
}
|
||||
|
||||
|
||||
// Directories which don't depend on a volume should be calculated once
|
||||
// in InitDirs. Directories which depend on the root directory of a volume
|
||||
// should be calculated in this method.
|
||||
void
|
||||
DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType,
|
||||
const nsAString& aStorageName,
|
||||
@ -715,11 +747,7 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType,
|
||||
|
||||
// Apps directory
|
||||
else if (aStorageType.EqualsLiteral(DEVICESTORAGE_APPS)) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
NS_NewLocalFile(NS_LITERAL_STRING("/data"), false, getter_AddRefs(f));
|
||||
#else
|
||||
f = sDirs->apps;
|
||||
#endif
|
||||
}
|
||||
|
||||
// default SDCard
|
||||
@ -731,6 +759,11 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType,
|
||||
#endif
|
||||
}
|
||||
|
||||
// crash reports directory.
|
||||
else if (aStorageType.EqualsLiteral(DEVICESTORAGE_CRASHES)) {
|
||||
f = sDirs->crashes;
|
||||
}
|
||||
|
||||
// in testing, we default all device storage types to a temp directory
|
||||
if (f && mozilla::Preferences::GetBool("device.storage.testing", false)) {
|
||||
f = sDirs->temp;
|
||||
@ -2489,7 +2522,7 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType,
|
||||
|
||||
// the 'apps' type is special. We only want this exposed
|
||||
// if the caller has the "webapps-manage" permission.
|
||||
if (aType.EqualsLiteral("apps")) {
|
||||
if (aType.EqualsLiteral(DEVICESTORAGE_APPS)) {
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager
|
||||
= do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(permissionManager, NS_ERROR_FAILURE);
|
||||
|
@ -88,7 +88,8 @@ TextEncoder::Encode(JSContext* aCx,
|
||||
JSObject* outView = nullptr;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
buf[dstLen] = '\0';
|
||||
outView = CreateUint8Array(aCx, aObj, buf, dstLen);
|
||||
outView = Uint8Array::Create(aCx, aObj, dstLen,
|
||||
reinterpret_cast<uint8_t*>(buf.get()));
|
||||
if (!outView) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
|
@ -100,15 +100,6 @@ public:
|
||||
const bool aStream,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
JSObject*
|
||||
CreateUint8Array(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
char* aBuf, uint32_t aLen) const
|
||||
{
|
||||
return Uint8Array::Create(aCx, aObj, aLen,
|
||||
reinterpret_cast<uint8_t*>(aBuf));
|
||||
}
|
||||
|
||||
private:
|
||||
nsCString mEncoding;
|
||||
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
|
||||
|
@ -134,7 +134,7 @@ RTCIceCandidate.prototype = {
|
||||
__init: function(dict) {
|
||||
this.candidate = dict.candidate;
|
||||
this.sdpMid = dict.sdpMid;
|
||||
this.sdpMLineIndex = ("sdpMLineIndex" in dict)? dict.sdpMLineIndex+1 : null;
|
||||
this.sdpMLineIndex = ("sdpMLineIndex" in dict)? dict.sdpMLineIndex : null;
|
||||
}
|
||||
};
|
||||
|
||||
@ -691,7 +691,8 @@ RTCPeerConnection.prototype = {
|
||||
|
||||
this._queueOrRun({
|
||||
func: this._getPC().addIceCandidate,
|
||||
args: [cand.candidate, cand.sdpMid || "", cand.sdpMLineIndex],
|
||||
args: [cand.candidate, cand.sdpMid || "",
|
||||
(cand.sdpMLineIndex === null)? 0 : cand.sdpMLineIndex + 1],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
@ -14,9 +14,9 @@
|
||||
#include "mozilla/dom/PromiseBinding.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
struct JSContext;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -31,12 +31,12 @@
|
||||
|
||||
#include "nsIGeolocationProvider.h"
|
||||
#include "nsIContentPermissionPrompt.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
#include "PCOMContentPermissionRequestChild.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class nsGeolocationService;
|
||||
class nsIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "AudioManager.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISettingsService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
@ -40,11 +41,12 @@ using namespace mozilla::dom::bluetooth;
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AudioManager" , ## args)
|
||||
|
||||
#define HEADPHONES_STATUS_CHANGED "headphones-status-changed"
|
||||
#define HEADPHONES_STATUS_HEADSET NS_LITERAL_STRING("headset").get()
|
||||
#define HEADPHONES_STATUS_HEADPHONE NS_LITERAL_STRING("headphone").get()
|
||||
#define HEADPHONES_STATUS_OFF NS_LITERAL_STRING("off").get()
|
||||
#define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get()
|
||||
#define HEADPHONES_STATUS_CHANGED "headphones-status-changed"
|
||||
#define MOZ_SETTINGS_CHANGE_ID "mozsettings-changed"
|
||||
|
||||
static void BinderDeadCallback(status_t aErr);
|
||||
static void InternalSetAudioRoutes(SwitchState aState);
|
||||
@ -105,6 +107,49 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class AudioChannelVolInitCallback MOZ_FINAL : public nsISettingsServiceCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
AudioChannelVolInitCallback() {}
|
||||
|
||||
NS_IMETHOD Handle(const nsAString& aName, const JS::Value& aResult)
|
||||
{
|
||||
nsCOMPtr<nsIAudioManager> audioManager =
|
||||
do_GetService(NS_AUDIOMANAGER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(JSVAL_IS_INT(aResult), NS_OK);
|
||||
|
||||
int32_t volIndex = JSVAL_TO_INT(aResult);
|
||||
if (aName.EqualsLiteral("audio.volume.content")) {
|
||||
audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_CONTENT, volIndex);
|
||||
} else if (aName.EqualsLiteral("audio.volume.notification")) {
|
||||
audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_NOTIFICATION,
|
||||
volIndex);
|
||||
} else if (aName.EqualsLiteral("audio.volume.alarm")) {
|
||||
audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_ALARM, volIndex);
|
||||
} else if (aName.EqualsLiteral("audio.volume.telephony")) {
|
||||
audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_TELEPHONY, volIndex);
|
||||
} else if (aName.EqualsLiteral("audio.volume.bt_sco")) {
|
||||
static_cast<AudioManager *>(audioManager.get())->SetStreamVolumeIndex(
|
||||
AUDIO_STREAM_BLUETOOTH_SCO, volIndex);
|
||||
} else {
|
||||
MOZ_ASSERT("unexpected audio channel for volume control");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleError(const nsAString& aName)
|
||||
{
|
||||
LOG("AudioChannelVolInitCallback::HandleError: %s\n",
|
||||
NS_ConvertUTF16toUTF8(aName).get());
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(AudioChannelVolInitCallback, nsISettingsServiceCallback)
|
||||
} /* namespace gonk */
|
||||
} /* namespace dom */
|
||||
} /* namespace mozilla */
|
||||
@ -245,7 +290,7 @@ AudioManager::Observe(nsISupports* aSubject,
|
||||
|
||||
// To process the volume control on each audio channel according to
|
||||
// change of settings
|
||||
else if (!strcmp(aTopic, "mozsettings-changed")) {
|
||||
else if (!strcmp(aTopic, MOZ_SETTINGS_CHANGE_ID)) {
|
||||
AutoSafeJSContext cx;
|
||||
nsDependentString dataStr(aData);
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
@ -327,21 +372,6 @@ AudioManager::AudioManager() : mPhoneState(PHONE_STATE_CURRENT),
|
||||
InternalSetAudioRoutes(GetCurrentSwitchState(SWITCH_HEADPHONES));
|
||||
NotifyHeadphonesStatus(GetCurrentSwitchState(SWITCH_HEADPHONES));
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_SCO_STATUS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add bluetooth sco status changed observer!");
|
||||
}
|
||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_A2DP_STATUS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add bluetooth a2dp status changed observer!");
|
||||
}
|
||||
if (NS_FAILED(obs->AddObserver(this, "mozsettings-changed", false))) {
|
||||
NS_WARNING("Failed to add mozsettings-changed oberver!");
|
||||
}
|
||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add bluetooth hfp status changed observer!");
|
||||
}
|
||||
|
||||
for (int loop = 0; loop < AUDIO_STREAM_CNT; loop++) {
|
||||
AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(loop), 0,
|
||||
sMaxStreamVolumeTbl[loop]);
|
||||
@ -350,11 +380,41 @@ AudioManager::AudioManager() : mPhoneState(PHONE_STATE_CURRENT),
|
||||
// Force publicnotification to output at maximal volume
|
||||
SetStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE,
|
||||
sMaxStreamVolumeTbl[AUDIO_STREAM_ENFORCED_AUDIBLE]);
|
||||
|
||||
// Get the initial volume index from settings DB during boot up.
|
||||
nsCOMPtr<nsISettingsService> settingsService =
|
||||
do_GetService("@mozilla.org/settingsService;1");
|
||||
NS_ENSURE_TRUE_VOID(settingsService);
|
||||
nsCOMPtr<nsISettingsServiceLock> lock;
|
||||
nsresult rv = settingsService->CreateLock(getter_AddRefs(lock));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
nsCOMPtr<nsISettingsServiceCallback> callback = new AudioChannelVolInitCallback();
|
||||
NS_ENSURE_TRUE_VOID(callback);
|
||||
lock->Get("audio.volume.content", callback);
|
||||
lock->Get("audio.volume.notification", callback);
|
||||
lock->Get("audio.volume.alarm", callback);
|
||||
lock->Get("audio.volume.telephony", callback);
|
||||
lock->Get("audio.volume.bt_sco", callback);
|
||||
|
||||
// Gecko only control stream volume not master so set to default value
|
||||
// directly.
|
||||
AudioSystem::setMasterVolume(1.0);
|
||||
|
||||
AudioSystem::setErrorCallback(BinderDeadCallback);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
NS_ENSURE_TRUE_VOID(obs);
|
||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_SCO_STATUS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add bluetooth sco status changed observer!");
|
||||
}
|
||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_A2DP_STATUS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add bluetooth a2dp status changed observer!");
|
||||
}
|
||||
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID, false))) {
|
||||
NS_WARNING("Failed to add bluetooth hfp status changed observer!");
|
||||
}
|
||||
if (NS_FAILED(obs->AddObserver(this, MOZ_SETTINGS_CHANGE_ID, false))) {
|
||||
NS_WARNING("Failed to add mozsettings-changed observer!");
|
||||
}
|
||||
}
|
||||
|
||||
AudioManager::~AudioManager() {
|
||||
@ -371,6 +431,9 @@ AudioManager::~AudioManager() {
|
||||
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_HFP_STATUS_CHANGED_ID))) {
|
||||
NS_WARNING("Failed to remove bluetooth hfp status changed observer!");
|
||||
}
|
||||
if (NS_FAILED(obs->RemoveObserver(this, MOZ_SETTINGS_CHANGE_ID))) {
|
||||
NS_WARNING("Failed to remove mozsettings-changed observer!");
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -39,6 +39,7 @@ typedef Observer<SwitchEvent> SwitchObserver;
|
||||
namespace dom {
|
||||
namespace gonk {
|
||||
class RecoverTask;
|
||||
class AudioChannelVolInitCallback;
|
||||
class AudioManager : public nsIAudioManager
|
||||
, public nsIObserver
|
||||
{
|
||||
@ -53,6 +54,7 @@ public:
|
||||
// When audio backend is dead, recovery task needs to read all volume
|
||||
// settings then set back into audio backend.
|
||||
friend class RecoverTask;
|
||||
friend class AudioChannelVolInitCallback;
|
||||
|
||||
protected:
|
||||
int32_t mPhoneState;
|
||||
|
@ -2487,6 +2487,7 @@ RadioInterface.prototype = {
|
||||
this._updateCallingLineIdRestrictionPref(response.clirMode);
|
||||
}
|
||||
target.sendAsyncMessage("RIL:SetCallingLineIdRestriction", response);
|
||||
return false;
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
|
36
gfx/gl/VBOArena.cpp
Normal file
36
gfx/gl/VBOArena.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "VBOArena.h"
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
GLuint VBOArena::Allocate(GLContext *aGLContext)
|
||||
{
|
||||
if (!mAvailableVBOs.size()) {
|
||||
GLuint vbo;
|
||||
aGLContext->fGenBuffers(1, &vbo);
|
||||
mAllocatedVBOs.push_back(vbo);
|
||||
return vbo;
|
||||
}
|
||||
GLuint vbo = mAvailableVBOs.back();
|
||||
mAvailableVBOs.pop_back();
|
||||
return vbo;
|
||||
}
|
||||
|
||||
void VBOArena::Reset()
|
||||
{
|
||||
mAvailableVBOs = mAllocatedVBOs;
|
||||
}
|
||||
|
||||
void VBOArena::Flush(GLContext *aGLContext)
|
||||
{
|
||||
if (mAvailableVBOs.size()) {
|
||||
#ifdef DEBUG
|
||||
printf_stderr("VBOArena::Flush for %u VBOs\n", mAvailableVBOs.size());
|
||||
#endif
|
||||
aGLContext->fDeleteBuffers(mAvailableVBOs.size(), &mAvailableVBOs[0]);
|
||||
}
|
||||
}
|
33
gfx/gl/VBOArena.h
Normal file
33
gfx/gl/VBOArena.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
#ifndef VBOARENA_H_
|
||||
#define VBOARENA_H_
|
||||
|
||||
#include "GLContext.h"
|
||||
#include <vector>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class VBOArena {
|
||||
public:
|
||||
// Allocate a new VBO.
|
||||
GLuint Allocate(GLContext *aGLContext);
|
||||
|
||||
// Re-use previously allocated VBOs.
|
||||
void Reset();
|
||||
|
||||
// Throw away all allocated VBOs.
|
||||
void Flush(GLContext *aGLContext);
|
||||
private:
|
||||
std::vector<GLuint> mAllocatedVBOs;
|
||||
std::vector<GLuint> mAvailableVBOs;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -53,6 +53,7 @@ EXPORTS += [
|
||||
'SurfaceFactory.h',
|
||||
'SurfaceStream.h',
|
||||
'SurfaceTypes.h',
|
||||
'VBOArena.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_X11']:
|
||||
@ -112,6 +113,7 @@ CPP_SOURCES += [
|
||||
'SharedSurfaceGL.cpp',
|
||||
'SurfaceFactory.cpp',
|
||||
'SurfaceStream.cpp',
|
||||
'VBOArena.cpp',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdlib.h> // for free, malloc
|
||||
#include "FPSCounter.h" // for FPSState, FPSCounter
|
||||
#include "GLContextProvider.h" // for GLContextProvider
|
||||
#include "LayerManagerOGL.h" // for BUFFER_OFFSET
|
||||
#include "Layers.h" // for WriteSnapshotToDumpFile
|
||||
#include "gfx2DGlue.h" // for ThebesFilter
|
||||
#include "gfx3DMatrix.h" // for gfx3DMatrix
|
||||
@ -56,6 +57,51 @@ static inline IntSize ns2gfxSize(const nsIntSize& s) {
|
||||
return IntSize(s.width, s.height);
|
||||
}
|
||||
|
||||
// Draw the supplied geometry with the already selected shader. Both aArray1
|
||||
// and aArray2 are expected to have a stride of 2 * sizeof(GLfloat).
|
||||
static void
|
||||
DrawWithVertexBuffer2(GLContext *aGLContext, VBOArena &aVBOs,
|
||||
GLenum aMode, GLsizei aElements,
|
||||
GLint aAttr1, GLfloat *aArray1,
|
||||
GLint aAttr2, GLfloat *aArray2)
|
||||
{
|
||||
GLsizei bytes = aElements * 2 * sizeof(GLfloat);
|
||||
|
||||
aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER,
|
||||
aVBOs.Allocate(aGLContext));
|
||||
aGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER,
|
||||
2 * bytes,
|
||||
nullptr,
|
||||
LOCAL_GL_STREAM_DRAW);
|
||||
|
||||
aGLContext->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
|
||||
0,
|
||||
bytes,
|
||||
aArray1);
|
||||
aGLContext->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
|
||||
bytes,
|
||||
bytes,
|
||||
aArray2);
|
||||
|
||||
aGLContext->fEnableVertexAttribArray(aAttr1);
|
||||
aGLContext->fEnableVertexAttribArray(aAttr2);
|
||||
|
||||
aGLContext->fVertexAttribPointer(aAttr1,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, BUFFER_OFFSET(0));
|
||||
aGLContext->fVertexAttribPointer(aAttr2,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, BUFFER_OFFSET(bytes));
|
||||
|
||||
aGLContext->fDrawArrays(aMode, 0, aElements);
|
||||
|
||||
aGLContext->fDisableVertexAttribArray(aAttr1);
|
||||
aGLContext->fDisableVertexAttribArray(aAttr2);
|
||||
|
||||
aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void
|
||||
FPSState::DrawFPS(TimeStamp aNow,
|
||||
@ -98,6 +144,8 @@ FPSState::DrawFPS(TimeStamp aNow,
|
||||
free(buf);
|
||||
}
|
||||
|
||||
mVBOs.Reset();
|
||||
|
||||
struct Vertex2D {
|
||||
float x,y;
|
||||
};
|
||||
@ -191,44 +239,21 @@ FPSState::DrawFPS(TimeStamp aNow,
|
||||
copyprog->Activate();
|
||||
copyprog->SetTextureUnit(0);
|
||||
|
||||
// we're going to use client-side vertex arrays for this.
|
||||
context->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// "COPY"
|
||||
context->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ZERO,
|
||||
LOCAL_GL_ONE, LOCAL_GL_ZERO);
|
||||
|
||||
// enable our vertex attribs; we'll call glVertexPointer below
|
||||
// to fill with the correct data.
|
||||
GLint vcattr = copyprog->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
|
||||
GLint tcattr = copyprog->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||
|
||||
context->fEnableVertexAttribArray(vcattr);
|
||||
context->fEnableVertexAttribArray(tcattr);
|
||||
|
||||
context->fVertexAttribPointer(vcattr,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, vertices);
|
||||
|
||||
context->fVertexAttribPointer(tcattr,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, texCoords);
|
||||
|
||||
context->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 12);
|
||||
|
||||
context->fVertexAttribPointer(vcattr,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, vertices2);
|
||||
|
||||
context->fVertexAttribPointer(tcattr,
|
||||
2, LOCAL_GL_FLOAT,
|
||||
LOCAL_GL_FALSE,
|
||||
0, texCoords2);
|
||||
|
||||
context->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 12);
|
||||
DrawWithVertexBuffer2(context, mVBOs,
|
||||
LOCAL_GL_TRIANGLE_STRIP, 12,
|
||||
vcattr, (GLfloat *) vertices,
|
||||
tcattr, (GLfloat *) texCoords);
|
||||
DrawWithVertexBuffer2(context, mVBOs,
|
||||
LOCAL_GL_TRIANGLE_STRIP, 12,
|
||||
vcattr, (GLfloat *) vertices2,
|
||||
tcattr, (GLfloat *) texCoords2);
|
||||
}
|
||||
|
||||
#ifdef CHECK_CURRENT_PROGRAM
|
||||
@ -312,9 +337,17 @@ CompositorOGL::GetTemporaryTexture(GLenum aTextureUnit)
|
||||
void
|
||||
CompositorOGL::Destroy()
|
||||
{
|
||||
if (gl() && mTextures.Length() > 0) {
|
||||
if (gl()) {
|
||||
gl()->MakeCurrent();
|
||||
gl()->fDeleteTextures(mTextures.Length(), &mTextures[0]);
|
||||
if (mTextures.Length() > 0) {
|
||||
gl()->fDeleteTextures(mTextures.Length(), &mTextures[0]);
|
||||
}
|
||||
mVBOs.Flush(gl());
|
||||
if (mFPS) {
|
||||
if (mFPS->mTexture > 0)
|
||||
gl()->fDeleteTextures(1, &mFPS->mTexture);
|
||||
mFPS->mVBOs.Flush(gl());
|
||||
}
|
||||
}
|
||||
mTextures.SetLength(0);
|
||||
if (!mDestroyed) {
|
||||
@ -557,10 +590,6 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||
aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
|
||||
NS_ASSERTION(texCoordAttribIndex != GLuint(-1), "no texture coords?");
|
||||
|
||||
// clear any bound VBO so that glVertexAttribPointer() goes back to
|
||||
// "pointer mode"
|
||||
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Given what we know about these textures and coordinates, we can
|
||||
// compute fmod(t, 1.0f) to get the same texture coordinate out. If
|
||||
// the texCoordRect dimension is < 0 or > width/height, then we have
|
||||
@ -614,25 +643,10 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
|
||||
rects, flipped);
|
||||
}
|
||||
|
||||
mGLContext->fVertexAttribPointer(vertAttribIndex, 2,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
rects.vertexPointer());
|
||||
|
||||
mGLContext->fVertexAttribPointer(texCoordAttribIndex, 2,
|
||||
LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
|
||||
rects.texCoordPointer());
|
||||
|
||||
{
|
||||
mGLContext->fEnableVertexAttribArray(texCoordAttribIndex);
|
||||
{
|
||||
mGLContext->fEnableVertexAttribArray(vertAttribIndex);
|
||||
|
||||
mGLContext->fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
|
||||
|
||||
mGLContext->fDisableVertexAttribArray(vertAttribIndex);
|
||||
}
|
||||
mGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
|
||||
}
|
||||
DrawWithVertexBuffer2(mGLContext, mVBOs,
|
||||
LOCAL_GL_TRIANGLES, rects.elements(),
|
||||
vertAttribIndex, rects.vertexPointer(),
|
||||
texCoordAttribIndex, rects.texCoordPointer());
|
||||
}
|
||||
|
||||
void
|
||||
@ -769,6 +783,8 @@ CompositorOGL::BeginFrame(const Rect *aClipRectIn, const gfxMatrix& aTransform,
|
||||
{
|
||||
MOZ_ASSERT(!mFrameInProgress, "frame still in progress (should have called EndFrame or AbortFrame");
|
||||
|
||||
mVBOs.Reset();
|
||||
|
||||
mFrameInProgress = true;
|
||||
gfxRect rect;
|
||||
if (mUseExternalSurfaceSize) {
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
||||
#include "nsXULAppAPI.h" // for XRE_GetProcessType
|
||||
#include "nscore.h" // for NS_IMETHOD
|
||||
#include "VBOArena.h" // for gl::VBOArena
|
||||
|
||||
class gfx3DMatrix;
|
||||
class nsIWidget;
|
||||
struct gfxMatrix;
|
||||
@ -234,6 +236,11 @@ private:
|
||||
* flipped and unflipped textures */
|
||||
GLuint mQuadVBO;
|
||||
|
||||
/**
|
||||
* When we can't use mQuadVBO, we allocate VBOs from this arena instead.
|
||||
*/
|
||||
gl::VBOArena mVBOs;
|
||||
|
||||
bool mHasBGRA;
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "GLDefs.h" // for GLuint
|
||||
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
|
||||
#include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl, etc
|
||||
#include "VBOArena.h" // for gl::VBOArena
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
@ -70,6 +71,7 @@ struct FPSState {
|
||||
GLuint mTexture;
|
||||
FPSCounter mCompositionFps;
|
||||
FPSCounter mTransactionFps;
|
||||
gl::VBOArena mVBOs;
|
||||
|
||||
FPSState() : mTexture(0) { }
|
||||
|
||||
|
@ -9,9 +9,10 @@
|
||||
#include <gfxTypes.h>
|
||||
#include <gfxPoint3D.h>
|
||||
#include <gfxPointH3D.h>
|
||||
#include <gfxMatrix.h>
|
||||
#include <gfxQuad.h>
|
||||
|
||||
class gfxMatrix;
|
||||
|
||||
/**
|
||||
* This class represents a 3D transformation. The matrix is laid
|
||||
* out as follows:
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define GFX_QUAD_H
|
||||
|
||||
#include "gfxTypes.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxLineSegment.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -239,8 +239,8 @@ jsd_GetValueFunctionId(JSDContext* jsdc, JSDValue* jsdval)
|
||||
JSDValue*
|
||||
jsd_NewValue(JSDContext* jsdc, jsval value)
|
||||
{
|
||||
JS::RootedValue val(jsdc->jsrt, value);
|
||||
AutoSafeJSContext cx;
|
||||
JS::RootedValue val(cx, value);
|
||||
JSDValue* jsdval;
|
||||
|
||||
if(!(jsdval = (JSDValue*) calloc(1, sizeof(JSDValue))))
|
||||
@ -309,8 +309,9 @@ jsd_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval)
|
||||
return val;
|
||||
}
|
||||
|
||||
static JSDProperty* _newProperty(JSDContext* jsdc, JSPropertyDesc* pd,
|
||||
unsigned additionalFlags)
|
||||
static JSDProperty* _newProperty(JSDContext* jsdc, JS::HandleValue propId,
|
||||
JS::HandleValue propValue, JS::HandleValue propAlias,
|
||||
uint8_t propFlags, unsigned additionalFlags)
|
||||
{
|
||||
JSDProperty* jsdprop;
|
||||
|
||||
@ -319,16 +320,16 @@ static JSDProperty* _newProperty(JSDContext* jsdc, JSPropertyDesc* pd,
|
||||
|
||||
JS_INIT_CLIST(&jsdprop->links);
|
||||
jsdprop->nref = 1;
|
||||
jsdprop->flags = pd->flags | additionalFlags;
|
||||
jsdprop->flags = propFlags | additionalFlags;
|
||||
|
||||
if(!(jsdprop->name = jsd_NewValue(jsdc, pd->id)))
|
||||
if(!(jsdprop->name = jsd_NewValue(jsdc, propId)))
|
||||
goto new_prop_fail;
|
||||
|
||||
if(!(jsdprop->val = jsd_NewValue(jsdc, pd->value)))
|
||||
if(!(jsdprop->val = jsd_NewValue(jsdc, propValue)))
|
||||
goto new_prop_fail;
|
||||
|
||||
if((jsdprop->flags & JSDPD_ALIAS) &&
|
||||
!(jsdprop->alias = jsd_NewValue(jsdc, pd->alias)))
|
||||
!(jsdprop->alias = jsd_NewValue(jsdc, propAlias)))
|
||||
goto new_prop_fail;
|
||||
|
||||
return jsdprop;
|
||||
@ -374,9 +375,17 @@ static bool _buildProps(JSDContext* jsdc, JSDValue* jsdval)
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::RootedValue propId(cx);
|
||||
JS::RootedValue propValue(cx);
|
||||
JS::RootedValue propAlias(cx);
|
||||
uint8_t propFlags;
|
||||
for(i = 0; i < pda.length; i++)
|
||||
{
|
||||
JSDProperty* prop = _newProperty(jsdc, &pda.array[i], 0);
|
||||
propId = pda.array[i].id;
|
||||
propValue = pda.array[i].value;
|
||||
propAlias = pda.array[i].alias;
|
||||
propFlags = pda.array[i].flags;
|
||||
JSDProperty* prop = _newProperty(jsdc, propId, propValue, propAlias, propFlags, 0);
|
||||
if(!prop)
|
||||
{
|
||||
_freeProps(jsdc, jsdval);
|
||||
@ -462,19 +471,22 @@ jsd_IterateProperties(JSDContext* jsdc, JSDValue* jsdval, JSDProperty **iterp)
|
||||
JSDProperty*
|
||||
jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr)
|
||||
{
|
||||
JS::RootedString name(jsdc->jsrt, nameStr);
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment acBase(cx, jsdc->glob);
|
||||
JSDProperty* jsdprop;
|
||||
JSDProperty* iter = NULL;
|
||||
JS::RootedObject obj(cx);
|
||||
JS::RootedString name(cx, nameStr);
|
||||
unsigned attrs = 0;
|
||||
bool found;
|
||||
JSPropertyDesc pd;
|
||||
const jschar * nameChars;
|
||||
size_t nameLen;
|
||||
JS::RootedValue val(cx), nameval(cx);
|
||||
JS::RootedId nameid(cx);
|
||||
JS::RootedValue propId(cx);
|
||||
JS::RootedValue propValue(cx);
|
||||
JS::RootedValue propAlias(cx);
|
||||
uint8_t propFlags;
|
||||
|
||||
if(!jsd_IsValueObject(jsdc, jsdval))
|
||||
return NULL;
|
||||
@ -513,37 +525,36 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr)
|
||||
{
|
||||
if (JS_IsExceptionPending(cx))
|
||||
{
|
||||
if (!JS_GetPendingException(cx, &pd.value))
|
||||
if (!JS_GetPendingException(cx, propValue.address()))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pd.flags = JSPD_EXCEPTION;
|
||||
propFlags = JSPD_EXCEPTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
pd.flags = JSPD_ERROR;
|
||||
pd.value = JSVAL_VOID;
|
||||
propFlags = JSPD_ERROR;
|
||||
propValue = JSVAL_VOID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pd.value = val;
|
||||
propValue = val;
|
||||
}
|
||||
}
|
||||
|
||||
nameval = STRING_TO_JSVAL(name);
|
||||
if (!JS_ValueToId(cx, nameval, nameid.address()) ||
|
||||
!JS_IdToValue(cx, nameid, &pd.id)) {
|
||||
!JS_IdToValue(cx, nameid, propId.address())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pd.spare = 0;
|
||||
pd.alias = JSVAL_NULL;
|
||||
pd.flags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0
|
||||
propAlias = JSVAL_NULL;
|
||||
propFlags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0
|
||||
| (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0
|
||||
| (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0;
|
||||
|
||||
return _newProperty(jsdc, &pd, JSDPD_HINTED);
|
||||
return _newProperty(jsdc, propId, propValue, propAlias, propFlags, JSDPD_HINTED);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -655,8 +666,8 @@ jsd_GetValueClassName(JSDContext* jsdc, JSDValue* jsdval)
|
||||
jsval val = jsdval->val;
|
||||
if(!jsdval->className && !JSVAL_IS_PRIMITIVE(val))
|
||||
{
|
||||
JS::RootedObject obj(jsdc->jsrt, JSVAL_TO_OBJECT(val));
|
||||
AutoSafeJSContext cx;
|
||||
JS::RootedObject obj(cx, JSVAL_TO_OBJECT(val));
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
jsdval->className = JS_GetDebugClassName(obj);
|
||||
}
|
||||
|
@ -897,12 +897,13 @@ jsdProperty::GetValue(jsdIValue **_rval)
|
||||
NS_IMPL_ISUPPORTS2(jsdScript, jsdIScript, jsdIEphemeral)
|
||||
|
||||
static NS_IMETHODIMP
|
||||
AssignToJSString(JSDContext *aCx, nsACString *x, JSString *str)
|
||||
AssignToJSString(JSDContext *aCx, nsACString *x, JSString *str_)
|
||||
{
|
||||
if (!str) {
|
||||
if (!str_) {
|
||||
x->SetLength(0);
|
||||
return NS_OK;
|
||||
}
|
||||
JS::RootedString str(JSD_GetJSRuntime(aCx), str_);
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment ac(cx, JSD_GetDefaultGlobal(aCx)); // Just in case.
|
||||
size_t length = JS_GetStringEncodingLength(cx, str);
|
||||
@ -1261,7 +1262,7 @@ jsdScript::GetParameterNames(uint32_t* count, PRUnichar*** paramNames)
|
||||
NS_IMETHODIMP
|
||||
jsdScript::GetFunctionObject(jsdIValue **_rval)
|
||||
{
|
||||
JSFunction *fun = JSD_GetJSFunction(mCx, mScript);
|
||||
JS::RootedFunction fun(JSD_GetJSRuntime(mCx), JSD_GetJSFunction(mCx, mScript));
|
||||
if (!fun)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
@ -2114,10 +2115,8 @@ NS_IMETHODIMP
|
||||
jsdValue::GetJsType (uint32_t *_rval)
|
||||
{
|
||||
ASSERT_VALID_EPHEMERAL;
|
||||
jsval val;
|
||||
JS::RootedValue val(JSD_GetJSRuntime(mCx), JSD_GetValueWrappedJSVal (mCx, mValue));
|
||||
|
||||
val = JSD_GetValueWrappedJSVal (mCx, mValue);
|
||||
|
||||
if (JSVAL_IS_NULL(val))
|
||||
*_rval = TYPE_NULL;
|
||||
else if (JSVAL_IS_BOOLEAN(val))
|
||||
|
@ -337,8 +337,12 @@ endif
|
||||
endif
|
||||
|
||||
DIST_GARBAGE = config.cache config.log config.status* \
|
||||
config/autoconf.mk \
|
||||
$(JS_CONFIG_NAME) js-config.h js-confdefs.h
|
||||
config/autoconf.mk config/emptyvars.mk \
|
||||
$(JS_CONFIG_NAME) js-config.h js-confdefs.h \
|
||||
backend.mk config/backend.mk devtools/backend.mk editline/backend.mk \
|
||||
gdb/backend.mk jsapi-tests/backend.mk shell/backend.mk tests/backend.mk \
|
||||
backend.RecursiveMakeBackend.built backend.RecursiveMakeBackend.built.pp \
|
||||
devtools/rootAnalysis/Makefile
|
||||
|
||||
distclean::
|
||||
$(RM) $(DIST_GARBAGE)
|
||||
@ -665,3 +669,30 @@ endif
|
||||
#
|
||||
# END kludges for the Nitro assembler
|
||||
###############################################
|
||||
|
||||
###############################################
|
||||
# Generating source package tarballs
|
||||
# (only possible when tar is found)
|
||||
ifneq (,$(TAR))
|
||||
|
||||
source-package:
|
||||
SRCDIR=$(srcdir) \
|
||||
DIST=$(DIST) \
|
||||
MAKE=$(MAKE) \
|
||||
MKDIR=$(MKDIR) \
|
||||
TAR=$(TAR) \
|
||||
MOZJS_MAJOR_VERSION=$(MOZJS_MAJOR_VERSION) \
|
||||
MOZJS_MINOR_VERSION=$(MOZJS_MINOR_VERSION) \
|
||||
MOZJS_PATCH_VERSION=$(MOZJS_PATCH_VERSION) \
|
||||
MOZJS_ALPHA=$(MOZJS_ALPHA) \
|
||||
$(srcdir)/make-source-package.sh
|
||||
|
||||
clean::
|
||||
DIST=$(DIST) \
|
||||
MOZJS_MAJOR_VERSION=$(MOZJS_MAJOR_VERSION) \
|
||||
MOZJS_MINOR_VERSION=$(MOZJS_MINOR_VERSION) \
|
||||
MOZJS_PATCH_VERSION=$(MOZJS_PATCH_VERSION) \
|
||||
MOZJS_ALPHA=$(MOZJS_ALPHA) \
|
||||
$(srcdir)/make-source-package.sh clean
|
||||
|
||||
endif
|
||||
|
@ -87,8 +87,8 @@ obj_propertyIsEnumerable(JSContext *cx, unsigned argc, Value *vp)
|
||||
}
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
static bool
|
||||
obj_toSource(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::obj_toSource(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
@ -14,10 +14,14 @@ namespace js {
|
||||
extern const JSFunctionSpec object_methods[];
|
||||
extern const JSFunctionSpec object_static_methods[];
|
||||
|
||||
/* Object constructor native. Exposed only so the JIT can know its address. */
|
||||
// Object constructor native. Exposed only so the JIT can know its address.
|
||||
extern bool
|
||||
obj_construct(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
// Object.prototype.toSource. Exposed so that Function.prototype.toSource can chain up.
|
||||
extern bool
|
||||
obj_toSource(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* builtin_Object_h */
|
||||
|
@ -571,6 +571,14 @@ dnl ========================================================
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
||||
AC_MSG_CHECKING([for tar archiver])
|
||||
AC_CHECK_PROGS(TAR, gnutar gtar tar, "")
|
||||
if test -z "$TAR"; then
|
||||
AC_MSG_WARN([no tar archiver found in \$PATH])
|
||||
fi
|
||||
AC_MSG_RESULT([$TAR])
|
||||
AC_SUBST(TAR)
|
||||
|
||||
if test -z "$TINDERBOX_SKIP_PERL_VERSION_CHECK"; then
|
||||
AC_MSG_CHECKING([for minimum required perl version >= $PERL_VERSION])
|
||||
_perl_version=`PERL_VERSION=$PERL_VERSION $PERL -e 'print "$]"; if ($] >= $ENV{PERL_VERSION}) { exit(0); } else { exit(1); }' 2>&5`
|
||||
|
@ -451,9 +451,10 @@ frontend::CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *cha
|
||||
|
||||
// Compile a JS function body, which might appear as the value of an event
|
||||
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
|
||||
bool
|
||||
frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
|
||||
const AutoNameVector &formals, const jschar *chars, size_t length)
|
||||
static bool
|
||||
CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
|
||||
const AutoNameVector &formals, const jschar *chars, size_t length,
|
||||
GeneratorKind generatorKind)
|
||||
{
|
||||
#if JS_TRACE_LOGGING
|
||||
js::AutoTraceLog logger(js::TraceLogging::defaultLogger(),
|
||||
@ -520,7 +521,7 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
||||
ParseNode *fn;
|
||||
while (true) {
|
||||
Directives newDirectives = directives;
|
||||
fn = parser.standaloneFunctionBody(fun, formals, NotGenerator, directives, &newDirectives);
|
||||
fn = parser.standaloneFunctionBody(fun, formals, generatorKind, directives, &newDirectives);
|
||||
if (fn)
|
||||
break;
|
||||
|
||||
@ -585,3 +586,18 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
|
||||
const AutoNameVector &formals, const jschar *chars, size_t length)
|
||||
{
|
||||
return CompileFunctionBody(cx, fun, options, formals, chars, length, NotGenerator);
|
||||
}
|
||||
|
||||
bool
|
||||
frontend::CompileStarGeneratorBody(JSContext *cx, MutableHandleFunction fun,
|
||||
CompileOptions options, const AutoNameVector &formals,
|
||||
const jschar *chars, size_t length)
|
||||
{
|
||||
return CompileFunctionBody(cx, fun, options, formals, chars, length, StarGenerator);
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *chars, size_t
|
||||
bool
|
||||
CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
|
||||
const AutoNameVector &formals, const jschar *chars, size_t length);
|
||||
bool
|
||||
CompileStarGeneratorBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
|
||||
const AutoNameVector &formals, const jschar *chars, size_t length);
|
||||
|
||||
/*
|
||||
* This should be called while still on the main thread if compilation will
|
||||
|
@ -1244,7 +1244,7 @@ struct BindData
|
||||
template <typename ParseHandler>
|
||||
JSFunction *
|
||||
Parser<ParseHandler>::newFunction(GenericParseContext *pc, HandleAtom atom,
|
||||
FunctionSyntaxKind kind)
|
||||
FunctionSyntaxKind kind, JSObject *proto)
|
||||
{
|
||||
JS_ASSERT_IF(kind == Statement, atom != NULL);
|
||||
|
||||
@ -1267,8 +1267,8 @@ Parser<ParseHandler>::newFunction(GenericParseContext *pc, HandleAtom atom,
|
||||
: (kind == Arrow)
|
||||
? JSFunction::INTERPRETED_LAMBDA_ARROW
|
||||
: JSFunction::INTERPRETED;
|
||||
fun = NewFunction(context, NullPtr(), NULL, 0, flags, parent, atom,
|
||||
JSFunction::FinalizeKind, MaybeSingletonObject);
|
||||
fun = NewFunctionWithProto(context, NullPtr(), NULL, 0, flags, parent, atom, proto,
|
||||
JSFunction::FinalizeKind, MaybeSingletonObject);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
if (options().selfHostingMode)
|
||||
@ -1999,7 +1999,17 @@ Parser<ParseHandler>::functionDef(HandlePropertyName funName, const TokenStream:
|
||||
if (bodyProcessed)
|
||||
return pn;
|
||||
|
||||
RootedFunction fun(context, newFunction(pc, funName, kind));
|
||||
RootedObject proto(context);
|
||||
if (generatorKind == StarGenerator) {
|
||||
// If we are off the main thread, the generator meta-objects have
|
||||
// already been created by js::StartOffThreadParseScript, so cx will not
|
||||
// be necessary.
|
||||
JSContext *cx = context->maybeJSContext();
|
||||
proto = context->global()->getOrCreateStarGeneratorFunctionPrototype(cx);
|
||||
if (!proto)
|
||||
return null();
|
||||
}
|
||||
RootedFunction fun(context, newFunction(pc, funName, kind, proto));
|
||||
if (!fun)
|
||||
return null();
|
||||
|
||||
|
@ -407,7 +407,8 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
* Create a new function object given parse context (pc) and a name (which
|
||||
* is optional if this is a function expression).
|
||||
*/
|
||||
JSFunction *newFunction(GenericParseContext *pc, HandleAtom atom, FunctionSyntaxKind kind);
|
||||
JSFunction *newFunction(GenericParseContext *pc, HandleAtom atom, FunctionSyntaxKind kind,
|
||||
JSObject *proto = NULL);
|
||||
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
|
@ -195,18 +195,15 @@ struct Zone : private JS::shadow::Zone,
|
||||
|
||||
void scheduleGC() {
|
||||
JS_ASSERT(!runtimeFromMainThread()->isHeapBusy());
|
||||
|
||||
// Ignore attempts to schedule GCs on zones which can't be collected.
|
||||
if (canCollect())
|
||||
gcScheduled = true;
|
||||
gcScheduled = true;
|
||||
}
|
||||
|
||||
void unscheduleGC() {
|
||||
gcScheduled = false;
|
||||
}
|
||||
|
||||
bool isGCScheduled() const {
|
||||
return gcScheduled;
|
||||
bool isGCScheduled() {
|
||||
return gcScheduled && canCollect();
|
||||
}
|
||||
|
||||
void setPreservingCode(bool preserving) {
|
||||
|
@ -207,7 +207,10 @@ IsNullOrUndefined(MIRType type)
|
||||
|
||||
// Make sure registers are not modified between an instruction and
|
||||
// its OsiPoint.
|
||||
# ifdef JS_ION
|
||||
//
|
||||
// Skip this check in rooting analysis builds, which poison unrooted
|
||||
// pointers on the stack.
|
||||
# if defined(JS_ION) && !defined(JSGC_ROOT_ANALYSIS)
|
||||
# define CHECK_OSIPOINT_REGISTERS 1
|
||||
# endif
|
||||
#endif
|
||||
|
@ -2904,7 +2904,7 @@ struct JSClass {
|
||||
* with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
|
||||
* prevously allowed, but is now an ES5 violation and thus unsupported.
|
||||
*/
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 25)
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT (JSProto_LIMIT * 3 + 26)
|
||||
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
|
||||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
|
||||
#define JSCLASS_GLOBAL_FLAGS \
|
||||
|
177
js/src/jsfun.cpp
177
js/src/jsfun.cpp
@ -27,6 +27,7 @@
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "builtin/Eval.h"
|
||||
#include "builtin/Object.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "gc/Marking.h"
|
||||
@ -195,40 +196,51 @@ ResolveInterpretedFunctionPrototype(JSContext *cx, HandleObject obj)
|
||||
JS_ASSERT(!fun->isFunctionPrototype());
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assert that fun is not a compiler-created function object, which
|
||||
* must never leak to script or embedding code and then be mutated.
|
||||
* Also assert that obj is not bound, per the ES5 15.3.4.5 ref above.
|
||||
*/
|
||||
// Assert that fun is not a compiler-created function object, which
|
||||
// must never leak to script or embedding code and then be mutated.
|
||||
// Also assert that obj is not bound, per the ES5 15.3.4.5 ref above.
|
||||
JS_ASSERT(!IsInternalFunctionObject(obj));
|
||||
JS_ASSERT(!obj->isBoundFunction());
|
||||
|
||||
/*
|
||||
* Make the prototype object an instance of Object with the same parent
|
||||
* as the function object itself.
|
||||
*/
|
||||
JSObject *objProto = obj->global().getOrCreateObjectPrototype(cx);
|
||||
// Make the prototype object an instance of Object with the same parent as
|
||||
// the function object itself, unless the function is an ES6 generator. In
|
||||
// that case, per the 15 July 2013 ES6 draft, section 15.19.3, its parent is
|
||||
// the GeneratorObjectPrototype singleton.
|
||||
bool isStarGenerator = obj->as<JSFunction>().isStarGenerator();
|
||||
JSObject *objProto;
|
||||
if (isStarGenerator)
|
||||
objProto = obj->global().getOrCreateStarGeneratorObjectPrototype(cx);
|
||||
else
|
||||
objProto = obj->global().getOrCreateObjectPrototype(cx);
|
||||
if (!objProto)
|
||||
return NULL;
|
||||
RootedObject proto(cx, NewObjectWithGivenProto(cx, &JSObject::class_, objProto, NULL, SingletonObject));
|
||||
Class *clasp = &JSObject::class_;
|
||||
|
||||
RootedObject proto(cx, NewObjectWithGivenProto(cx, clasp, objProto, NULL, SingletonObject));
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Per ES5 15.3.5.2 a user-defined function's .prototype property is
|
||||
* initially non-configurable, non-enumerable, and writable. Per ES5 13.2
|
||||
* the prototype's .constructor property is configurable, non-enumerable,
|
||||
* and writable.
|
||||
*/
|
||||
// Per ES5 15.3.5.2 a user-defined function's .prototype property is
|
||||
// initially non-configurable, non-enumerable, and writable.
|
||||
RootedValue protoVal(cx, ObjectValue(*proto));
|
||||
RootedValue objVal(cx, ObjectValue(*obj));
|
||||
if (!JSObject::defineProperty(cx, obj, cx->names().classPrototype,
|
||||
protoVal, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_PERMANENT) ||
|
||||
!JSObject::defineProperty(cx, proto, cx->names().constructor,
|
||||
objVal, JS_PropertyStub, JS_StrictPropertyStub, 0))
|
||||
JSPROP_PERMANENT))
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Per ES5 13.2 the prototype's .constructor property is configurable,
|
||||
// non-enumerable, and writable. However, per the 15 July 2013 ES6 draft,
|
||||
// section 15.19.3, the .prototype of a generator function does not link
|
||||
// back with a .constructor.
|
||||
if (!isStarGenerator) {
|
||||
RootedValue objVal(cx, ObjectValue(*obj));
|
||||
if (!JSObject::defineProperty(cx, proto, cx->names().constructor,
|
||||
objVal, JS_PropertyStub, JS_StrictPropertyStub, 0))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return proto;
|
||||
@ -327,12 +339,15 @@ bool
|
||||
js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
MutableHandleObject objp)
|
||||
{
|
||||
enum FirstWordFlag {
|
||||
HasAtom = 0x1,
|
||||
IsStarGenerator = 0x2
|
||||
};
|
||||
|
||||
/* NB: Keep this in sync with CloneFunctionAndScript. */
|
||||
RootedAtom atom(xdr->cx());
|
||||
uint32_t firstword; /* flag telling whether fun->atom is non-null,
|
||||
plus for fun->u.i.skipmin, fun->u.i.wrapper,
|
||||
and 14 bits reserved for future use */
|
||||
uint32_t flagsword; /* word for argument count and fun->flags */
|
||||
uint32_t firstword = 0; /* bitmask of FirstWordFlag */
|
||||
uint32_t flagsword = 0; /* word for argument count and fun->flags */
|
||||
|
||||
JSContext *cx = xdr->cx();
|
||||
RootedFunction fun(cx);
|
||||
@ -347,24 +362,38 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
|
||||
}
|
||||
return false;
|
||||
}
|
||||
firstword = !!fun->atom();
|
||||
if (fun->atom())
|
||||
firstword |= HasAtom;
|
||||
if (fun->isStarGenerator())
|
||||
firstword |= IsStarGenerator;
|
||||
script = fun->getOrCreateScript(cx);
|
||||
if (!script)
|
||||
return false;
|
||||
atom = fun->atom();
|
||||
flagsword = (fun->nargs << 16) | fun->flags;
|
||||
|
||||
if (!xdr->codeUint32(&firstword))
|
||||
return false;
|
||||
} else {
|
||||
fun = NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED, NullPtr(), NullPtr(),
|
||||
JSFunction::FinalizeKind, TenuredObject);
|
||||
if (!xdr->codeUint32(&firstword))
|
||||
return false;
|
||||
|
||||
JSObject *proto = NULL;
|
||||
if (firstword & IsStarGenerator) {
|
||||
proto = cx->global()->getOrCreateStarGeneratorFunctionPrototype(cx);
|
||||
if (!proto)
|
||||
return false;
|
||||
}
|
||||
fun = NewFunctionWithProto(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED,
|
||||
NullPtr(), NullPtr(), proto,
|
||||
JSFunction::FinalizeKind, TenuredObject);
|
||||
if (!fun)
|
||||
return false;
|
||||
atom = NULL;
|
||||
script = NULL;
|
||||
}
|
||||
|
||||
if (!xdr->codeUint32(&firstword))
|
||||
return false;
|
||||
if ((firstword & 1U) && !XDRAtom(xdr, &atom))
|
||||
if ((firstword & HasAtom) && !XDRAtom(xdr, &atom))
|
||||
return false;
|
||||
if (!xdr->codeUint32(&flagsword))
|
||||
return false;
|
||||
@ -399,10 +428,15 @@ JSObject *
|
||||
js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction srcFun)
|
||||
{
|
||||
/* NB: Keep this in sync with XDRInterpretedFunction. */
|
||||
|
||||
RootedFunction clone(cx, NewFunction(cx, NullPtr(), NULL, 0,
|
||||
JSFunction::INTERPRETED, NullPtr(), NullPtr(),
|
||||
JSFunction::FinalizeKind, TenuredObject));
|
||||
JSObject *cloneProto = NULL;
|
||||
if (srcFun->isStarGenerator()) {
|
||||
cloneProto = cx->global()->getOrCreateStarGeneratorFunctionPrototype(cx);
|
||||
if (!cloneProto)
|
||||
return NULL;
|
||||
}
|
||||
RootedFunction clone(cx, NewFunctionWithProto(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED,
|
||||
NullPtr(), NullPtr(), cloneProto,
|
||||
JSFunction::FinalizeKind, TenuredObject));
|
||||
if (!clone)
|
||||
return NULL;
|
||||
|
||||
@ -605,7 +639,7 @@ js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lamb
|
||||
return NULL;
|
||||
}
|
||||
if (!fun->isArrow()) {
|
||||
if (!out.append("function "))
|
||||
if (!(fun->isStarGenerator() ? out.append("function* ") : out.append("function ")))
|
||||
return NULL;
|
||||
}
|
||||
if (fun->atom()) {
|
||||
@ -795,6 +829,9 @@ fun_toSource(JSContext *cx, unsigned argc, Value *vp)
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (!obj->is<JSFunction>() && !obj->is<FunctionProxyObject>())
|
||||
return obj_toSource(cx, argc, vp);
|
||||
|
||||
RootedString str(cx, fun_toStringHelper(cx, obj, JS_DONT_PRETTY_PRINT));
|
||||
if (!str)
|
||||
return false;
|
||||
@ -1327,8 +1364,8 @@ const JSFunctionSpec js::function_methods[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
bool
|
||||
js::Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
static bool
|
||||
FunctionConstructor(JSContext *cx, unsigned argc, Value *vp, GeneratorKind generatorKind)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedString arg(cx); // used multiple times below
|
||||
@ -1345,6 +1382,9 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
bool hasRest = false;
|
||||
|
||||
bool isStarGenerator = generatorKind == StarGenerator;
|
||||
JS_ASSERT(generatorKind != LegacyGenerator);
|
||||
|
||||
const char *filename;
|
||||
unsigned lineno;
|
||||
JSPrincipals *originPrincipals;
|
||||
@ -1437,6 +1477,7 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
*/
|
||||
TokenStream ts(cx, options, collected_args.get(), args_length,
|
||||
/* strictModeGetter = */ NULL);
|
||||
bool yieldIsValidName = ts.versionNumber() < JSVERSION_1_7 && !isStarGenerator;
|
||||
|
||||
/* The argument string may be empty or contain no tokens. */
|
||||
TokenKind tt = ts.getToken();
|
||||
@ -1451,14 +1492,14 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tt == TOK_YIELD && ts.versionNumber() < JSVERSION_1_7)
|
||||
if (tt == TOK_YIELD && yieldIsValidName)
|
||||
tt = TOK_NAME;
|
||||
|
||||
if (tt != TOK_NAME) {
|
||||
if (tt == TOK_TRIPLEDOT) {
|
||||
hasRest = true;
|
||||
tt = ts.getToken();
|
||||
if (tt == TOK_YIELD && ts.versionNumber() < JSVERSION_1_7)
|
||||
if (tt == TOK_YIELD && yieldIsValidName)
|
||||
tt = TOK_NAME;
|
||||
if (tt != TOK_NAME) {
|
||||
if (tt != TOK_ERROR)
|
||||
@ -1519,24 +1560,47 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
* and so would a call to f from another top-level's script or function.
|
||||
*/
|
||||
RootedAtom anonymousAtom(cx, cx->names().anonymous);
|
||||
RootedFunction fun(cx, NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED_LAMBDA,
|
||||
global, anonymousAtom, JSFunction::FinalizeKind,
|
||||
TenuredObject));
|
||||
JSObject *proto = NULL;
|
||||
if (isStarGenerator) {
|
||||
proto = global->getOrCreateStarGeneratorFunctionPrototype(cx);
|
||||
if (!proto)
|
||||
return false;
|
||||
}
|
||||
RootedFunction fun(cx, NewFunctionWithProto(cx, NullPtr(), NULL, 0,
|
||||
JSFunction::INTERPRETED_LAMBDA, global,
|
||||
anonymousAtom, proto,
|
||||
JSFunction::FinalizeKind, TenuredObject));
|
||||
if (!fun)
|
||||
return false;
|
||||
|
||||
if (hasRest)
|
||||
fun->setHasRest();
|
||||
|
||||
bool ok = frontend::CompileFunctionBody(cx, &fun, options, formals, chars, length);
|
||||
bool ok;
|
||||
if (isStarGenerator)
|
||||
ok = frontend::CompileStarGeneratorBody(cx, &fun, options, formals, chars, length);
|
||||
else
|
||||
ok = frontend::CompileFunctionBody(cx, &fun, options, formals, chars, length);
|
||||
args.rval().setObject(*fun);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
js::Function(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return FunctionConstructor(cx, argc, vp, NotGenerator);
|
||||
}
|
||||
|
||||
bool
|
||||
js::Generator(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return FunctionConstructor(cx, argc, vp, StarGenerator);
|
||||
}
|
||||
|
||||
bool
|
||||
JSFunction::isBuiltinFunctionConstructor()
|
||||
{
|
||||
return maybeNative() == Function;
|
||||
return maybeNative() == Function || maybeNative() == Generator;
|
||||
}
|
||||
|
||||
JSFunction *
|
||||
@ -1544,6 +1608,17 @@ js::NewFunction(ExclusiveContext *cx, HandleObject funobjArg, Native native, uns
|
||||
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
|
||||
gc::AllocKind allocKind /* = JSFunction::FinalizeKind */,
|
||||
NewObjectKind newKind /* = GenericObject */)
|
||||
{
|
||||
return NewFunctionWithProto(cx, funobjArg, native, nargs, flags, parent, atom, NULL,
|
||||
allocKind, newKind);
|
||||
}
|
||||
|
||||
JSFunction *
|
||||
js::NewFunctionWithProto(ExclusiveContext *cx, HandleObject funobjArg, Native native,
|
||||
unsigned nargs, JSFunction::Flags flags, HandleObject parent,
|
||||
HandleAtom atom, JSObject *proto,
|
||||
gc::AllocKind allocKind /* = JSFunction::FinalizeKind */,
|
||||
NewObjectKind newKind /* = GenericObject */)
|
||||
{
|
||||
JS_ASSERT(allocKind == JSFunction::FinalizeKind || allocKind == JSFunction::ExtendedFinalizeKind);
|
||||
JS_ASSERT(sizeof(JSFunction) <= gc::Arena::thingSize(JSFunction::FinalizeKind));
|
||||
@ -1560,7 +1635,7 @@ js::NewFunction(ExclusiveContext *cx, HandleObject funobjArg, Native native, uns
|
||||
// that hasSingletonType implies isInterpreted.
|
||||
if (native && !IsAsmJSModuleNative(native))
|
||||
newKind = SingletonObject;
|
||||
funobj = NewObjectWithClassProto(cx, &JSFunction::class_, NULL,
|
||||
funobj = NewObjectWithClassProto(cx, &JSFunction::class_, proto,
|
||||
SkipScopeParent(parent), allocKind, newKind);
|
||||
if (!funobj)
|
||||
return NULL;
|
||||
@ -1603,7 +1678,13 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
|
||||
return NULL;
|
||||
|
||||
NewObjectKind newKind = useSameScript ? newKindArg : SingletonObject;
|
||||
JSObject *cloneobj = NewObjectWithClassProto(cx, &JSFunction::class_, NULL,
|
||||
JSObject *cloneProto = NULL;
|
||||
if (fun->isStarGenerator()) {
|
||||
cloneProto = cx->global()->getOrCreateStarGeneratorFunctionPrototype(cx);
|
||||
if (!cloneProto)
|
||||
return NULL;
|
||||
}
|
||||
JSObject *cloneobj = NewObjectWithClassProto(cx, &JSFunction::class_, cloneProto,
|
||||
SkipScopeParent(parent), allocKind, newKind);
|
||||
if (!cloneobj)
|
||||
return NULL;
|
||||
|
@ -410,12 +410,22 @@ namespace js {
|
||||
extern bool
|
||||
Function(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
Generator(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern JSFunction *
|
||||
NewFunction(ExclusiveContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
|
||||
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
|
||||
gc::AllocKind allocKind = JSFunction::FinalizeKind,
|
||||
NewObjectKind newKind = GenericObject);
|
||||
|
||||
// If proto is NULL, Function.prototype is used instead.
|
||||
extern JSFunction *
|
||||
NewFunctionWithProto(ExclusiveContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
|
||||
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
|
||||
JSObject *proto, gc::AllocKind allocKind = JSFunction::FinalizeKind,
|
||||
NewObjectKind newKind = GenericObject);
|
||||
|
||||
extern JSFunction *
|
||||
DefineFunction(JSContext *cx, HandleObject obj, HandleId id, JSNative native,
|
||||
unsigned nargs, unsigned flags,
|
||||
|
@ -4445,11 +4445,6 @@ GCCycle(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gcki
|
||||
/* If we attempt to invoke the GC while we are running in the GC, assert. */
|
||||
JS_ASSERT(!rt->isHeapBusy());
|
||||
|
||||
#ifdef DEBUG
|
||||
for (ZonesIter zone(rt); !zone.done(); zone.next())
|
||||
JS_ASSERT_IF(rt->gcMode == JSGC_MODE_GLOBAL, zone->isGCScheduled());
|
||||
#endif
|
||||
|
||||
AutoGCSession gcsession(rt);
|
||||
|
||||
/*
|
||||
|
@ -958,7 +958,7 @@ const JSFunctionSpec ElementIteratorObject::methods[] = {
|
||||
};
|
||||
|
||||
static bool
|
||||
CloseGenerator(JSContext *cx, HandleObject genobj);
|
||||
CloseLegacyGenerator(JSContext *cx, HandleObject genobj);
|
||||
|
||||
bool
|
||||
js::ValueToIterator(JSContext *cx, unsigned flags, MutableHandleValue vp)
|
||||
@ -999,6 +999,30 @@ js::ValueToIterator(JSContext *cx, unsigned flags, MutableHandleValue vp)
|
||||
return GetIterator(cx, obj, flags, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
IsGenerator(HandleValue v)
|
||||
{
|
||||
return v.isObject() && v.toObject().is<GeneratorObject>();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsLegacyGenerator(HandleObject obj)
|
||||
{
|
||||
if (!obj->is<GeneratorObject>())
|
||||
return false;
|
||||
JSGenerator *gen = obj->as<GeneratorObject>().getGenerator();
|
||||
return gen->regs.fp()->script()->isLegacyGenerator();
|
||||
}
|
||||
|
||||
bool
|
||||
IsLegacyGenerator(HandleValue v)
|
||||
{
|
||||
if (!IsGenerator(v))
|
||||
return false;
|
||||
JSGenerator *gen = v.toObject().as<GeneratorObject>().getGenerator();
|
||||
return gen->regs.fp()->script()->isLegacyGenerator();
|
||||
}
|
||||
|
||||
bool
|
||||
js::CloseIterator(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
@ -1020,9 +1044,8 @@ js::CloseIterator(JSContext *cx, HandleObject obj)
|
||||
*/
|
||||
ni->props_cursor = ni->props_array;
|
||||
}
|
||||
} else if (obj->is<GeneratorObject>()) {
|
||||
// FIXME: Only close legacy generators.
|
||||
return CloseGenerator(cx, obj);
|
||||
} else if (IsLegacyGenerator(obj)) {
|
||||
return CloseLegacyGenerator(cx, obj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1477,15 +1500,25 @@ js_NewGenerator(JSContext *cx, const FrameRegs &stackRegs)
|
||||
|
||||
JS_ASSERT(stackfp->script()->isGenerator());
|
||||
|
||||
if (stackfp->script()->isStarGenerator()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_ES6_UNIMPLEMENTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &stackfp->global());
|
||||
RootedObject obj(cx);
|
||||
{
|
||||
JSObject *proto = global->getOrCreateGeneratorPrototype(cx);
|
||||
if (stackfp->script()->isStarGenerator()) {
|
||||
RootedValue pval(cx);
|
||||
RootedObject fun(cx, stackfp->fun());
|
||||
// FIXME: This would be faster if we could avoid doing a lookup to get
|
||||
// the prototype for the instance. Bug 906600.
|
||||
if (!JSObject::getProperty(cx, fun, fun, cx->names().classPrototype, &pval))
|
||||
return NULL;
|
||||
JSObject *proto = pval.isObject() ? &pval.toObject() : NULL;
|
||||
if (!proto) {
|
||||
proto = global->getOrCreateStarGeneratorObjectPrototype(cx);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
}
|
||||
obj = NewObjectWithGivenProto(cx, &GeneratorObject::class_, proto, global);
|
||||
} else {
|
||||
JS_ASSERT(stackfp->script()->isLegacyGenerator());
|
||||
JSObject *proto = global->getOrCreateLegacyGeneratorObjectPrototype(cx);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
obj = NewObjectWithGivenProto(cx, &GeneratorObject::class_, proto, global);
|
||||
@ -1623,66 +1656,17 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
|
||||
}
|
||||
|
||||
static bool
|
||||
CloseGenerator(JSContext *cx, HandleObject obj)
|
||||
CloseLegacyGenerator(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
JS_ASSERT(IsLegacyGenerator(obj));
|
||||
|
||||
JSGenerator *gen = obj->as<GeneratorObject>().getGenerator();
|
||||
if (!gen) {
|
||||
/* Generator prototype object. */
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: Assert that gen is a legacy generator.
|
||||
|
||||
if (gen->state == JSGEN_CLOSED)
|
||||
return true;
|
||||
|
||||
return SendToGenerator(cx, JSGENOP_CLOSE, obj, gen, JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE bool
|
||||
IsGenerator(HandleValue v)
|
||||
{
|
||||
return v.isObject() && v.toObject().is<GeneratorObject>();
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE bool
|
||||
generator_send_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
// FIXME: Change assertion to IsLegacyGenerator().
|
||||
JS_ASSERT(IsGenerator(args.thisv()));
|
||||
|
||||
RootedObject thisObj(cx, &args.thisv().toObject());
|
||||
|
||||
JSGenerator *gen = thisObj->as<GeneratorObject>().getGenerator();
|
||||
if (!gen || gen->state == JSGEN_CLOSED) {
|
||||
/* This happens when obj is the generator prototype. See bug 352885. */
|
||||
return js_ThrowStopIteration(cx);
|
||||
}
|
||||
|
||||
if (gen->state == JSGEN_NEWBORN && args.hasDefined(0)) {
|
||||
RootedValue val(cx, args[0]);
|
||||
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
|
||||
JSDVG_SEARCH_STACK, val, NullPtr());
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: next() takes the send value as an optional argument in ES6
|
||||
// generator objects.
|
||||
if (!SendToGenerator(cx, JSGENOP_SEND, thisObj, gen, args.get(0)))
|
||||
return false;
|
||||
|
||||
args.rval().set(gen->fp->returnValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
generator_send(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
// FIXME: send() is only a method on legacy generator objects.
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsGenerator, generator_send_impl>(cx, args);
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE bool
|
||||
generator_next_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
@ -1691,12 +1675,17 @@ generator_next_impl(JSContext *cx, CallArgs args)
|
||||
RootedObject thisObj(cx, &args.thisv().toObject());
|
||||
|
||||
JSGenerator *gen = thisObj->as<GeneratorObject>().getGenerator();
|
||||
if (!gen || gen->state == JSGEN_CLOSED) {
|
||||
/* This happens when obj is the generator prototype. See bug 352885. */
|
||||
if (gen->state == JSGEN_CLOSED)
|
||||
return js_ThrowStopIteration(cx);
|
||||
|
||||
if (gen->state == JSGEN_NEWBORN && args.hasDefined(0)) {
|
||||
RootedValue val(cx, args[0]);
|
||||
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_SEND,
|
||||
JSDVG_SEARCH_STACK, val, NullPtr());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SendToGenerator(cx, JSGENOP_NEXT, thisObj, gen, JS::UndefinedHandleValue))
|
||||
if (!SendToGenerator(cx, JSGENOP_SEND, thisObj, gen, args.get(0)))
|
||||
return false;
|
||||
|
||||
args.rval().set(gen->fp->returnValue());
|
||||
@ -1718,8 +1707,7 @@ generator_throw_impl(JSContext *cx, CallArgs args)
|
||||
RootedObject thisObj(cx, &args.thisv().toObject());
|
||||
|
||||
JSGenerator *gen = thisObj->as<GeneratorObject>().getGenerator();
|
||||
if (!gen || gen->state == JSGEN_CLOSED) {
|
||||
/* This happens when obj is the generator prototype. See bug 352885. */
|
||||
if (gen->state == JSGEN_CLOSED) {
|
||||
cx->setPendingException(args.length() >= 1 ? args[0] : UndefinedValue());
|
||||
return false;
|
||||
}
|
||||
@ -1741,14 +1729,12 @@ generator_throw(JSContext *cx, unsigned argc, Value *vp)
|
||||
JS_ALWAYS_INLINE bool
|
||||
generator_close_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
// FIXME: Change assertion to IsLegacyGenerator().
|
||||
JS_ASSERT(IsGenerator(args.thisv()));
|
||||
JS_ASSERT(IsLegacyGenerator(args.thisv()));
|
||||
|
||||
RootedObject thisObj(cx, &args.thisv().toObject());
|
||||
|
||||
JSGenerator *gen = thisObj->as<GeneratorObject>().getGenerator();
|
||||
if (!gen || gen->state == JSGEN_CLOSED) {
|
||||
/* This happens when obj is the generator prototype. See bug 352885. */
|
||||
if (gen->state == JSGEN_CLOSED) {
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
@ -1769,22 +1755,47 @@ generator_close_impl(JSContext *cx, CallArgs args)
|
||||
bool
|
||||
generator_close(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
// FIXME: close() is only a method on legacy generator objects.
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsGenerator, generator_close_impl>(cx, args);
|
||||
return CallNonGenericMethod<IsLegacyGenerator, generator_close_impl>(cx, args);
|
||||
}
|
||||
|
||||
#define JSPROP_ROPERM (JSPROP_READONLY | JSPROP_PERMANENT)
|
||||
|
||||
static const JSFunctionSpec generator_methods[] = {
|
||||
static const JSFunctionSpec legacy_generator_methods[] = {
|
||||
JS_FN("iterator", iterator_iterator, 0, 0),
|
||||
JS_FN("next", generator_next, 0,JSPROP_ROPERM),
|
||||
JS_FN("send", generator_send, 1,JSPROP_ROPERM),
|
||||
JS_FN("next", generator_next, 1,JSPROP_ROPERM),
|
||||
// Send is exactly the same as next.
|
||||
JS_FN("send", generator_next, 1,JSPROP_ROPERM),
|
||||
JS_FN("throw", generator_throw, 1,JSPROP_ROPERM),
|
||||
JS_FN("close", generator_close, 0,JSPROP_ROPERM),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
static const JSFunctionSpec star_generator_methods[] = {
|
||||
JS_FN("iterator", iterator_iterator, 0, 0),
|
||||
JS_FN("next", generator_next, 1,JSPROP_ROPERM),
|
||||
JS_FN("throw", generator_throw, 1,JSPROP_ROPERM),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
static JSObject*
|
||||
NewObjectWithObjectPrototype(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
JSObject *proto = global->getOrCreateObjectPrototype(cx);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
return NewObjectWithGivenProto(cx, &JSObject::class_, proto, global);
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
NewObjectWithFunctionPrototype(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
JSObject *proto = global->getOrCreateFunctionPrototype(cx);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
return NewObjectWithGivenProto(cx, &JSObject::class_, proto, global);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
@ -1826,11 +1837,41 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
|
||||
global->setReservedSlot(ELEMENT_ITERATOR_PROTO, ObjectValue(*proto));
|
||||
}
|
||||
|
||||
if (global->getSlot(GENERATOR_PROTO).isUndefined()) {
|
||||
proto = global->createBlankPrototype(cx, &GeneratorObject::class_);
|
||||
if (!proto || !DefinePropertiesAndBrand(cx, proto, NULL, generator_methods))
|
||||
if (global->getSlot(LEGACY_GENERATOR_OBJECT_PROTO).isUndefined()) {
|
||||
proto = NewObjectWithObjectPrototype(cx, global);
|
||||
if (!proto || !DefinePropertiesAndBrand(cx, proto, NULL, legacy_generator_methods))
|
||||
return false;
|
||||
global->setReservedSlot(GENERATOR_PROTO, ObjectValue(*proto));
|
||||
global->setReservedSlot(LEGACY_GENERATOR_OBJECT_PROTO, ObjectValue(*proto));
|
||||
}
|
||||
|
||||
if (global->getSlot(STAR_GENERATOR_OBJECT_PROTO).isUndefined()) {
|
||||
RootedObject genObjectProto(cx, NewObjectWithObjectPrototype(cx, global));
|
||||
if (!genObjectProto)
|
||||
return false;
|
||||
if (!DefinePropertiesAndBrand(cx, genObjectProto, NULL, star_generator_methods))
|
||||
return false;
|
||||
|
||||
RootedObject genFunctionProto(cx, NewObjectWithFunctionPrototype(cx, global));
|
||||
if (!genFunctionProto)
|
||||
return false;
|
||||
if (!LinkConstructorAndPrototype(cx, genFunctionProto, genObjectProto))
|
||||
return false;
|
||||
|
||||
RootedValue function(cx, global->getConstructor(JSProto_Function));
|
||||
if (!function.toObjectOrNull())
|
||||
return false;
|
||||
RootedAtom name(cx, cx->names().GeneratorFunction);
|
||||
RootedObject genFunction(cx, NewFunctionWithProto(cx, NullPtr(), Generator, 1,
|
||||
JSFunction::NATIVE_CTOR, global, name,
|
||||
&function.toObject()));
|
||||
if (!genFunction)
|
||||
return false;
|
||||
if (!LinkConstructorAndPrototype(cx, genFunction, genFunctionProto))
|
||||
return false;
|
||||
|
||||
global->setSlot(STAR_GENERATOR_OBJECT_PROTO, ObjectValue(*genObjectProto));
|
||||
global->setSlot(JSProto_GeneratorFunction, ObjectValue(*genFunction));
|
||||
global->setSlot(JSProto_GeneratorFunction + JSProto_LIMIT, ObjectValue(*genFunctionProto));
|
||||
}
|
||||
|
||||
if (global->getPrototype(JSProto_StopIteration).isUndefined()) {
|
||||
|
@ -69,5 +69,6 @@
|
||||
macro(ArrayType, 50, js_InitBinaryDataClasses) \
|
||||
macro(StructType, 51, js_InitBinaryDataClasses) \
|
||||
macro(ArrayTypeObject, 52, js_InitBinaryDataClasses) \
|
||||
macro(GeneratorFunction, 53, js_InitIteratorClasses) \
|
||||
|
||||
#endif /* jsprototypes_h */
|
||||
|
@ -236,7 +236,8 @@ js::StartOffThreadParseScript(JSContext *cx, const CompileOptions &options,
|
||||
// pointers can be changed infallibly after parsing finishes.
|
||||
if (!js_GetClassObject(cx, cx->global(), JSProto_Function, &obj) ||
|
||||
!js_GetClassObject(cx, cx->global(), JSProto_Array, &obj) ||
|
||||
!js_GetClassObject(cx, cx->global(), JSProto_RegExp, &obj))
|
||||
!js_GetClassObject(cx, cx->global(), JSProto_RegExp, &obj) ||
|
||||
!js_GetClassObject(cx, cx->global(), JSProto_GeneratorFunction, &obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -244,7 +245,8 @@ js::StartOffThreadParseScript(JSContext *cx, const CompileOptions &options,
|
||||
AutoCompartment ac(cx, global);
|
||||
if (!js_GetClassObject(cx, global, JSProto_Function, &obj) ||
|
||||
!js_GetClassObject(cx, global, JSProto_Array, &obj) ||
|
||||
!js_GetClassObject(cx, global, JSProto_RegExp, &obj))
|
||||
!js_GetClassObject(cx, global, JSProto_RegExp, &obj) ||
|
||||
!js_GetClassObject(cx, global, JSProto_GeneratorFunction, &obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
123
js/src/make-source-package.sh
Executable file
123
js/src/make-source-package.sh
Executable file
@ -0,0 +1,123 @@
|
||||
#!/bin/sh
|
||||
# need these environment vars:
|
||||
echo "Environment:"
|
||||
echo " MAKE = $MAKE"
|
||||
echo " MKDIR = $MKDIR"
|
||||
echo " TAR = $TAR"
|
||||
echo " DIST = $DIST"
|
||||
echo " SRCDIR = $SRCDIR"
|
||||
echo " MOZJS_MAJOR_VERSION = $MOZJS_MAJOR_VERSION"
|
||||
echo " MOZJS_MINOR_VERSION = $MOZJS_MINOR_VERSION"
|
||||
echo " MOZJS_PATCH_VERSION = $MOZJS_PATCH_VERSION"
|
||||
echo " MOZJS_ALPHA = $MOZJS_ALPHA"
|
||||
|
||||
cmd=${1:-build}
|
||||
pkg="mozjs-${MOZJS_MAJOR_VERSION}.${MOZJS_MINOR_VERSION}.${MOZJS_PATCH_VERSION:-${MOZJS_ALPHA:-0}}.tar.bz2"
|
||||
pkgpath=${pkg%.tar*}
|
||||
tgtpath=${DIST}/${pkgpath}
|
||||
taropts="-jcf"
|
||||
|
||||
case $cmd in
|
||||
"clean")
|
||||
echo "Cleaning ${pkg} and ${tgtpath} ..."
|
||||
rm -rf ${pkg} ${tgtpath}
|
||||
;;
|
||||
"build")
|
||||
echo "Packaging source tarball ${pkg}..."
|
||||
if [ -d ${tgtpath} ]; then
|
||||
echo "WARNING - dist tree ${tgtpath} already exists!"
|
||||
fi
|
||||
${MKDIR} -p ${tgtpath}/js/src
|
||||
|
||||
# copy the embedded icu
|
||||
${MKDIR} -p ${tgtpath}/intl
|
||||
cp -t ${tgtpath}/intl -dRp ${SRCDIR}/../../intl/icu
|
||||
|
||||
# put in js itself
|
||||
cp -t ${tgtpath} -dRp ${SRCDIR}/../../mfbt
|
||||
cp -t ${tgtpath}/js -dRp ${SRCDIR}/../jsd ${SRCDIR}/../public
|
||||
find ${SRCDIR} -mindepth 1 -maxdepth 1 -not -path ${DIST} -a -not -name ${pkg} \
|
||||
-exec cp -t ${tgtpath}/js/src -dRp {} +
|
||||
|
||||
# distclean if necessary
|
||||
if [ -e ${tgtpath}/js/src/Makefile ]; then
|
||||
${MAKE} -C ${tgtpath}/js/src distclean
|
||||
fi
|
||||
|
||||
# put in the virtualenv and supporting files if it doesnt already exist
|
||||
if [ ! -e ${SRCDIR}/build/virtualenv ]; then
|
||||
cp -t ${tgtpath}/js/src/build -dRp \
|
||||
${SRCDIR}/../../build/virtualenv \
|
||||
${SRCDIR}/../../build/buildconfig.py
|
||||
fi
|
||||
if [ ! -e ${SRCDIR}/python ]; then
|
||||
cp -t ${tgtpath}/js/src -dRp \
|
||||
${SRCDIR}/../../python
|
||||
fi
|
||||
if [ ! -e ${SRCDIR}/testing ]; then
|
||||
${MKDIR} -p ${tgtpath}/js/src/testing
|
||||
cp -t ${tgtpath}/js/src/testing -dRp \
|
||||
${SRCDIR}/../../testing/mozbase
|
||||
fi
|
||||
# end of virtualenv injection
|
||||
|
||||
# remove *.pyc and *.pyo files if any
|
||||
find ${tgtpath} -type f -name "*.pyc" -o -name "*.pyo" |xargs rm -f
|
||||
|
||||
# copy or create INSTALL
|
||||
if [ -e {DIST}/INSTALL ]; then
|
||||
cp -t ${tgtpath} ${DIST}/INSTALL
|
||||
else
|
||||
cat <<INSTALL_EOF >${tgtpath}/INSTALL
|
||||
Full build documentation for SpiderMonkey is hosted on MDN:
|
||||
https://developer.mozilla.org/en-US/docs/SpiderMonkey/Build_Documentation
|
||||
|
||||
Note that the libraries produced by the build system include symbols,
|
||||
causing the binaries to be extremely large. It is highly suggested that \`strip\`
|
||||
be run over the binaries before deploying them.
|
||||
|
||||
Building with default options may be performed as follows:
|
||||
cd js/src
|
||||
./configure
|
||||
make
|
||||
INSTALL_EOF
|
||||
fi
|
||||
|
||||
# copy or create README
|
||||
if [ -e ${DIST}/README ]; then
|
||||
cp -t ${tgtpath} ${DIST}/README
|
||||
else
|
||||
cat <<README_EOF >${tgtpath}/README
|
||||
This directory contains SpiderMonkey ${MOZJS_MAJOR_VERSION}.
|
||||
|
||||
This release is based on a revision of Mozilla ${MOZJS_MAJOR_VERSION}:
|
||||
http://hg.mozilla.org/releases/
|
||||
The changes in the patches/ directory were applied.
|
||||
|
||||
MDN hosts the latest SpiderMonkey ${MOZJS_MAJOR_VERSION} release notes:
|
||||
https://developer.mozilla.org/en-US/docs/SpiderMonkey/${MOZJS_MAJOR_VERSION}
|
||||
README_EOF
|
||||
fi
|
||||
|
||||
# copy LICENSE
|
||||
if [ -e ${SRCDIR}/../../b2g/LICENSE ]; then
|
||||
cp ${SRCDIR}/../../b2g/LICENSE ${tgtpath}/
|
||||
else
|
||||
cp ${SRCDIR}/../../LICENSE ${tgtpath}/
|
||||
fi
|
||||
|
||||
# copy patches dir, if it currently exists in DIST
|
||||
if [ -d ${DIST}/patches ]; then
|
||||
cp -t ${tgtpath} -dRp ${DIST}/patches
|
||||
elif [ -d ${SRCDIR}/../../patches ]; then
|
||||
cp -t ${tgtpath} -dRp ${SRCDIR}/../../patches
|
||||
fi
|
||||
|
||||
# Roll the tarball
|
||||
${TAR} $taropts ${DIST}/../${pkg} -C ${DIST} ${pkgpath}
|
||||
echo "done."
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognized command: $cmd"
|
||||
;;
|
||||
esac
|
150
js/src/tests/ecma_6/Generators/runtime.js
Normal file
150
js/src/tests/ecma_6/Generators/runtime.js
Normal file
@ -0,0 +1,150 @@
|
||||
// This file was written by Andy Wingo <wingo@igalia.com> and originally
|
||||
// contributed to V8 as generators-runtime.js, available here:
|
||||
//
|
||||
// http://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/harmony/generators-runtime.js
|
||||
|
||||
// Test aspects of the generator runtime.
|
||||
|
||||
// See http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.19.3.
|
||||
|
||||
function assertSyntaxError(str) {
|
||||
var msg;
|
||||
var evil = eval;
|
||||
try {
|
||||
// Non-direct eval.
|
||||
evil(str);
|
||||
} catch (exc) {
|
||||
if (exc instanceof SyntaxError)
|
||||
return;
|
||||
msg = "Assertion failed: expected SyntaxError, got " + exc;
|
||||
}
|
||||
if (msg === undefined)
|
||||
msg = "Assertion failed: expected SyntaxError, but no exception thrown";
|
||||
throw new Error(msg + " - " + str);
|
||||
}
|
||||
|
||||
function assertFalse(a) { assertEq(a, false) }
|
||||
function assertTrue(a) { assertEq(a, true) }
|
||||
function assertNotEq(found, not_expected) { assertFalse(found === expected) }
|
||||
function assertArrayEq(found, expected) {
|
||||
assertEq(found.length, expected.length);
|
||||
for (var i = 0; i < expected.length; i++)
|
||||
assertEq(found[i], expected[i]);
|
||||
}
|
||||
|
||||
|
||||
function f() { }
|
||||
function* g() { yield 1; }
|
||||
var GeneratorFunctionPrototype = Object.getPrototypeOf(g);
|
||||
var GeneratorFunction = GeneratorFunctionPrototype.constructor;
|
||||
var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
|
||||
|
||||
|
||||
// A generator function should have the same set of properties as any
|
||||
// other function.
|
||||
function TestGeneratorFunctionInstance() {
|
||||
var f_own_property_names = Object.getOwnPropertyNames(f);
|
||||
var g_own_property_names = Object.getOwnPropertyNames(g);
|
||||
|
||||
f_own_property_names.sort();
|
||||
g_own_property_names.sort();
|
||||
|
||||
assertArrayEq(f_own_property_names, g_own_property_names);
|
||||
var i;
|
||||
for (i = 0; i < f_own_property_names.length; i++) {
|
||||
var prop = f_own_property_names[i];
|
||||
var f_desc = Object.getOwnPropertyDescriptor(f, prop);
|
||||
var g_desc = Object.getOwnPropertyDescriptor(g, prop);
|
||||
assertEq(f_desc.configurable, g_desc.configurable, prop);
|
||||
assertEq(f_desc.writable, g_desc.writable, prop);
|
||||
assertEq(f_desc.enumerable, g_desc.enumerable, prop);
|
||||
}
|
||||
}
|
||||
TestGeneratorFunctionInstance();
|
||||
|
||||
|
||||
// Generators have an additional object interposed in the chain between
|
||||
// themselves and Function.prototype.
|
||||
function TestGeneratorFunctionPrototype() {
|
||||
// Sanity check.
|
||||
assertEq(Object.getPrototypeOf(f), Function.prototype);
|
||||
assertNotEq(GeneratorFunctionPrototype, Function.prototype);
|
||||
assertEq(Object.getPrototypeOf(GeneratorFunctionPrototype),
|
||||
Function.prototype);
|
||||
assertEq(Object.getPrototypeOf(function* () {}),
|
||||
GeneratorFunctionPrototype);
|
||||
}
|
||||
TestGeneratorFunctionPrototype();
|
||||
|
||||
|
||||
// Functions that we associate with generator objects are actually defined by
|
||||
// a common prototype.
|
||||
function TestGeneratorObjectPrototype() {
|
||||
assertEq(Object.getPrototypeOf(GeneratorObjectPrototype),
|
||||
Object.prototype);
|
||||
assertEq(Object.getPrototypeOf((function*(){yield 1}).prototype),
|
||||
GeneratorObjectPrototype);
|
||||
|
||||
var expected_property_names = ["iterator", "next", "throw", "constructor"];
|
||||
var found_property_names =
|
||||
Object.getOwnPropertyNames(GeneratorObjectPrototype);
|
||||
|
||||
expected_property_names.sort();
|
||||
found_property_names.sort();
|
||||
|
||||
assertArrayEq(found_property_names, expected_property_names);
|
||||
}
|
||||
TestGeneratorObjectPrototype();
|
||||
|
||||
|
||||
// This tests the object that would be called "GeneratorFunction", if it were
|
||||
// like "Function".
|
||||
function TestGeneratorFunction() {
|
||||
assertEq(GeneratorFunctionPrototype, GeneratorFunction.prototype);
|
||||
assertTrue(g instanceof GeneratorFunction);
|
||||
|
||||
assertEq(Function, Object.getPrototypeOf(GeneratorFunction));
|
||||
assertTrue(g instanceof Function);
|
||||
|
||||
assertEq("function* g() { yield 1; }", g.toString());
|
||||
|
||||
// Not all functions are generators.
|
||||
assertTrue(f instanceof Function); // Sanity check.
|
||||
assertFalse(f instanceof GeneratorFunction);
|
||||
|
||||
assertTrue((new GeneratorFunction()) instanceof GeneratorFunction);
|
||||
assertTrue(GeneratorFunction() instanceof GeneratorFunction);
|
||||
|
||||
assertTrue(GeneratorFunction('yield 1') instanceof GeneratorFunction);
|
||||
assertTrue(GeneratorFunction('return 1') instanceof GeneratorFunction);
|
||||
assertTrue(GeneratorFunction('a', 'yield a') instanceof GeneratorFunction);
|
||||
assertTrue(GeneratorFunction('a', 'return a') instanceof GeneratorFunction);
|
||||
assertTrue(GeneratorFunction('a', 'return a') instanceof GeneratorFunction);
|
||||
assertSyntaxError("GeneratorFunction('yield', 'return yield')");
|
||||
assertTrue(GeneratorFunction('with (x) return foo;') instanceof GeneratorFunction);
|
||||
assertSyntaxError("GeneratorFunction('\"use strict\"; with (x) return foo;')");
|
||||
|
||||
// Doesn't matter particularly what string gets serialized, as long
|
||||
// as it contains "function*" and "yield 10".
|
||||
assertEq(GeneratorFunction('yield 10').toString(),
|
||||
"function* anonymous() {\nyield 10\n}");
|
||||
}
|
||||
TestGeneratorFunction();
|
||||
|
||||
|
||||
function TestPerGeneratorPrototype() {
|
||||
assertNotEq((function*(){}).prototype, (function*(){}).prototype);
|
||||
assertNotEq((function*(){}).prototype, g.prototype);
|
||||
assertEq(typeof GeneratorFunctionPrototype, "object");
|
||||
assertEq(g.prototype.__proto__.constructor, GeneratorFunctionPrototype, "object");
|
||||
assertEq(Object.getPrototypeOf(g.prototype), GeneratorObjectPrototype);
|
||||
assertFalse(g.prototype instanceof Function);
|
||||
assertEq(typeof (g.prototype), "object");
|
||||
|
||||
assertArrayEq(Object.getOwnPropertyNames(g.prototype), []);
|
||||
}
|
||||
TestPerGeneratorPrototype();
|
||||
|
||||
|
||||
if (typeof reportCompare == "function")
|
||||
reportCompare(true, true);
|
@ -26,34 +26,35 @@ function test()
|
||||
|
||||
try {
|
||||
proto.next();
|
||||
throw "generatorProto.next() does not throw StopIteration";
|
||||
throw "generatorProto.next() does not throw TypeError";
|
||||
} catch (e) {
|
||||
if (!(e instanceof StopIteration))
|
||||
if (!(e instanceof TypeError))
|
||||
throw "generatorProto.next() throws unexpected exception: "+uneval(e);
|
||||
}
|
||||
|
||||
try {
|
||||
proto.send();
|
||||
throw "generatorProto.send() does not throw StopIteration";
|
||||
throw "generatorProto.send() does not throw TypeError";
|
||||
} catch (e) {
|
||||
if (!(e instanceof StopIteration))
|
||||
if (!(e instanceof TypeError))
|
||||
throw "generatorProto.send() throws unexpected exception: "+uneval(e);
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
try {
|
||||
proto.throw(obj);
|
||||
throw "generatorProto.throw(obj) does not throw obj";
|
||||
throw "generatorProto.throw(obj) does not throw TypeError";
|
||||
} catch (e) {
|
||||
if (e !== obj)
|
||||
if (!(e instanceof TypeError))
|
||||
throw "generatorProto.throw() throws unexpected exception: "+uneval(e);
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
try {
|
||||
proto.close();
|
||||
throw "generatorProto.close() does not throw TypeError";
|
||||
} catch (e) {
|
||||
throw "generatorProto.throw() throws exception: "+uneval(e);
|
||||
if (!(e instanceof TypeError))
|
||||
throw "generatorProto.close() throws unexpected exception: "+uneval(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -90,8 +90,9 @@ class GlobalObject : public JSObject
|
||||
|
||||
/* One-off properties stored after slots for built-ins. */
|
||||
static const unsigned ELEMENT_ITERATOR_PROTO = FROM_BUFFER_UINT8CLAMPED + 1;
|
||||
static const unsigned GENERATOR_PROTO = ELEMENT_ITERATOR_PROTO + 1;
|
||||
static const unsigned MAP_ITERATOR_PROTO = GENERATOR_PROTO + 1;
|
||||
static const unsigned LEGACY_GENERATOR_OBJECT_PROTO = ELEMENT_ITERATOR_PROTO + 1;
|
||||
static const unsigned STAR_GENERATOR_OBJECT_PROTO = LEGACY_GENERATOR_OBJECT_PROTO + 1;
|
||||
static const unsigned MAP_ITERATOR_PROTO = STAR_GENERATOR_OBJECT_PROTO + 1;
|
||||
static const unsigned SET_ITERATOR_PROTO = MAP_ITERATOR_PROTO + 1;
|
||||
static const unsigned COLLATOR_PROTO = SET_ITERATOR_PROTO + 1;
|
||||
static const unsigned NUMBER_FORMAT_PROTO = COLLATOR_PROTO + 1;
|
||||
@ -364,8 +365,21 @@ class GlobalObject : public JSObject
|
||||
return getOrCreateObject(cx, ELEMENT_ITERATOR_PROTO, initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateGeneratorPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, GENERATOR_PROTO, initIteratorClasses);
|
||||
JSObject *getOrCreateLegacyGeneratorObjectPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, LEGACY_GENERATOR_OBJECT_PROTO, initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateStarGeneratorObjectPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, STAR_GENERATOR_OBJECT_PROTO, initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateStarGeneratorFunctionPrototype(JSContext *cx) {
|
||||
return getOrCreateObject(cx, JSProto_LIMIT + JSProto_GeneratorFunction,
|
||||
initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateStarGeneratorFunction(JSContext *cx) {
|
||||
return getOrCreateObject(cx, JSProto_GeneratorFunction, initIteratorClasses);
|
||||
}
|
||||
|
||||
JSObject *getOrCreateMapIteratorPrototype(JSContext *cx) {
|
||||
|
@ -1665,6 +1665,14 @@ WrapPreserve3DListInternal(nsIFrame* aFrame, nsDisplayListBuilder *aBuilder, nsD
|
||||
if (!aTemp->IsEmpty()) {
|
||||
aOutput->AppendToTop(new (aBuilder) nsDisplayTransform(aBuilder, aFrame, aTemp, aIndex++));
|
||||
}
|
||||
// Override item's clipping with our current clip state (if any). Since we're
|
||||
// bubbling up a preserve-3d transformed child to a preserve-3d parent,
|
||||
// we can be sure the child doesn't have clip state of its own.
|
||||
NS_ASSERTION(!item->GetClip().HasClip(), "Unexpected clip on item");
|
||||
const DisplayItemClip* clip = aBuilder->ClipState().GetCurrentCombinedClip(aBuilder);
|
||||
if (clip) {
|
||||
item->SetClip(aBuilder, *clip);
|
||||
}
|
||||
aOutput->AppendToTop(item);
|
||||
break;
|
||||
}
|
||||
|
32
layout/reftests/bugs/906199-1-ref.html
Normal file
32
layout/reftests/bugs/906199-1-ref.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
div {
|
||||
position:relative;
|
||||
width:300px;
|
||||
height:200px;
|
||||
left:50px;
|
||||
top:50px;
|
||||
}
|
||||
.grandparentdiv {
|
||||
background:yellow;
|
||||
overflow:hidden;
|
||||
}
|
||||
.childdiv {
|
||||
background:green;
|
||||
}
|
||||
.grandchilddiv {
|
||||
background:red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="grandparentdiv">
|
||||
<div class="childdiv">
|
||||
<div class="grandchilddiv"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
33
layout/reftests/bugs/906199-1.html
Normal file
33
layout/reftests/bugs/906199-1.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
div {
|
||||
position:relative;
|
||||
width:300px;
|
||||
height:200px;
|
||||
left:50px;
|
||||
top:50px;
|
||||
transform-style:preserve-3d;
|
||||
}
|
||||
.grandparentdiv {
|
||||
background:yellow;
|
||||
overflow:hidden;
|
||||
}
|
||||
.childdiv {
|
||||
background:green;
|
||||
}
|
||||
.grandchilddiv {
|
||||
background:red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="grandparentdiv">
|
||||
<div class="childdiv">
|
||||
<div class="grandchilddiv"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1772,6 +1772,7 @@ test-pref(layout.css.flexbox.enabled,true) == 849407-1.html 849407-1-ref.html
|
||||
== 883987-1f.html 883987-1-ref.html
|
||||
== 890495-1.html 890495-1-ref.html
|
||||
== 894931-1.html 894931-1-ref.html
|
||||
fuzzy(1,10000) == 902330-1.html 902330-1-ref.html
|
||||
== 897491-1.html 897491-1-ref.html
|
||||
== 897491-2.html 897491-2-ref.html
|
||||
fuzzy(1,10000) == 902330-1.html 902330-1-ref.html
|
||||
fuzzy-if(Android,4,245) == 906199-1.html 906199-1-ref.html
|
||||
|
@ -30,14 +30,13 @@
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsINode.h"
|
||||
|
||||
// dbeabbfa-6cb3-4f5c-aec2-dd558d9d681f
|
||||
#define NS_ICSSDECLARATION_IID \
|
||||
{ 0xdbeabbfa, 0x6cb3, 0x4f5c, \
|
||||
{ 0xae, 0xc2, 0xdd, 0x55, 0x8d, 0x9d, 0x68, 0x1f } }
|
||||
|
||||
class nsINode;
|
||||
|
||||
class nsICSSDeclaration : public nsIDOMCSSStyleDeclaration,
|
||||
public nsWrapperCache
|
||||
{
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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/. */
|
||||
|
||||
@ -4401,6 +4403,189 @@ fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb_p, sdp_media_e
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_add_rtcp_fb
|
||||
*
|
||||
* Description:
|
||||
* Adds a=rtcp-fb attributes to local SDP for supported video codecs
|
||||
*
|
||||
* Parameters:
|
||||
* level - SDP media level (between 1 and the # of m-lines)
|
||||
* sdp_p - pointer to local SDP
|
||||
* codec - the codec type that the attributes should be added for
|
||||
* types - a bitmask of rtcp-fb types to add, taken from
|
||||
* sdp_rtcp_fb_bitmask_e
|
||||
*
|
||||
* returns
|
||||
* CC_CAUSE_OK - success
|
||||
* any other code - failure
|
||||
*/
|
||||
cc_causes_t
|
||||
gsmsdp_add_rtcp_fb (int level, sdp_t *sdp_p,
|
||||
rtp_ptype codec, unsigned int types)
|
||||
{
|
||||
int num_pts;
|
||||
int pt_codec;
|
||||
sdp_payload_ind_e indicator;
|
||||
|
||||
int pt_index;
|
||||
unsigned int j;
|
||||
num_pts = sdp_get_media_num_payload_types(sdp_p, level);
|
||||
for (pt_index = 1; pt_index <= num_pts; pt_index++) {
|
||||
pt_codec = sdp_get_media_payload_type (sdp_p, level, pt_index,
|
||||
&indicator);
|
||||
if ((pt_codec & 0xFF) == codec) {
|
||||
int pt = GET_DYN_PAYLOAD_TYPE_VALUE(pt_codec);
|
||||
|
||||
/* Add requested a=rtcp-fb:nack attributes */
|
||||
for (j = 0; j < SDP_MAX_RTCP_FB_NACK; j++) {
|
||||
if (types & SDP_RTCP_FB_NACK_TO_BITMAP(j)) {
|
||||
gsmsdp_set_rtcp_fb_nack_attribute(level, sdp_p, pt, j);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add requested a=rtcp-fb:ack attributes */
|
||||
for (j = 0; j < SDP_MAX_RTCP_FB_ACK; j++) {
|
||||
if (types & SDP_RTCP_FB_ACK_TO_BITMAP(j)) {
|
||||
gsmsdp_set_rtcp_fb_nack_attribute(level, sdp_p, pt, j);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add requested a=rtcp-fb:ccm attributes */
|
||||
for (j = 0; j < SDP_MAX_RTCP_FB_CCM; j++) {
|
||||
if (types & SDP_RTCP_FB_CCM_TO_BITMAP(j)) {
|
||||
gsmsdp_set_rtcp_fb_ccm_attribute(level, sdp_p, pt, j);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return CC_CAUSE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gsmsdp_negotiate_rtcp_fb
|
||||
*
|
||||
* Description:
|
||||
* Negotiates a=rtcp-fb attributes to local SDP for supported video codecs
|
||||
*
|
||||
* Parameters:
|
||||
* cc_sdp_p - local and remote SDP
|
||||
* media - The media structure for the current level to be negotiated
|
||||
* offer - True if the remote SDP is an offer
|
||||
*
|
||||
* returns
|
||||
* CC_CAUSE_OK - success
|
||||
* any other code - failure
|
||||
*/
|
||||
cc_causes_t
|
||||
gsmsdp_negotiate_rtcp_fb (cc_sdp_t *cc_sdp_p,
|
||||
fsmdef_media_t *media,
|
||||
boolean offer)
|
||||
{
|
||||
int level = media->level;
|
||||
int pt_codec;
|
||||
int remote_pt;
|
||||
sdp_payload_ind_e indicator;
|
||||
int pt_index, i;
|
||||
sdp_rtcp_fb_nack_type_e nack_type;
|
||||
sdp_rtcp_fb_ack_type_e ack_type;
|
||||
sdp_rtcp_fb_ccm_type_e ccm_type;
|
||||
uint32_t fb_types = 0;
|
||||
|
||||
int num_pts = sdp_get_media_num_payload_types(cc_sdp_p->dest_sdp, level);
|
||||
|
||||
/*
|
||||
* Remove any previously negotiated rtcp-fb attributes from the
|
||||
* local SDP
|
||||
*/
|
||||
sdp_result_e result = SDP_SUCCESS;
|
||||
while (result == SDP_SUCCESS) {
|
||||
result = sdp_delete_attr (cc_sdp_p->src_sdp, level, 0,
|
||||
SDP_ATTR_RTCP_FB, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* For each remote payload type, determine what feedback types are
|
||||
* requested.
|
||||
*/
|
||||
for (pt_index = 1; pt_index <= num_pts; pt_index++) {
|
||||
int pt_codec = sdp_get_media_payload_type (cc_sdp_p->dest_sdp,
|
||||
level, pt_index, &indicator);
|
||||
int codec = pt_codec & 0xFF;
|
||||
remote_pt = GET_DYN_PAYLOAD_TYPE_VALUE(pt_codec);
|
||||
fb_types = 0;
|
||||
|
||||
/* a=rtcp-fb:nack */
|
||||
i = 1;
|
||||
do {
|
||||
nack_type = sdp_attr_get_rtcp_fb_nack(cc_sdp_p->dest_sdp,
|
||||
level, remote_pt, i);
|
||||
if (nack_type >= 0 && nack_type < SDP_MAX_RTCP_FB_NACK) {
|
||||
fb_types |= SDP_RTCP_FB_NACK_TO_BITMAP(nack_type);
|
||||
}
|
||||
i++;
|
||||
} while (nack_type != SDP_RTCP_FB_NACK_NOT_FOUND);
|
||||
|
||||
/* a=rtcp-fb:ack */
|
||||
i = 1;
|
||||
do {
|
||||
ack_type = sdp_attr_get_rtcp_fb_ack(cc_sdp_p->dest_sdp,
|
||||
level, remote_pt, i);
|
||||
if (ack_type >= 0 && ack_type < SDP_MAX_RTCP_FB_ACK) {
|
||||
fb_types |= SDP_RTCP_FB_ACK_TO_BITMAP(ack_type);
|
||||
}
|
||||
i++;
|
||||
} while (ack_type != SDP_RTCP_FB_CCM_NOT_FOUND);
|
||||
|
||||
/* a=rtcp-fb:ccm */
|
||||
i = 1;
|
||||
do {
|
||||
ccm_type = sdp_attr_get_rtcp_fb_ccm(cc_sdp_p->dest_sdp,
|
||||
level, remote_pt, i);
|
||||
if (ccm_type >= 0 && ccm_type < SDP_MAX_RTCP_FB_CCM) {
|
||||
fb_types |= SDP_RTCP_FB_CCM_TO_BITMAP(ccm_type);
|
||||
}
|
||||
i++;
|
||||
} while (ccm_type != SDP_RTCP_FB_CCM_NOT_FOUND);
|
||||
|
||||
/*
|
||||
* Mask out the types that we do not support
|
||||
*/
|
||||
switch (codec) {
|
||||
case RTP_VP8:
|
||||
fb_types &=
|
||||
SDP_RTCP_FB_NACK_TO_BITMAP(SDP_RTCP_FB_NACK_BASIC) |
|
||||
SDP_RTCP_FB_NACK_TO_BITMAP(SDP_RTCP_FB_NACK_PLI) |
|
||||
SDP_RTCP_FB_CCM_TO_BITMAP(SDP_RTCP_FB_CCM_FIR);
|
||||
break;
|
||||
default:
|
||||
fb_types = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, in our local SDP, set rtcp-fb types that both we and the
|
||||
* remote party support
|
||||
*/
|
||||
if (fb_types) {
|
||||
gsmsdp_add_rtcp_fb (level, cc_sdp_p->src_sdp, codec, fb_types);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, update the media record for this payload type to
|
||||
* reflect the expected feedback types
|
||||
*/
|
||||
for (i = 0; i < media->num_payloads; i++) {
|
||||
if (media->payloads[i].remote_rtp_pt == remote_pt) {
|
||||
media->payloads[i].video.rtcp_fb_types = fb_types;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CC_CAUSE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* gsmsdp_negotiate_media_lines
|
||||
*
|
||||
@ -4731,6 +4916,11 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
|
||||
update_local_ret_value = TRUE;
|
||||
}
|
||||
|
||||
/* Negotiate rtcp feedback mechanisms */
|
||||
if (media && media_type == SDP_MEDIA_VIDEO) {
|
||||
gsmsdp_negotiate_rtcp_fb (dcb_p->sdp, media, offer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Negotiate rtcp-mux
|
||||
*/
|
||||
@ -4815,19 +5005,6 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO (abr) -- temporarily hardcode rtcb-fb attributes to match our
|
||||
actual behavior. This really needs to be a negotiation, with the
|
||||
results of the negotiation propagating into the codec configuration.
|
||||
See Bug 880067. */
|
||||
if (media && media_type == SDP_MEDIA_VIDEO) {
|
||||
gsmsdp_set_rtcp_fb_nack_attribute(media->level, sdp_p->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
gsmsdp_set_rtcp_fb_ccm_attribute(media->level, sdp_p->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_CCM_FIR);
|
||||
}
|
||||
|
||||
if (unsupported_line) {
|
||||
/* add this line to unsupported line */
|
||||
gsmsdp_add_unsupported_stream_to_local_sdp(sdp_p, i);
|
||||
@ -5271,6 +5448,14 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
|
||||
|
||||
gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction);
|
||||
|
||||
/* Add supported rtcp-fb types */
|
||||
if (media_cap->type == SDP_MEDIA_VIDEO) {
|
||||
gsmsdp_add_rtcp_fb (level, dcb_p->sdp->src_sdp, RTP_VP8,
|
||||
SDP_RTCP_FB_NACK_TO_BITMAP(SDP_RTCP_FB_NACK_BASIC) |
|
||||
SDP_RTCP_FB_NACK_TO_BITMAP(SDP_RTCP_FB_NACK_PLI) |
|
||||
SDP_RTCP_FB_CCM_TO_BITMAP(SDP_RTCP_FB_CCM_FIR));
|
||||
}
|
||||
|
||||
/*
|
||||
* wait until here to set ICE candidates as SDP is now initialized
|
||||
*/
|
||||
@ -5397,20 +5582,6 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
|
||||
level = level - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO (abr) -- temporarily hardcode rtcb-fb attributes to match
|
||||
our actual behavior. This really needs to be a negotiation, with
|
||||
the results of the negotiation propagating into the codec
|
||||
configuration. See Bug 880067. */
|
||||
if (media_cap->type == SDP_MEDIA_VIDEO) {
|
||||
gsmsdp_set_rtcp_fb_nack_attribute(level, dcb_p->sdp->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
gsmsdp_set_rtcp_fb_ccm_attribute(level, dcb_p->sdp->src_sdp,
|
||||
SDP_ALL_PAYLOADS,
|
||||
SDP_RTCP_FB_CCM_FIR);
|
||||
}
|
||||
|
||||
}
|
||||
/* next capability */
|
||||
media_cap++;
|
||||
|
@ -488,7 +488,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
SDP_RTCP_FB_NACK_NOT_FOUND = -1,
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED = 0,
|
||||
SDP_RTCP_FB_NACK_BASIC = 0,
|
||||
SDP_RTCP_FB_NACK_SLI,
|
||||
SDP_RTCP_FB_NACK_PLI,
|
||||
SDP_RTCP_FB_NACK_RPSI,
|
||||
@ -519,6 +519,11 @@ typedef enum {
|
||||
SDP_RTCP_FB_CCM_UNKNOWN
|
||||
} sdp_rtcp_fb_ccm_type_e;
|
||||
|
||||
#define SDP_RTCP_FB_NACK_TO_BITMAP(type) (1 << (type))
|
||||
#define SDP_RTCP_FB_ACK_TO_BITMAP(type) (1 << (SDP_MAX_RTCP_FB_NACK + (type)))
|
||||
#define SDP_RTCP_FB_CCM_TO_BITMAP(type) (1 << (SDP_MAX_RTCP_FB_NACK + \
|
||||
SDP_MAX_RTCP_FB_ACK + (type)))
|
||||
|
||||
/*
|
||||
* sdp_srtp_fec_order_t
|
||||
* This type defines the order in which to perform FEC
|
||||
|
@ -4784,7 +4784,7 @@ sdp_result_e sdp_build_attr_rtcp_fb(sdp_t *sdp_p,
|
||||
}
|
||||
break;
|
||||
case SDP_RTCP_FB_NACK:
|
||||
if (attr_p->attr.rtcp_fb.param.nack > SDP_RTCP_FB_NACK_UNSPECIFIED
|
||||
if (attr_p->attr.rtcp_fb.param.nack > SDP_RTCP_FB_NACK_BASIC
|
||||
&& attr_p->attr.rtcp_fb.param.nack < SDP_MAX_RTCP_FB_NACK) {
|
||||
flex_string_sprintf(fs, " %s",
|
||||
sdp_rtcp_fb_nack_type_val[attr_p->attr.rtcp_fb.param.nack]
|
||||
@ -4935,7 +4935,7 @@ sdp_result_e sdp_parse_attr_rtcp_fb (sdp_t *sdp_p,
|
||||
}
|
||||
/* Check for empty string */
|
||||
if (*ptr == '\r') {
|
||||
rtcp_fb_p->param.nack = SDP_RTCP_FB_NACK_UNSPECIFIED;
|
||||
rtcp_fb_p->param.nack = SDP_RTCP_FB_NACK_BASIC;
|
||||
break;
|
||||
}
|
||||
i = find_token_enum("rtcp-fb nack type", sdp_p, &ptr,
|
||||
|
@ -185,6 +185,7 @@ typedef struct
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
uint32_t rtcp_fb_types;
|
||||
} video;
|
||||
};
|
||||
|
||||
|
@ -167,7 +167,7 @@ class SdpTest : public ::testing::Test {
|
||||
return inst_num;
|
||||
}
|
||||
|
||||
u16 AddNewRtcpTrrInt(int level, u32 interval,
|
||||
u16 AddNewRtcpFbTrrInt(int level, u32 interval,
|
||||
u16 payload = SDP_ALL_PAYLOADS) {
|
||||
u16 inst_num = 0;
|
||||
EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
|
||||
@ -233,7 +233,7 @@ TEST_F(SdpTest, parseRtcpFbAckFooBarBaz) {
|
||||
TEST_F(SdpTest, parseRtcpFbNack) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack\r\n");
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
SDP_RTCP_FB_NACK_BASIC);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbNackPli) {
|
||||
@ -381,7 +381,7 @@ TEST_F(SdpTest, parseRtcpFbKitchenSink) {
|
||||
SDP_RTCP_FB_ACK_NOT_FOUND);
|
||||
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
|
||||
SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
SDP_RTCP_FB_NACK_BASIC);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 2),
|
||||
SDP_RTCP_FB_NACK_PLI);
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 3),
|
||||
@ -422,16 +422,42 @@ TEST_F(SdpTest, parseRtcpFbKitchenSink) {
|
||||
SDP_RTCP_FB_CCM_NOT_FOUND);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbAckRpsi) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_RPSI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 ack rpsi\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
/* TODO (abr@mozilla.com) These attribute adding test cases definitely need
|
||||
beefing up; for now, I'm testing the two use cases that we know
|
||||
we need right now. An exhaustive check of the various permutations
|
||||
will look similar to the parsing tests, above */
|
||||
TEST_F(SdpTest, addRtcpFbAckRpsiAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_RPSI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ack rpsi\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbAckApp) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_APP, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 ack app\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbAckAppAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_APP);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ack app\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNack) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_UNSPECIFIED, 120);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_BASIC, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack\r\n"), std::string::npos);
|
||||
}
|
||||
@ -439,11 +465,154 @@ TEST_F(SdpTest, addRtcpFbNack) {
|
||||
TEST_F(SdpTest, addRtcpFbNackAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_UNSPECIFIED);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_BASIC);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackSli) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_SLI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack sli\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackSliAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_SLI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack sli\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackPli) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PLI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack pli\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackPliAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PLI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack pli\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackRpsi) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RPSI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack rpsi\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackRpsiAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RPSI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack rpsi\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackApp) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_APP, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack app\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackAppAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_APP);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack app\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackRai) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RAI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack rai\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackRaiAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RAI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack rai\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackTllei) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_TLLEI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack tllei\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackTlleiAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_TLLEI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack tllei\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackPslei) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PSLEI, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack pslei\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackPsleiAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PSLEI);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack pslei\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackEcn) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_ECN, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 nack ecn\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackEcnAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_ECN);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* nack ecn\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbTrrInt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbTrrInt(level, 12345, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 trr-int 12345\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbNackTrrIntAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbTrrInt(level, 0);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* trr-int 0\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmFir) {
|
||||
InitLocalSdp();
|
||||
@ -461,7 +630,61 @@ TEST_F(SdpTest, addRtcpFbCcmFirAllPt) {
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ccm fir\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
/* TODO We need to test the pt=* use cases. */
|
||||
TEST_F(SdpTest, addRtcpFbCcmTmmbr) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TMMBR, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 ccm tmmbr\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmTmmbrAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TMMBR);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ccm tmmbr\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmTstr) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TSTR, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 ccm tstr\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmTstrAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TSTR);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ccm tstr\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmVbcm) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_VBCM, 120);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:120 ccm vbcm\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, addRtcpFbCcmVbcmAllPt) {
|
||||
InitLocalSdp();
|
||||
int level = AddNewMedia(SDP_MEDIA_VIDEO);
|
||||
AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_VBCM);
|
||||
std::string body = SerializeSdp();
|
||||
ASSERT_NE(body.find("a=rtcp-fb:* ccm vbcm\r\n"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(SdpTest, parseRtcpFbAllPayloads) {
|
||||
ParseSdp(kVideoSdp + "a=rtcp-fb:* ack rpsi\r\n");
|
||||
for (int i = 0; i < 128; i++) {
|
||||
ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, i, 1),
|
||||
SDP_RTCP_FB_ACK_RPSI);
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace test.
|
||||
|
||||
|
@ -1885,6 +1885,8 @@ TEST_F(SignalingTest, ChromeOfferAnswer)
|
||||
"a=rtpmap:100 VP8/90000\r\n"
|
||||
"a=rtpmap:101 red/90000\r\n"
|
||||
"a=rtpmap:102 ulpfec/90000\r\n"
|
||||
"a=rtcp-fb:100 nack\r\n"
|
||||
"a=rtcp-fb:100 ccm fir\r\n"
|
||||
"a=ssrc:3012607008 cname:KIXaNxUlU5DP3fVS\r\n"
|
||||
"a=ssrc:3012607008 msid:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5 v0\r\n"
|
||||
"a=ssrc:3012607008 mslabel:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5\r\n"
|
||||
|
@ -66,7 +66,10 @@ public class GeckoEvent {
|
||||
CALL_OBSERVER(33),
|
||||
REMOVE_OBSERVER(34),
|
||||
LOW_MEMORY(35),
|
||||
NETWORK_LINK_CHANGE(36);
|
||||
NETWORK_LINK_CHANGE(36),
|
||||
TELEMETRY_HISTOGRAM_ADD(37),
|
||||
PREFERENCES_OBSERVE(38),
|
||||
PREFERENCES_GET(39);
|
||||
|
||||
public final int value;
|
||||
|
||||
@ -185,6 +188,8 @@ public class GeckoEvent {
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
|
||||
private String[] mPrefNames;
|
||||
|
||||
private GeckoEvent(NativeGeckoEvent event) {
|
||||
mType = event.value;
|
||||
}
|
||||
@ -688,6 +693,20 @@ public class GeckoEvent {
|
||||
return event;
|
||||
}
|
||||
|
||||
public static GeckoEvent createPreferencesObserveEvent(int requestId, String[] prefNames) {
|
||||
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.PREFERENCES_OBSERVE);
|
||||
event.mCount = requestId;
|
||||
event.mPrefNames = prefNames;
|
||||
return event;
|
||||
}
|
||||
|
||||
public static GeckoEvent createPreferencesGetEvent(int requestId, String[] prefNames) {
|
||||
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.PREFERENCES_GET);
|
||||
event.mCount = requestId;
|
||||
event.mPrefNames = prefNames;
|
||||
return event;
|
||||
}
|
||||
|
||||
public static GeckoEvent createLowMemoryEvent(int level) {
|
||||
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.LOW_MEMORY);
|
||||
event.mMetaState = level;
|
||||
@ -700,6 +719,14 @@ public class GeckoEvent {
|
||||
return event;
|
||||
}
|
||||
|
||||
public static GeckoEvent createTelemetryHistogramAddEvent(String histogram,
|
||||
int value) {
|
||||
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
|
||||
event.mCharacters = histogram;
|
||||
event.mCount = value;
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setAckNeeded(boolean ackNeeded) {
|
||||
mAckNeeded = ackNeeded;
|
||||
}
|
||||
|
@ -664,9 +664,7 @@ public class GeckoPreferences
|
||||
|
||||
// Initialize preferences by requesting the preference values from Gecko
|
||||
private int getGeckoPreferences(final PreferenceGroup screen, ArrayList<String> prefs) {
|
||||
JSONArray jsonPrefs = new JSONArray(prefs);
|
||||
|
||||
return PrefsHelper.getPrefs(jsonPrefs, new PrefsHelper.PrefHandlerBase() {
|
||||
return PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() {
|
||||
private Preference getField(String prefName) {
|
||||
return screen.findPreference(prefName);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import org.json.JSONObject;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -27,20 +28,18 @@ public final class PrefsHelper {
|
||||
private static int sUniqueRequestId = 1;
|
||||
|
||||
public static int getPref(String prefName, PrefHandler callback) {
|
||||
JSONArray prefs = new JSONArray();
|
||||
prefs.put(prefName);
|
||||
return getPrefs(prefs, callback);
|
||||
return getPrefsInternal(new String[] { prefName }, callback);
|
||||
}
|
||||
|
||||
public static int getPrefs(String[] prefNames, PrefHandler callback) {
|
||||
JSONArray prefs = new JSONArray();
|
||||
for (String p : prefNames) {
|
||||
prefs.put(p);
|
||||
}
|
||||
return getPrefs(prefs, callback);
|
||||
return getPrefsInternal(prefNames, callback);
|
||||
}
|
||||
|
||||
public static int getPrefs(JSONArray prefNames, PrefHandler callback) {
|
||||
public static int getPrefs(ArrayList<String> prefNames, PrefHandler callback) {
|
||||
return getPrefsInternal(prefNames.toArray(new String[prefNames.size()]), callback);
|
||||
}
|
||||
|
||||
private static int getPrefsInternal(String[] prefNames, PrefHandler callback) {
|
||||
int requestId;
|
||||
synchronized (PrefsHelper.class) {
|
||||
ensureRegistered();
|
||||
@ -50,25 +49,12 @@ public final class PrefsHelper {
|
||||
}
|
||||
|
||||
GeckoEvent event;
|
||||
try {
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", Integer.toString(requestId));
|
||||
message.put("preferences", prefNames);
|
||||
event = GeckoEvent.createBroadcastEvent(callback.isObserver() ?
|
||||
"Preferences:Observe" : "Preferences:Get", message.toString());
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "Error while composing Preferences:" +
|
||||
(callback.isObserver() ? "Observe" : "Get") + " message", e);
|
||||
|
||||
// if we failed to send the message, drop our reference to the callback because
|
||||
// otherwise it will leak since we will never get the response
|
||||
synchronized (PrefsHelper.class) {
|
||||
sCallbacks.remove(requestId);
|
||||
}
|
||||
|
||||
return -1;
|
||||
if (callback.isObserver()) {
|
||||
event = GeckoEvent.createPreferencesObserveEvent(requestId, prefNames);
|
||||
} else {
|
||||
event = GeckoEvent.createPreferencesGetEvent(requestId, prefNames);
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
|
||||
return requestId;
|
||||
}
|
||||
|
@ -35,6 +35,14 @@ public class RobocopAPI {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(subject, data));
|
||||
}
|
||||
|
||||
public void preferencesGetEvent(int requestId, String[] prefNames) {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createPreferencesGetEvent(requestId, prefNames));
|
||||
}
|
||||
|
||||
public void preferencesObserveEvent(int requestId, String[] prefNames) {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createPreferencesObserveEvent(requestId, prefNames));
|
||||
}
|
||||
|
||||
public void setDrawListener(GeckoLayerClient.DrawListener listener) {
|
||||
GeckoAppShell.getLayerView().getLayerClient().setDrawListener(listener);
|
||||
}
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
@ -18,18 +15,9 @@ public class Telemetry {
|
||||
// toolkit/components/telemetry/Histograms.json
|
||||
public static void HistogramAdd(String name,
|
||||
int value) {
|
||||
try {
|
||||
JSONObject jsonData = new JSONObject();
|
||||
|
||||
jsonData.put("name", name);
|
||||
jsonData.put("value", value);
|
||||
|
||||
GeckoEvent event =
|
||||
GeckoEvent.createBroadcastEvent("Telemetry:Add", jsonData.toString());
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "JSON exception: ", e);
|
||||
}
|
||||
GeckoEvent event =
|
||||
GeckoEvent.createTelemetryHistogramAddEvent(name, value);
|
||||
GeckoAppShell.sendEventToGecko(event);
|
||||
}
|
||||
|
||||
public static class Timer {
|
||||
|
@ -64,13 +64,12 @@ abstract class Axis {
|
||||
}
|
||||
|
||||
static void initPrefs() {
|
||||
JSONArray prefs = new JSONArray();
|
||||
prefs.put(PREF_SCROLLING_FRICTION_FAST);
|
||||
prefs.put(PREF_SCROLLING_FRICTION_SLOW);
|
||||
prefs.put(PREF_SCROLLING_MAX_EVENT_ACCELERATION);
|
||||
prefs.put(PREF_SCROLLING_OVERSCROLL_DECEL_RATE);
|
||||
prefs.put(PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT);
|
||||
prefs.put(PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE);
|
||||
final String[] prefs = { PREF_SCROLLING_FRICTION_FAST,
|
||||
PREF_SCROLLING_FRICTION_SLOW,
|
||||
PREF_SCROLLING_MAX_EVENT_ACCELERATION,
|
||||
PREF_SCROLLING_OVERSCROLL_DECEL_RATE,
|
||||
PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT,
|
||||
PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE };
|
||||
|
||||
PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() {
|
||||
Map<String, Integer> mPrefs = new HashMap<String, Integer>();
|
||||
|
@ -61,19 +61,18 @@ final class DisplayPortCalculator {
|
||||
}
|
||||
|
||||
static void initPrefs() {
|
||||
JSONArray prefs = new JSONArray();
|
||||
prefs.put(PREF_DISPLAYPORT_STRATEGY);
|
||||
prefs.put(PREF_DISPLAYPORT_FM_MULTIPLIER);
|
||||
prefs.put(PREF_DISPLAYPORT_FM_DANGER_X);
|
||||
prefs.put(PREF_DISPLAYPORT_FM_DANGER_Y);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_MULTIPLIER);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_REVERSE_BUFFER);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_DANGER_X_BASE);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_DANGER_Y_BASE);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_DANGER_X_INCR);
|
||||
prefs.put(PREF_DISPLAYPORT_VB_DANGER_Y_INCR);
|
||||
prefs.put(PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD);
|
||||
final String[] prefs = { PREF_DISPLAYPORT_STRATEGY,
|
||||
PREF_DISPLAYPORT_FM_MULTIPLIER,
|
||||
PREF_DISPLAYPORT_FM_DANGER_X,
|
||||
PREF_DISPLAYPORT_FM_DANGER_Y,
|
||||
PREF_DISPLAYPORT_VB_MULTIPLIER,
|
||||
PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD,
|
||||
PREF_DISPLAYPORT_VB_REVERSE_BUFFER,
|
||||
PREF_DISPLAYPORT_VB_DANGER_X_BASE,
|
||||
PREF_DISPLAYPORT_VB_DANGER_Y_BASE,
|
||||
PREF_DISPLAYPORT_VB_DANGER_X_INCR,
|
||||
PREF_DISPLAYPORT_VB_DANGER_Y_INCR,
|
||||
PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD };
|
||||
|
||||
PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() {
|
||||
private Map<String, Integer> mValues = new HashMap<String, Integer>();
|
||||
|
@ -59,21 +59,18 @@ public class testAddonManager extends PixelTest {
|
||||
mActions.sendGeckoEvent("Preferences:Set", jsonPref.toString());
|
||||
|
||||
// Wait for confirmation of the pref change before proceeding with the test.
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put("extensions.getAddons.browseAddons");
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", "testAddonManager");
|
||||
message.put("preferences", getPrefData);
|
||||
final String[] prefNames = { "extensions.getAddons.browseAddons" };
|
||||
final int ourRequestId = 0x7357;
|
||||
Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Get", message.toString());
|
||||
mActions.sendPreferencesGetEvent(ourRequestId, prefNames);
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
// Wait until we get the correct "Preferences:Data" event
|
||||
while (!requestId.equals("testAddonManager")) {
|
||||
while (requestId != ourRequestId) {
|
||||
data = new JSONObject(eventExpecter.blockForEventData());
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
eventExpecter.unregisterListener();
|
||||
|
||||
|
@ -29,7 +29,7 @@ import org.json.JSONObject;
|
||||
*/
|
||||
public class testDistribution extends ContentProviderTest {
|
||||
private static final String MOCK_PACKAGE = "mock-package.zip";
|
||||
private static final String PREF_REQUEST_ID = "testDistribution";
|
||||
private static final int PREF_REQUEST_ID = 0x7357;
|
||||
|
||||
private Activity mActivity;
|
||||
|
||||
@ -86,28 +86,23 @@ public class testDistribution extends ContentProviderTest {
|
||||
String prefTestInt = "distribution.test.int";
|
||||
|
||||
try {
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put(prefID);
|
||||
getPrefData.put(prefAbout);
|
||||
getPrefData.put(prefVersion);
|
||||
getPrefData.put(prefTestBoolean);
|
||||
getPrefData.put(prefTestString);
|
||||
getPrefData.put(prefTestInt);
|
||||
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", PREF_REQUEST_ID);
|
||||
message.put("preferences", getPrefData);
|
||||
final String[] prefNames = { prefID,
|
||||
prefAbout,
|
||||
prefVersion,
|
||||
prefTestBoolean,
|
||||
prefTestString,
|
||||
prefTestInt };
|
||||
|
||||
Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Get", message.toString());
|
||||
mActions.sendPreferencesGetEvent(PREF_REQUEST_ID, prefNames);
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
// Wait until we get the correct "Preferences:Data" event
|
||||
while (!requestId.equals(PREF_REQUEST_ID)) {
|
||||
while (requestId != PREF_REQUEST_ID) {
|
||||
data = new JSONObject(eventExpecter.blockForEventData());
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
eventExpecter.unregisterListener();
|
||||
|
||||
@ -172,23 +167,18 @@ public class testDistribution extends ContentProviderTest {
|
||||
mActions.sendGeckoEvent("Preferences:Set", jsonPref.toString());
|
||||
|
||||
// Wait for confirmation of the pref change.
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put(prefUseragentLocale);
|
||||
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", PREF_REQUEST_ID);
|
||||
message.put("preferences", getPrefData);
|
||||
final String[] prefNames = { prefUseragentLocale };
|
||||
|
||||
Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Get", message.toString());
|
||||
mActions.sendPreferencesGetEvent(PREF_REQUEST_ID, prefNames);
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
// Wait until we get the correct "Preferences:Data" event
|
||||
while (!requestId.equals(PREF_REQUEST_ID)) {
|
||||
while (requestId != PREF_REQUEST_ID) {
|
||||
data = new JSONObject(eventExpecter.blockForEventData());
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
eventExpecter.unregisterListener();
|
||||
|
||||
@ -204,25 +194,18 @@ public class testDistribution extends ContentProviderTest {
|
||||
String prefLocalizeableOverride = "distribution.test.localizeable-override";
|
||||
|
||||
try {
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put(prefAbout);
|
||||
getPrefData.put(prefLocalizeable);
|
||||
getPrefData.put(prefLocalizeableOverride);
|
||||
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", PREF_REQUEST_ID);
|
||||
message.put("preferences", getPrefData);
|
||||
final String[] prefNames = { prefAbout, prefLocalizeable, prefLocalizeableOverride };
|
||||
|
||||
Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Get", message.toString());
|
||||
mActions.sendPreferencesGetEvent(PREF_REQUEST_ID, prefNames);
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
// Wait until we get the correct "Preferences:Data" event
|
||||
while (!requestId.equals(PREF_REQUEST_ID)) {
|
||||
while (requestId != PREF_REQUEST_ID) {
|
||||
data = new JSONObject(eventExpecter.blockForEventData());
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
eventExpecter.unregisterListener();
|
||||
|
||||
|
@ -81,22 +81,19 @@ public class testDoorHanger extends BaseTest {
|
||||
boolean offlineAllowedByDefault = true;
|
||||
try {
|
||||
// Save offline-allow-by-default preferences first
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put("offline-apps.allow_by_default");
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", "testDoorHanger");
|
||||
message.put("preferences", getPrefData);
|
||||
final String[] prefNames = { "offline-apps.allow_by_default" };
|
||||
final int ourRequestId = 0x7357;
|
||||
|
||||
Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Get", message.toString());
|
||||
mActions.sendPreferencesGetEvent(ourRequestId, prefNames);
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
// Wait until we get the correct "Preferences:Data" event
|
||||
while (!requestId.equals("testDoorHanger")) {
|
||||
while (requestId != ourRequestId) {
|
||||
data = new JSONObject(eventExpecter.blockForEventData());
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
eventExpecter.unregisterListener();
|
||||
|
||||
|
@ -126,21 +126,18 @@ public class testPasswordEncrypt extends BaseTest {
|
||||
mActions.sendGeckoEvent("Preferences:Set", jsonPref.toString());
|
||||
|
||||
// Wait for confirmation of the pref change before proceeding with the test.
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put("privacy.masterpassword.enabled");
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", "testPasswordEncrypt");
|
||||
message.put("preferences", getPrefData);
|
||||
final String[] prefNames = { "privacy.masterpassword.enabled" };
|
||||
final int ourRequestId = 0x73577;
|
||||
Actions.RepeatedEventExpecter eventExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Get", message.toString());
|
||||
mActions.sendPreferencesGetEvent(ourRequestId, prefNames);
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
// Wait until we get the correct "Preferences:Data" event
|
||||
while (!requestId.equals("testPasswordEncrypt")) {
|
||||
while (requestId != ourRequestId) {
|
||||
data = new JSONObject(eventExpecter.blockForEventData());
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
mAsserter.ok(false, "exception in toggleMasterPassword", ex.toString());
|
||||
|
@ -16,6 +16,7 @@ import org.json.JSONObject;
|
||||
*/
|
||||
public class testPrefsObserver extends BaseTest {
|
||||
private static final String PREF_TEST_PREF = "robocop.tests.dummy";
|
||||
private static final int PREF_OBSERVE_REQUEST_ID = 0x7357;
|
||||
private static final String PREF_REQUEST_ID = "testPrefsObserver";
|
||||
private static final long PREF_TIMEOUT = 10000;
|
||||
|
||||
@ -40,15 +41,15 @@ public class testPrefsObserver extends BaseTest {
|
||||
mAsserter.dumpLog("Waiting to check pref");
|
||||
|
||||
JSONObject data = null;
|
||||
String requestId = "";
|
||||
int requestId = -1;
|
||||
|
||||
while (!requestId.equals(PREF_REQUEST_ID)) {
|
||||
while (requestId != PREF_OBSERVE_REQUEST_ID) {
|
||||
data = new JSONObject(mExpecter.blockForEventData());
|
||||
if (!mExpecter.eventReceived()) {
|
||||
mAsserter.ok(false, "Checking pref is correct value", "Didn't receive pref");
|
||||
return;
|
||||
}
|
||||
requestId = data.getString("requestId");
|
||||
requestId = data.getInt("requestId");
|
||||
}
|
||||
|
||||
JSONObject pref = data.getJSONArray("preferences").getJSONObject(0);
|
||||
@ -80,19 +81,14 @@ public class testPrefsObserver extends BaseTest {
|
||||
mAsserter.dumpLog("Setting up pref observer");
|
||||
|
||||
// Setup the pref observer
|
||||
JSONArray getPrefData = new JSONArray();
|
||||
getPrefData.put(PREF_TEST_PREF);
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("requestId", PREF_REQUEST_ID);
|
||||
message.put("preferences", getPrefData);
|
||||
mExpecter = mActions.expectGeckoEvent("Preferences:Data");
|
||||
mActions.sendGeckoEvent("Preferences:Observe", message.toString());
|
||||
mActions.sendPreferencesObserveEvent(PREF_OBSERVE_REQUEST_ID, new String[] { PREF_TEST_PREF });
|
||||
}
|
||||
|
||||
public void removePrefObserver() {
|
||||
mAsserter.dumpLog("Removing pref observer");
|
||||
|
||||
mActions.sendGeckoEvent("Preferences:RemoveObservers", PREF_REQUEST_ID);
|
||||
mActions.sendGeckoEvent("Preferences:RemoveObservers", Integer.toString(PREF_OBSERVE_REQUEST_ID));
|
||||
}
|
||||
|
||||
public void testPrefsObserver() {
|
||||
|
@ -278,9 +278,7 @@ var BrowserApp = {
|
||||
Services.obs.addObserver(this, "Session:Stop", false);
|
||||
Services.obs.addObserver(this, "SaveAs:PDF", false);
|
||||
Services.obs.addObserver(this, "Browser:Quit", false);
|
||||
Services.obs.addObserver(this, "Preferences:Get", false);
|
||||
Services.obs.addObserver(this, "Preferences:Set", false);
|
||||
Services.obs.addObserver(this, "Preferences:Observe", false);
|
||||
Services.obs.addObserver(this, "Preferences:RemoveObservers", false);
|
||||
Services.obs.addObserver(this, "ScrollTo:FocusedInput", false);
|
||||
Services.obs.addObserver(this, "Sanitize:ClearData", false);
|
||||
@ -336,9 +334,6 @@ var BrowserApp = {
|
||||
ExternalApps.init();
|
||||
Distribution.init();
|
||||
Tabs.init();
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
Telemetry.init();
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
AccessFu.attach(window);
|
||||
#endif
|
||||
@ -657,9 +652,6 @@ var BrowserApp = {
|
||||
ExternalApps.uninit();
|
||||
Distribution.uninit();
|
||||
Tabs.uninit();
|
||||
#ifdef MOZ_TELEMETRY_REPORTING
|
||||
Telemetry.uninit();
|
||||
#endif
|
||||
},
|
||||
|
||||
// This function returns false during periods where the browser displayed document is
|
||||
@ -994,16 +986,17 @@ var BrowserApp = {
|
||||
|
||||
notifyPrefObservers: function(aPref) {
|
||||
this._prefObservers[aPref].forEach(function(aRequestId) {
|
||||
let request = { requestId : aRequestId,
|
||||
preferences : [aPref] };
|
||||
this.getPreferences(request);
|
||||
this.getPreferences(aRequestId, [aPref], 1);
|
||||
}, this);
|
||||
},
|
||||
|
||||
getPreferences: function getPreferences(aPrefsRequest, aListen) {
|
||||
handlePreferencesRequest: function handlePreferencesRequest(aRequestId,
|
||||
aPrefNames,
|
||||
aListen) {
|
||||
|
||||
let prefs = [];
|
||||
|
||||
for (let prefName of aPrefsRequest.preferences) {
|
||||
for (let prefName of aPrefNames) {
|
||||
let pref = {
|
||||
name: prefName,
|
||||
type: "",
|
||||
@ -1012,9 +1005,9 @@ var BrowserApp = {
|
||||
|
||||
if (aListen) {
|
||||
if (this._prefObservers[prefName])
|
||||
this._prefObservers[prefName].push(aPrefsRequest.requestId);
|
||||
this._prefObservers[prefName].push(aRequestId);
|
||||
else
|
||||
this._prefObservers[prefName] = [ aPrefsRequest.requestId ];
|
||||
this._prefObservers[prefName] = [ aRequestId ];
|
||||
Services.prefs.addObserver(prefName, this, false);
|
||||
}
|
||||
|
||||
@ -1121,7 +1114,7 @@ var BrowserApp = {
|
||||
|
||||
sendMessageToJava({
|
||||
type: "Preferences:Data",
|
||||
requestId: aPrefsRequest.requestId, // opaque request identifier, can be any string/int/whatever
|
||||
requestId: aRequestId, // opaque request identifier, can be any string/int/whatever
|
||||
preferences: prefs
|
||||
});
|
||||
},
|
||||
@ -1444,18 +1437,10 @@ var BrowserApp = {
|
||||
this.saveAsPDF(browser);
|
||||
break;
|
||||
|
||||
case "Preferences:Get":
|
||||
this.getPreferences(JSON.parse(aData));
|
||||
break;
|
||||
|
||||
case "Preferences:Set":
|
||||
this.setPreferences(aData);
|
||||
break;
|
||||
|
||||
case "Preferences:Observe":
|
||||
this.getPreferences(JSON.parse(aData), true);
|
||||
break;
|
||||
|
||||
case "Preferences:RemoveObservers":
|
||||
this.removePreferenceObservers(aData);
|
||||
break;
|
||||
@ -1533,6 +1518,14 @@ var BrowserApp = {
|
||||
return this.getTabForId(tabId);
|
||||
},
|
||||
|
||||
getPreferences: function getPreferences(requestId, prefNames, count) {
|
||||
this.handlePreferencesRequest(requestId, prefNames, false);
|
||||
},
|
||||
|
||||
observePreferences: function observePreferences(requestId, prefNames, count) {
|
||||
this.handlePreferencesRequest(requestId, prefNames, true);
|
||||
},
|
||||
|
||||
// This method will print a list from fromIndex to toIndex, optionally
|
||||
// selecting selIndex(if fromIndex<=selIndex<=toIndex)
|
||||
showHistory: function(fromIndex, toIndex, selIndex) {
|
||||
@ -7088,26 +7081,10 @@ var RemoteDebugger = {
|
||||
var Telemetry = {
|
||||
SHARED_PREF_TELEMETRY_ENABLED: "datareporting.telemetry.enabled",
|
||||
|
||||
init: function init() {
|
||||
Services.obs.addObserver(this, "Telemetry:Add", false);
|
||||
},
|
||||
|
||||
uninit: function uninit() {
|
||||
Services.obs.removeObserver(this, "Telemetry:Add");
|
||||
},
|
||||
|
||||
addData: function addData(aHistogramId, aValue) {
|
||||
let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
|
||||
let histogram = telemetry.getHistogramById(aHistogramId);
|
||||
let histogram = Services.telemetry.getHistogramById(aHistogramId);
|
||||
histogram.add(aValue);
|
||||
},
|
||||
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
if (aTopic == "Telemetry:Add") {
|
||||
let json = JSON.parse(aData);
|
||||
this.addData(json.name, json.value);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let Reader = {
|
||||
|
@ -8,7 +8,7 @@ function run_test() {
|
||||
Components.utils.import("resource://testing-common/httpd.js");
|
||||
|
||||
let server = new HttpServer();
|
||||
server.start(8080);
|
||||
server.start(-1);
|
||||
|
||||
do_test_pending();
|
||||
|
||||
|
@ -1 +1 @@
|
||||
NSPR_4_10_1_BETA1
|
||||
NSPR_4_10_1_BETA2
|
||||
|
@ -10,4 +10,3 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -528,9 +528,6 @@ void _MD_unix_map_connect_error(int err)
|
||||
PRErrorCode prError;
|
||||
|
||||
switch (err) {
|
||||
case EACCES:
|
||||
prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
#if defined(UNIXWARE)
|
||||
/*
|
||||
* On some platforms, if we connect to a port on the local host
|
||||
@ -541,12 +538,6 @@ void _MD_unix_map_connect_error(int err)
|
||||
prError = PR_CONNECT_REFUSED_ERROR;
|
||||
break;
|
||||
#endif
|
||||
case ELOOP:
|
||||
prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
case ENOENT:
|
||||
prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
case ENXIO:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
@ -565,17 +556,6 @@ void _MD_unix_map_bind_error(int err)
|
||||
case EINVAL:
|
||||
prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR;
|
||||
break;
|
||||
/*
|
||||
* UNIX domain sockets are not supported in NSPR
|
||||
*/
|
||||
case EIO:
|
||||
case EISDIR:
|
||||
case ELOOP:
|
||||
case ENOENT:
|
||||
case ENOTDIR:
|
||||
case EROFS:
|
||||
prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
default:
|
||||
_MD_unix_map_default_error(err);
|
||||
return;
|
||||
|
@ -20,8 +20,8 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef jArray_h_
|
||||
#define jArray_h_
|
||||
#ifndef jArray_h
|
||||
#define jArray_h
|
||||
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include "nsDebug.h"
|
||||
@ -124,4 +124,4 @@ class autoJArray {
|
||||
}
|
||||
};
|
||||
|
||||
#endif // jArray_h_
|
||||
#endif // jArray_h
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsAHtml5TreeBuilderState_h___
|
||||
#define nsAHtml5TreeBuilderState_h___
|
||||
#ifndef nsAHtml5TreeBuilderState_h
|
||||
#define nsAHtml5TreeBuilderState_h
|
||||
|
||||
/**
|
||||
* Interface for exposing the internal state of the HTML5 tree builder.
|
||||
@ -45,4 +45,4 @@ class nsAHtml5TreeBuilderState {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* nsAHtml5TreeBuilderState_h___ */
|
||||
#endif /* nsAHtml5TreeBuilderState_h */
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsAHtml5TreeOpSink_h___
|
||||
#define nsAHtml5TreeOpSink_h___
|
||||
#ifndef nsAHtml5TreeOpSink_h
|
||||
#define nsAHtml5TreeOpSink_h
|
||||
|
||||
/**
|
||||
* The purpose of this interface is to connect a tree op executor
|
||||
@ -21,4 +21,4 @@ class nsAHtml5TreeOpSink {
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsAHtml5TreeOpSink_h___ */
|
||||
#endif /* nsAHtml5TreeOpSink_h */
|
||||
|
@ -20,8 +20,8 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5ArrayCopy_h__
|
||||
#define nsHtml5ArrayCopy_h__
|
||||
#ifndef nsHtml5ArrayCopy_h
|
||||
#define nsHtml5ArrayCopy_h
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
@ -76,4 +76,4 @@ class nsHtml5ArrayCopy {
|
||||
memmove(&(arr[targetOffset]), &(arr[sourceOffset]), length * sizeof(nsHtml5StackNode*));
|
||||
}
|
||||
};
|
||||
#endif // nsHtml5ArrayCopy_h__
|
||||
#endif // nsHtml5ArrayCopy_h
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsHtml5Atom_h_
|
||||
#define nsHtml5Atom_h_
|
||||
#ifndef nsHtml5Atom_h
|
||||
#define nsHtml5Atom_h
|
||||
|
||||
#include "nsIAtom.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
@ -25,4 +25,4 @@ class nsHtml5Atom MOZ_FINAL : public nsIAtom
|
||||
~nsHtml5Atom();
|
||||
};
|
||||
|
||||
#endif // nsHtml5Atom_h_
|
||||
#endif // nsHtml5Atom_h
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsHtml5AtomTable_h_
|
||||
#define nsHtml5AtomTable_h_
|
||||
#ifndef nsHtml5AtomTable_h
|
||||
#define nsHtml5AtomTable_h
|
||||
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsTHashtable.h"
|
||||
@ -108,4 +108,4 @@ class nsHtml5AtomTable
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // nsHtml5AtomTable_h_
|
||||
#endif // nsHtml5AtomTable_h
|
||||
|
@ -9,8 +9,8 @@
|
||||
* is loaded and they are destroyed when gklayout is unloaded.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5Atoms_h___
|
||||
#define nsHtml5Atoms_h___
|
||||
#ifndef nsHtml5Atoms_h
|
||||
#define nsHtml5Atoms_h
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
||||
@ -27,4 +27,4 @@ class nsHtml5Atoms {
|
||||
#undef HTML5_ATOM
|
||||
};
|
||||
|
||||
#endif /* nsHtml5Atoms_h___ */
|
||||
#endif /* nsHtml5Atoms_h */
|
||||
|
@ -25,8 +25,8 @@
|
||||
* Please edit AttributeName.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5AttributeName_h__
|
||||
#define nsHtml5AttributeName_h__
|
||||
#ifndef nsHtml5AttributeName_h
|
||||
#define nsHtml5AttributeName_h
|
||||
|
||||
#include "nsIAtom.h"
|
||||
#include "nsHtml5AtomTable.h"
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsHtml5ByteReadable_h__
|
||||
#define nsHtml5ByteReadable_h__
|
||||
#ifndef nsHtml5ByteReadable_h
|
||||
#define nsHtml5ByteReadable_h
|
||||
|
||||
/**
|
||||
* A weak reference wrapper around a byte array.
|
||||
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsHtml5DependentUTF16Buffer_h_
|
||||
#define nsHtml5DependentUTF16Buffer_h_
|
||||
#ifndef nsHtml5DependentUTF16Buffer_h
|
||||
#define nsHtml5DependentUTF16Buffer_h
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsHtml5OwningUTF16Buffer.h"
|
||||
@ -28,4 +28,4 @@ class MOZ_STACK_CLASS nsHtml5DependentUTF16Buffer : public nsHtml5UTF16Buffer
|
||||
already_AddRefed<nsHtml5OwningUTF16Buffer> FalliblyCopyAsOwningBuffer();
|
||||
};
|
||||
|
||||
#endif // nsHtml5DependentUTF16Buffer_h_
|
||||
#endif // nsHtml5DependentUTF16Buffer_h
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user