mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
1d9d0ab094
@ -93,7 +93,7 @@ include backend.RecursiveMakeBackend.pp
|
||||
default:: backend.RecursiveMakeBackend
|
||||
|
||||
install_manifests := \
|
||||
$(addprefix dist/,bin idl include public private sdk) \
|
||||
$(addprefix dist/,bin idl include public private sdk xpi-stage) \
|
||||
_tests \
|
||||
$(NULL)
|
||||
install_manifest_depends = \
|
||||
|
@ -30,10 +30,11 @@ ClearCacheEntry(const void* aKey, nsRefPtr<T>& aAccessible, void* aUserArg)
|
||||
* Clear the cache and shutdown the accessibles.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
static void
|
||||
ClearCache(mozilla::a11y::AccessibleHashtable& aCache)
|
||||
ClearCache(nsRefPtrHashtable<nsPtrHashKey<const void>, T>& aCache)
|
||||
{
|
||||
aCache.Enumerate(ClearCacheEntry<mozilla::a11y::Accessible>, nullptr);
|
||||
aCache.Enumerate(ClearCacheEntry<T>, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "Relation.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
#include "XULTreeGridAccessible.h"
|
||||
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIAccessibleRelation.h"
|
||||
|
@ -16,6 +16,8 @@ class nsTreeBodyFrame;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class XULTreeGridCellAccessible;
|
||||
|
||||
/*
|
||||
* A class the represents the XUL Tree widget.
|
||||
*/
|
||||
@ -174,7 +176,7 @@ public:
|
||||
* Return cell accessible for the given column. If XUL tree accessible is not
|
||||
* accessible table then return null.
|
||||
*/
|
||||
virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn) const
|
||||
virtual XULTreeGridCellAccessible* GetCellAccessible(nsITreeColumn* aColumn) const
|
||||
{ return nullptr; }
|
||||
|
||||
/**
|
||||
|
@ -361,17 +361,17 @@ XULTreeGridRowAccessible::ChildCount() const
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
|
||||
|
||||
Accessible*
|
||||
XULTreeGridCellAccessible*
|
||||
XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn) const
|
||||
{
|
||||
NS_PRECONDITION(aColumn, "No tree column!");
|
||||
|
||||
void* key = static_cast<void*>(aColumn);
|
||||
Accessible* cachedCell = mAccessibleCache.GetWeak(key);
|
||||
XULTreeGridCellAccessible* cachedCell = mAccessibleCache.GetWeak(key);
|
||||
if (cachedCell)
|
||||
return cachedCell;
|
||||
|
||||
nsRefPtr<Accessible> cell =
|
||||
nsRefPtr<XULTreeGridCellAccessible> cell =
|
||||
new XULTreeGridCellAccessibleWrap(mContent, mDoc,
|
||||
const_cast<XULTreeGridRowAccessible*>(this),
|
||||
mTree, mTreeView, mRow, aColumn);
|
||||
@ -394,12 +394,9 @@ XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx,
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
treeColumns->GetColumnAt(colIdx, getter_AddRefs(column));
|
||||
if (column && !nsCoreUtils::IsColumnHidden(column)) {
|
||||
Accessible* cellAccessible = GetCellAccessible(column);
|
||||
if (cellAccessible) {
|
||||
nsRefPtr<XULTreeGridCellAccessible> cellAcc = do_QueryObject(cellAccessible);
|
||||
|
||||
nameChanged |= cellAcc->CellInvalidated();
|
||||
}
|
||||
XULTreeGridCellAccessible* cell = GetCellAccessible(column);
|
||||
if (cell)
|
||||
nameChanged |= cell->CellInvalidated();
|
||||
}
|
||||
}
|
||||
|
||||
@ -452,10 +449,8 @@ XULTreeGridCellAccessible::~XULTreeGridCellAccessible()
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible, LeafAccessible,
|
||||
mTree, mColumn)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible)
|
||||
NS_INTERFACE_TABLE_INHERITED(XULTreeGridCellAccessible,
|
||||
XULTreeGridCellAccessible)
|
||||
NS_INTERFACE_TABLE_TAIL_INHERITING(LeafAccessible)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(LeafAccessible)
|
||||
NS_IMPL_ADDREF_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class XULTreeGridCellAccessible;
|
||||
|
||||
/**
|
||||
* Represents accessible for XUL tree in the case when it has multiple columns.
|
||||
*/
|
||||
@ -88,7 +90,8 @@ public:
|
||||
virtual uint32_t ChildCount() const MOZ_OVERRIDE;
|
||||
|
||||
// XULTreeItemAccessibleBase
|
||||
virtual Accessible* GetCellAccessible(nsITreeColumn* aColumn) const MOZ_OVERRIDE;
|
||||
virtual XULTreeGridCellAccessible* GetCellAccessible(nsITreeColumn* aColumn)
|
||||
const MOZ_OVERRIDE MOZ_FINAL;
|
||||
virtual void RowInvalidated(int32_t aStartColIdx, int32_t aEndColIdx);
|
||||
|
||||
protected:
|
||||
@ -98,7 +101,8 @@ protected:
|
||||
virtual void CacheChildren();
|
||||
|
||||
// XULTreeItemAccessibleBase
|
||||
mutable AccessibleHashtable mAccessibleCache;
|
||||
mutable nsRefPtrHashtable<nsPtrHashKey<const void>, XULTreeGridCellAccessible>
|
||||
mAccessibleCache;
|
||||
};
|
||||
|
||||
|
||||
@ -107,14 +111,6 @@ protected:
|
||||
* multiple columns.
|
||||
*/
|
||||
|
||||
#define XULTREEGRIDCELLACCESSIBLE_IMPL_CID \
|
||||
{ /* 84588ad4-549c-4196-a932-4c5ca5de5dff */ \
|
||||
0x84588ad4, \
|
||||
0x549c, \
|
||||
0x4196, \
|
||||
{ 0xa9, 0x32, 0x4c, 0x5c, 0xa5, 0xde, 0x5d, 0xff } \
|
||||
}
|
||||
|
||||
class XULTreeGridCellAccessible : public LeafAccessible,
|
||||
public TableCellAccessible
|
||||
{
|
||||
@ -155,9 +151,6 @@ public:
|
||||
virtual void RowHeaderCells(nsTArray<Accessible*>* aCells) MOZ_OVERRIDE { }
|
||||
virtual bool Selected() MOZ_OVERRIDE;
|
||||
|
||||
// XULTreeGridCellAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Fire name or state change event if the accessible text or value has been
|
||||
* changed.
|
||||
@ -191,9 +184,6 @@ protected:
|
||||
nsString mCachedTextEquiv;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(XULTreeGridCellAccessible,
|
||||
XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -69,9 +69,6 @@ libs::
|
||||
$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(FINAL_TARGET)/chrome/icons/default
|
||||
endif
|
||||
|
||||
libs:: $(srcdir)/profile/prefs.js
|
||||
$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile
|
||||
|
||||
ifndef LIBXUL_SDK
|
||||
# channel-prefs.js is handled separate from other prefs due to bug 756325
|
||||
libs:: $(srcdir)/profile/channel-prefs.js
|
||||
@ -79,9 +76,6 @@ libs:: $(srcdir)/profile/channel-prefs.js
|
||||
$(call py_action,preprocessor,-Fsubstitution $(PREF_PPFLAGS) $(ACDEFINES) $^ -o $(DIST)/bin/defaults/pref/channel-prefs.js)
|
||||
endif
|
||||
|
||||
libs:: $(srcdir)/blocklist.xml
|
||||
$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
|
||||
MAC_APP_NAME = $(MOZ_APP_DISPLAYNAME)
|
||||
|
@ -15,6 +15,9 @@ SOURCES += [
|
||||
'nsBrowserApp.cpp',
|
||||
]
|
||||
|
||||
FINAL_TARGET_FILES += ['blocklist.xml']
|
||||
FINAL_TARGET_FILES.defaults.profile += ['profile/prefs.js']
|
||||
|
||||
DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
|
||||
|
||||
for var in ('MOZILLA_OFFICIAL', 'LIBXUL_SDK'):
|
||||
|
@ -1961,7 +1961,7 @@ Navigator::GetMozAudioChannelManager(ErrorResult& aRv)
|
||||
#endif
|
||||
|
||||
bool
|
||||
Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
Navigator::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
{
|
||||
|
@ -274,7 +274,7 @@ public:
|
||||
|
||||
already_AddRefed<ServiceWorkerContainer> ServiceWorker();
|
||||
|
||||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc);
|
||||
void GetOwnPropertyNames(JSContext* aCx, nsTArray<nsString>& aNames,
|
||||
@ -358,7 +358,7 @@ private:
|
||||
nsRefPtr<ServiceWorkerContainer> mServiceWorkerContainer;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
|
||||
// Hashtable for saving cached objects newresolve created, so we don't create
|
||||
// Hashtable for saving cached objects DoResolve created, so we don't create
|
||||
// the object twice if asked for it twice, whether due to use of "delete" or
|
||||
// due to Xrays. We could probably use a nsJSThingHashtable here, but then
|
||||
// we'd need to figure out exactly how to trace that, and that seems to be
|
||||
|
@ -192,13 +192,13 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMPrototype, nsDOMConstructorSH,
|
||||
DOM_BASE_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_PRECREATE |
|
||||
nsIXPCScriptable::WANT_NEWRESOLVE |
|
||||
nsIXPCScriptable::WANT_RESOLVE |
|
||||
nsIXPCScriptable::WANT_HASINSTANCE |
|
||||
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMConstructor, nsDOMConstructorSH,
|
||||
DOM_BASE_SCRIPTABLE_FLAGS |
|
||||
nsIXPCScriptable::WANT_PRECREATE |
|
||||
nsIXPCScriptable::WANT_NEWRESOLVE |
|
||||
nsIXPCScriptable::WANT_RESOLVE |
|
||||
nsIXPCScriptable::WANT_HASINSTANCE |
|
||||
nsIXPCScriptable::WANT_CALL |
|
||||
nsIXPCScriptable::WANT_CONSTRUCT |
|
||||
@ -1015,11 +1015,18 @@ nsDOMClassInfo::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMClassInfo::ResolveConstructor(JSContext *cx, JSObject *aObj,
|
||||
JSObject **objp)
|
||||
NS_IMETHODIMP
|
||||
nsDOMClassInfo::Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *aObj, jsid aId, bool *resolvedp, bool *_retval)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, aObj);
|
||||
JS::Rooted<jsid> id(cx, aId);
|
||||
|
||||
if (id != sConstructor_id) {
|
||||
*resolvedp = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, obj));
|
||||
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
@ -1032,27 +1039,13 @@ nsDOMClassInfo::ResolveConstructor(JSContext *cx, JSObject *aObj,
|
||||
// constructor for this class, or someone messed with
|
||||
// window.classname, just fall through and let the JS engine
|
||||
// return the Object constructor.
|
||||
|
||||
JS::Rooted<jsid> id(cx, sConstructor_id);
|
||||
if (!::JS_DefinePropertyById(cx, obj, id, val,
|
||||
JSPROP_ENUMERATE,
|
||||
JS_STUBGETTER, JS_STUBSETTER)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
*objp = obj;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMClassInfo::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, JSObject **objp,
|
||||
bool *_retval)
|
||||
{
|
||||
if (id == sConstructor_id) {
|
||||
return ResolveConstructor(cx, obj, objp);
|
||||
*resolvedp = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -2158,7 +2151,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
||||
nsScriptNameSpaceManager *nameSpaceManager = GetNameSpaceManager();
|
||||
NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Note - Our only caller is nsGlobalWindow::DoNewResolve, which checks that
|
||||
// Note - Our only caller is nsGlobalWindow::DoResolve, which checks that
|
||||
// JSID_IS_STRING(id) is true.
|
||||
nsAutoJSString name;
|
||||
if (!name.init(cx, JSID_TO_STRING(id))) {
|
||||
@ -2622,8 +2615,8 @@ nsDOMConstructorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMConstructorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *aObj, jsid aId, JSObject **objp,
|
||||
nsDOMConstructorSH::Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *aObj, jsid aId, bool *resolvedp,
|
||||
bool *_retval)
|
||||
{
|
||||
JS::Rooted<JSObject*> obj(cx, aObj);
|
||||
@ -2645,7 +2638,7 @@ nsDOMConstructorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx
|
||||
// Now re-lookup the ID to see if we should report back that we resolved the
|
||||
// looked-for constant. Note that we don't have to worry about infinitely
|
||||
// recurring back here because the Xray wrapper's holder object doesn't call
|
||||
// NewResolve hooks.
|
||||
// Resolve hooks.
|
||||
bool found;
|
||||
if (!JS_HasPropertyById(cx, nativePropsObj, id, &found)) {
|
||||
*_retval = false;
|
||||
@ -2653,7 +2646,7 @@ nsDOMConstructorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx
|
||||
}
|
||||
|
||||
if (found) {
|
||||
*objp = obj;
|
||||
*resolvedp = true;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -138,8 +138,6 @@ protected:
|
||||
|
||||
static nsresult RegisterClassProtos(int32_t aDOMClassInfoID);
|
||||
static nsresult RegisterExternalClasses();
|
||||
nsresult ResolveConstructor(JSContext *cx, JSObject *obj,
|
||||
JSObject **objp);
|
||||
|
||||
static nsIXPConnect *sXPConnect;
|
||||
|
||||
@ -276,8 +274,8 @@ public:
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, JSObject **objp,
|
||||
NS_IMETHOD Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, jsid id, bool *resolvedp,
|
||||
bool *_retval) MOZ_OVERRIDE;
|
||||
NS_IMETHOD Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
||||
JSObject *obj, const JS::CallArgs &args, bool *_retval) MOZ_OVERRIDE;
|
||||
|
@ -704,7 +704,6 @@ const js::Class OuterWindowProxyClass =
|
||||
PROXY_MAKE_EXT(
|
||||
nullptr, /* outerObject */
|
||||
js::proxy_innerObject,
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nsOuterWindowProxy::ObjectMoved
|
||||
));
|
||||
@ -4239,7 +4238,7 @@ nsGlobalWindow::GetSupportedNames(nsTArray<nsString>& aNames)
|
||||
}
|
||||
|
||||
bool
|
||||
nsGlobalWindow::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
nsGlobalWindow::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
{
|
||||
|
@ -483,7 +483,7 @@ public:
|
||||
static bool IsShowModalDialogEnabled(JSContext* /* unused */ = nullptr,
|
||||
JSObject* /* unused */ = nullptr);
|
||||
|
||||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc);
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#define DEFAULT_SCRIPTABLE_FLAGS \
|
||||
(DOM_BASE_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_NEWRESOLVE | \
|
||||
nsIXPCScriptable::WANT_RESOLVE | \
|
||||
nsIXPCScriptable::WANT_PRECREATE)
|
||||
|
||||
#define DOM_DEFAULT_SCRIPTABLE_FLAGS \
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
@ -1692,24 +1693,24 @@ nsJSContext::RunCycleCollectorSlice()
|
||||
|
||||
// Decide how long we want to budget for this slice. By default,
|
||||
// use an unlimited budget.
|
||||
int64_t sliceBudget = -1;
|
||||
js::SliceBudget budget;
|
||||
|
||||
if (sIncrementalCC) {
|
||||
if (gCCStats.mBeginTime.IsNull()) {
|
||||
// If no CC is in progress, use the standard slice time.
|
||||
sliceBudget = kICCSliceBudget;
|
||||
budget = js::SliceBudget(js::TimeBudget(kICCSliceBudget));
|
||||
} else {
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
// Only run a limited slice if we're within the max running time.
|
||||
if (TimeBetween(gCCStats.mBeginTime, now) < kMaxICCDuration) {
|
||||
float sliceMultiplier = std::max(TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay, 1.0f);
|
||||
sliceBudget = kICCSliceBudget * sliceMultiplier;
|
||||
budget = js::SliceBudget(js::TimeBudget(kICCSliceBudget * sliceMultiplier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCycleCollector_collectSlice(sliceBudget);
|
||||
nsCycleCollector_collectSlice(budget);
|
||||
|
||||
gCCStats.FinishCycleCollectionSlice();
|
||||
}
|
||||
@ -1726,7 +1727,10 @@ nsJSContext::RunCycleCollectorWorkSlice(int64_t aWorkBudget)
|
||||
js::ProfileEntry::Category::CC);
|
||||
|
||||
gCCStats.PrepareForCycleCollectionSlice();
|
||||
nsCycleCollector_collectSliceWork(aWorkBudget);
|
||||
|
||||
js::SliceBudget budget = js::SliceBudget(js::WorkBudget(aWorkBudget));
|
||||
nsCycleCollector_collectSlice(budget);
|
||||
|
||||
gCCStats.FinishCycleCollectionSlice();
|
||||
}
|
||||
|
||||
|
@ -3622,7 +3622,7 @@ nsObjectLoadingContent::TeardownProtoChain()
|
||||
}
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
nsObjectLoadingContent::DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
{
|
||||
@ -3642,7 +3642,7 @@ nsObjectLoadingContent::GetOwnPropertyNames(JSContext* aCx,
|
||||
nsTArray<nsString>& /* unused */,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Just like DoNewResolve, just make sure we're instantiated. That will do
|
||||
// Just like DoResolve, just make sure we're instantiated. That will do
|
||||
// the work our Enumerate hook needs to do. This purposefully does not fire
|
||||
// for xray resolves, see bug 967694
|
||||
nsRefPtr<nsNPAPIPluginInstance> pi;
|
||||
|
@ -157,7 +157,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
* SetupProtoChain handles actually inserting the plug-in
|
||||
* scriptable object into the proto chain if needed.
|
||||
*
|
||||
* DoNewResolve is a hook that allows us to find out when the web
|
||||
* DoResolve is a hook that allows us to find out when the web
|
||||
* page is looking up a property name on our object and make sure
|
||||
* that our plug-in, if any, is instantiated.
|
||||
*/
|
||||
@ -167,8 +167,8 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// Remove plugin from protochain
|
||||
void TeardownProtoChain();
|
||||
|
||||
// Helper for WebIDL newResolve
|
||||
bool DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
// Helper for WebIDL NeedResolve
|
||||
bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc);
|
||||
// Helper for WebIDL enumeration
|
||||
|
@ -2292,15 +2292,9 @@ FinalizeGlobal(JSFreeOp* aFreeOp, JSObject* aObj)
|
||||
|
||||
bool
|
||||
ResolveGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<jsid> aId, JS::MutableHandle<JSObject*> aObjp)
|
||||
JS::Handle<jsid> aId, bool* aResolvedp)
|
||||
{
|
||||
bool resolved;
|
||||
if (!JS_ResolveStandardClass(aCx, aObj, aId, &resolved)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aObjp.set(resolved ? aObj.get() : nullptr);
|
||||
return true;
|
||||
return JS_ResolveStandardClass(aCx, aObj, aId, aResolvedp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2803,7 +2803,7 @@ FinalizeGlobal(JSFreeOp* aFop, JSObject* aObj);
|
||||
|
||||
bool
|
||||
ResolveGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<jsid> aId, JS::MutableHandle<JSObject*> aObjp);
|
||||
JS::Handle<jsid> aId, bool* aResolvedp);
|
||||
|
||||
bool
|
||||
EnumerateGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj);
|
||||
|
@ -21,7 +21,7 @@ OBJECT_MOVED_HOOK_NAME = '_objectMoved'
|
||||
CONSTRUCT_HOOK_NAME = '_constructor'
|
||||
LEGACYCALLER_HOOK_NAME = '_legacycaller'
|
||||
HASINSTANCE_HOOK_NAME = '_hasInstance'
|
||||
NEWRESOLVE_HOOK_NAME = '_newResolve'
|
||||
RESOLVE_HOOK_NAME = '_resolve'
|
||||
ENUMERATE_HOOK_NAME = '_enumerate'
|
||||
ENUM_ENTRY_VARIABLE_NAME = 'strings'
|
||||
INSTANCE_RESERVED_SLOTS = 1
|
||||
@ -275,7 +275,7 @@ class CGNativePropertyHooks(CGThing):
|
||||
resolveOwnProperty = "ResolveOwnProperty"
|
||||
enumerateOwnProperties = "EnumerateOwnProperties"
|
||||
elif self.descriptor.needsXrayResolveHooks():
|
||||
resolveOwnProperty = "ResolveOwnPropertyViaNewresolve"
|
||||
resolveOwnProperty = "ResolveOwnPropertyViaResolve"
|
||||
enumerateOwnProperties = "EnumerateOwnPropertiesViaGetOwnPropertyNames"
|
||||
else:
|
||||
resolveOwnProperty = "nullptr"
|
||||
@ -370,7 +370,6 @@ class CGDOMJSClass(CGThing):
|
||||
{
|
||||
nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
${objectMoved} /* objectMovedOp */
|
||||
@ -388,7 +387,6 @@ class CGDOMJSClass(CGThing):
|
||||
{
|
||||
nsGlobalWindow::OuterObject, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
${objectMoved} /* objectMovedOp */
|
||||
@ -420,16 +418,14 @@ class CGDOMJSClass(CGThing):
|
||||
else:
|
||||
classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount
|
||||
reservedSlots = slotCount
|
||||
if self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||
newResolveHook = "(JSResolveOp)" + NEWRESOLVE_HOOK_NAME
|
||||
classFlags += " | JSCLASS_NEW_RESOLVE"
|
||||
if self.descriptor.interface.getExtendedAttribute("NeedResolve"):
|
||||
resolveHook = RESOLVE_HOOK_NAME
|
||||
enumerateHook = ENUMERATE_HOOK_NAME
|
||||
elif self.descriptor.isGlobal():
|
||||
newResolveHook = "(JSResolveOp) mozilla::dom::ResolveGlobal"
|
||||
classFlags += " | JSCLASS_NEW_RESOLVE"
|
||||
resolveHook = "mozilla::dom::ResolveGlobal"
|
||||
enumerateHook = "mozilla::dom::EnumerateGlobal"
|
||||
else:
|
||||
newResolveHook = "JS_ResolveStub"
|
||||
resolveHook = "JS_ResolveStub"
|
||||
enumerateHook = "JS_EnumerateStub"
|
||||
|
||||
return fill(
|
||||
@ -463,7 +459,7 @@ class CGDOMJSClass(CGThing):
|
||||
flags=classFlags,
|
||||
addProperty=ADDPROPERTY_HOOK_NAME if wantsAddProperty(self.descriptor) else 'JS_PropertyStub',
|
||||
enumerate=enumerateHook,
|
||||
resolve=newResolveHook,
|
||||
resolve=resolveHook,
|
||||
finalize=FINALIZE_HOOK_NAME,
|
||||
call=callHook,
|
||||
trace=traceHook,
|
||||
@ -500,7 +496,6 @@ class CGDOMProxyJSClass(CGThing):
|
||||
${flags},
|
||||
PROXY_MAKE_EXT(nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
${objectMoved})),
|
||||
$*{descriptor}
|
||||
@ -7602,32 +7597,32 @@ class CGLegacyCallHook(CGAbstractBindingMethod):
|
||||
self._legacycaller)
|
||||
|
||||
|
||||
class CGNewResolveHook(CGAbstractBindingMethod):
|
||||
class CGResolveHook(CGAbstractBindingMethod):
|
||||
"""
|
||||
NewResolve hook for objects with custom hooks.
|
||||
Resolve hook for objects that have the NeedResolve extended attribute.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
assert descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
||||
assert descriptor.interface.getExtendedAttribute("NeedResolve")
|
||||
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'obj'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('JS::MutableHandle<JSObject*>', 'objp')]
|
||||
Argument('bool*', 'resolvedp')]
|
||||
# Our "self" is actually the "obj" argument in this case, not the thisval.
|
||||
CGAbstractBindingMethod.__init__(
|
||||
self, descriptor, NEWRESOLVE_HOOK_NAME,
|
||||
self, descriptor, RESOLVE_HOOK_NAME,
|
||||
args, getThisObj="", callArgs="")
|
||||
|
||||
def generate_code(self):
|
||||
return CGGeneric(dedent("""
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!self->DoNewResolve(cx, obj, id, &desc)) {
|
||||
if (!self->DoResolve(cx, obj, id, &desc)) {
|
||||
return false;
|
||||
}
|
||||
if (!desc.object()) {
|
||||
return true;
|
||||
}
|
||||
// If desc.value() is undefined, then the DoNewResolve call
|
||||
// If desc.value() is undefined, then the DoResolve call
|
||||
// has already defined it on the object. Don't try to also
|
||||
// define it.
|
||||
if (!desc.value().isUndefined() &&
|
||||
@ -7637,7 +7632,7 @@ class CGNewResolveHook(CGAbstractBindingMethod):
|
||||
JS_PROPERTYOP_SETTER(desc.setter()))) {
|
||||
return false;
|
||||
}
|
||||
objp.set(obj);
|
||||
*resolvedp = true;
|
||||
return true;
|
||||
"""))
|
||||
|
||||
@ -7645,10 +7640,10 @@ class CGNewResolveHook(CGAbstractBindingMethod):
|
||||
if self.descriptor.isGlobal():
|
||||
# Resolve standard classes
|
||||
prefix = dedent("""
|
||||
if (!ResolveGlobal(cx, obj, id, objp)) {
|
||||
if (!ResolveGlobal(cx, obj, id, resolvedp)) {
|
||||
return false;
|
||||
}
|
||||
if (objp) {
|
||||
if (*resolvedp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7663,7 +7658,7 @@ class CGEnumerateHook(CGAbstractBindingMethod):
|
||||
Enumerate hook for objects with custom hooks.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
assert descriptor.interface.getExtendedAttribute("NeedNewResolve")
|
||||
assert descriptor.interface.getExtendedAttribute("NeedResolve")
|
||||
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'obj')]
|
||||
@ -9569,10 +9564,10 @@ class CGResolveOwnProperty(CGAbstractStaticMethod):
|
||||
return "return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);\n"
|
||||
|
||||
|
||||
class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
|
||||
class CGResolveOwnPropertyViaResolve(CGAbstractBindingMethod):
|
||||
"""
|
||||
An implementation of Xray ResolveOwnProperty stuff for things that have a
|
||||
newresolve hook.
|
||||
resolve hook.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
@ -9581,7 +9576,7 @@ class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc')]
|
||||
CGAbstractBindingMethod.__init__(self, descriptor,
|
||||
"ResolveOwnPropertyViaNewresolve",
|
||||
"ResolveOwnPropertyViaResolve",
|
||||
args, getThisObj="",
|
||||
callArgs="")
|
||||
|
||||
@ -9596,10 +9591,10 @@ class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
|
||||
// them.
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
JS::Rooted<JSPropertyDescriptor> objDesc(cx);
|
||||
if (!self->DoNewResolve(cx, obj, id, &objDesc)) {
|
||||
if (!self->DoResolve(cx, obj, id, &objDesc)) {
|
||||
return false;
|
||||
}
|
||||
// If desc.value() is undefined, then the DoNewResolve call
|
||||
// If desc.value() is undefined, then the DoResolve call
|
||||
// has already defined the property on the object. Don't
|
||||
// try to also define it.
|
||||
if (objDesc.object() &&
|
||||
@ -9611,7 +9606,7 @@ class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return self->DoNewResolve(cx, wrapper, id, desc);
|
||||
return self->DoResolve(cx, wrapper, id, desc);
|
||||
"""))
|
||||
|
||||
|
||||
@ -9631,7 +9626,7 @@ class CGEnumerateOwnProperties(CGAbstractStaticMethod):
|
||||
class CGEnumerateOwnPropertiesViaGetOwnPropertyNames(CGAbstractBindingMethod):
|
||||
"""
|
||||
An implementation of Xray EnumerateOwnProperties stuff for things
|
||||
that have a newresolve hook.
|
||||
that have a resolve hook.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
@ -11097,7 +11092,7 @@ class CGDescriptor(CGThing):
|
||||
cgThings.append(CGResolveOwnProperty(descriptor))
|
||||
cgThings.append(CGEnumerateOwnProperties(descriptor))
|
||||
elif descriptor.needsXrayResolveHooks():
|
||||
cgThings.append(CGResolveOwnPropertyViaNewresolve(descriptor))
|
||||
cgThings.append(CGResolveOwnPropertyViaResolve(descriptor))
|
||||
cgThings.append(CGEnumerateOwnPropertiesViaGetOwnPropertyNames(descriptor))
|
||||
|
||||
# Now that we have our ResolveOwnProperty/EnumerateOwnProperties stuff
|
||||
@ -11114,8 +11109,8 @@ class CGDescriptor(CGThing):
|
||||
cgThings.append(CGNamedConstructors(descriptor))
|
||||
|
||||
cgThings.append(CGLegacyCallHook(descriptor))
|
||||
if descriptor.interface.getExtendedAttribute("NeedNewResolve"):
|
||||
cgThings.append(CGNewResolveHook(descriptor))
|
||||
if descriptor.interface.getExtendedAttribute("NeedResolve"):
|
||||
cgThings.append(CGResolveHook(descriptor))
|
||||
cgThings.append(CGEnumerateHook(descriptor))
|
||||
|
||||
if descriptor.hasNamedPropertiesObject:
|
||||
@ -11881,8 +11876,7 @@ class CGResolveSystemBinding(CGAbstractMethod):
|
||||
[Argument('JSContext*', 'aCx'),
|
||||
Argument('JS::Handle<JSObject*>', 'aObj'),
|
||||
Argument('JS::Handle<jsid>', 'aId'),
|
||||
Argument('JS::MutableHandle<JSObject*>',
|
||||
'aObjp')])
|
||||
Argument('bool*', 'aResolvedp')])
|
||||
self.config = config
|
||||
|
||||
def definition_body(self):
|
||||
@ -11915,7 +11909,7 @@ class CGResolveSystemBinding(CGAbstractMethod):
|
||||
defineCode = "!%s::GetConstructorObject(aCx, aObj)" % bindingNS
|
||||
defineCode = CGIfWrapper(CGGeneric("return false;\n"), defineCode)
|
||||
defineCode = CGList([defineCode,
|
||||
CGGeneric("aObjp.set(aObj);\n")])
|
||||
CGGeneric("*aResolvedp = true;\n")])
|
||||
|
||||
condition = "JSID_IS_VOID(aId) || aId == %s" % descNameToId(desc.name)
|
||||
if desc.isExposedConditionally():
|
||||
|
@ -663,14 +663,14 @@ class Descriptor(DescriptorProvider):
|
||||
|
||||
def needsXrayResolveHooks(self):
|
||||
"""
|
||||
Generally, any interface with NeedNewResolve needs Xray
|
||||
Generally, any interface with NeedResolve needs Xray
|
||||
resolveOwnProperty and enumerateOwnProperties hooks. But for
|
||||
the special case of plugin-loading elements, we do NOT want
|
||||
those, because we don't want to instantiate plug-ins simply
|
||||
due to chrome touching them and that's all those hooks do on
|
||||
those elements. So we special-case those here.
|
||||
"""
|
||||
return (self.interface.getExtendedAttribute("NeedNewResolve") and
|
||||
return (self.interface.getExtendedAttribute("NeedResolve") and
|
||||
self.interface.identifier.name not in ["HTMLObjectElement",
|
||||
"HTMLEmbedElement",
|
||||
"HTMLAppletElement"])
|
||||
|
@ -1225,7 +1225,7 @@ class IDLInterface(IDLObjectWithScope):
|
||||
self.parentScope.globalNames.add(self.identifier.name)
|
||||
self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
|
||||
self._isOnGlobalProtoChain = True
|
||||
elif (identifier == "NeedNewResolve" or
|
||||
elif (identifier == "NeedResolve" or
|
||||
identifier == "OverrideBuiltins" or
|
||||
identifier == "ChromeOnly" or
|
||||
identifier == "Unforgeable" or
|
||||
|
@ -2027,7 +2027,6 @@ BackgroundCursorChild::SendContinueInternal(const CursorRequestParams& aParams)
|
||||
MOZ_ASSERT(!mStrongCursor);
|
||||
|
||||
// Make sure all our DOM objects stay alive.
|
||||
mStrongRequest = mRequest;
|
||||
mStrongCursor = mCursor;
|
||||
|
||||
MOZ_ASSERT(mRequest->ReadyState() == IDBRequestReadyState::Done);
|
||||
@ -2119,9 +2118,7 @@ BackgroundCursorChild::HandleResponse(
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()), Move(cloneReadInfo));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mObjectStore,
|
||||
this,
|
||||
mDirection,
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(cloneReadInfo));
|
||||
mCursor = newCursor;
|
||||
@ -2150,10 +2147,7 @@ BackgroundCursorChild::HandleResponse(
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mObjectStore,
|
||||
this,
|
||||
mDirection,
|
||||
Move(response.key()));
|
||||
newCursor = IDBCursor::Create(this, Move(response.key()));
|
||||
mCursor = newCursor;
|
||||
}
|
||||
|
||||
@ -2187,9 +2181,7 @@ BackgroundCursorChild::HandleResponse(const IndexCursorResponse& aResponse)
|
||||
Move(response.objectKey()),
|
||||
Move(cloneReadInfo));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mIndex,
|
||||
this,
|
||||
mDirection,
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(response.objectKey()),
|
||||
Move(cloneReadInfo));
|
||||
@ -2218,9 +2210,7 @@ BackgroundCursorChild::HandleResponse(const IndexKeyCursorResponse& aResponse)
|
||||
if (mCursor) {
|
||||
mCursor->Reset(Move(response.key()), Move(response.objectKey()));
|
||||
} else {
|
||||
newCursor = IDBCursor::Create(mIndex,
|
||||
this,
|
||||
mDirection,
|
||||
newCursor = IDBCursor::Create(this,
|
||||
Move(response.key()),
|
||||
Move(response.objectKey()));
|
||||
mCursor = newCursor;
|
||||
@ -2265,8 +2255,8 @@ BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
|
||||
MOZ_ASSERT(aResponse.type() != CursorResponse::T__None);
|
||||
MOZ_ASSERT(mRequest);
|
||||
MOZ_ASSERT(mTransaction);
|
||||
MOZ_ASSERT(mStrongRequest);
|
||||
MOZ_ASSERT_IF(mCursor, mStrongCursor);
|
||||
MOZ_ASSERT_IF(!mCursor, mStrongRequest);
|
||||
|
||||
MaybeCollectGarbageOnIPCMessage();
|
||||
|
||||
|
@ -568,6 +568,38 @@ public:
|
||||
void
|
||||
SendDeleteMeInternal();
|
||||
|
||||
IDBRequest*
|
||||
GetRequest() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mRequest;
|
||||
}
|
||||
|
||||
IDBObjectStore*
|
||||
GetObjectStore() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mObjectStore;
|
||||
}
|
||||
|
||||
IDBIndex*
|
||||
GetIndex() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
Direction
|
||||
GetDirection() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mDirection;
|
||||
}
|
||||
|
||||
private:
|
||||
// Only destroyed by BackgroundTransactionChild or
|
||||
// BackgroundVersionChangeTransactionChild.
|
||||
|
@ -27,23 +27,20 @@ namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
IDBCursor::IDBCursor(Type aType,
|
||||
IDBObjectStore* aSourceObjectStore,
|
||||
IDBIndex* aSourceIndex,
|
||||
IDBTransaction* aTransaction,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
const Key& aKey)
|
||||
: mSourceObjectStore(aSourceObjectStore)
|
||||
, mSourceIndex(aSourceIndex)
|
||||
, mTransaction(aTransaction)
|
||||
, mBackgroundActor(aBackgroundActor)
|
||||
, mScriptOwner(aTransaction->Database()->GetScriptOwner())
|
||||
: mBackgroundActor(aBackgroundActor)
|
||||
, mRequest(aBackgroundActor->GetRequest())
|
||||
, mSourceObjectStore(aBackgroundActor->GetObjectStore())
|
||||
, mSourceIndex(aBackgroundActor->GetIndex())
|
||||
, mTransaction(mRequest->GetTransaction())
|
||||
, mScriptOwner(mTransaction->Database()->GetScriptOwner())
|
||||
, mCachedKey(JSVAL_VOID)
|
||||
, mCachedPrimaryKey(JSVAL_VOID)
|
||||
, mCachedValue(JSVAL_VOID)
|
||||
, mKey(aKey)
|
||||
, mType(aType)
|
||||
, mDirection(aDirection)
|
||||
, mDirection(aBackgroundActor->GetDirection())
|
||||
, mHaveCachedKey(false)
|
||||
, mHaveCachedPrimaryKey(false)
|
||||
, mHaveCachedValue(false)
|
||||
@ -51,12 +48,13 @@ IDBCursor::IDBCursor(Type aType,
|
||||
, mContinueCalled(false)
|
||||
, mHaveValue(true)
|
||||
{
|
||||
MOZ_ASSERT_IF(aType == Type_ObjectStore || aType == Type_ObjectStoreKey,
|
||||
aSourceObjectStore);
|
||||
MOZ_ASSERT_IF(aType == Type_Index || aType == Type_IndexKey, aSourceIndex);
|
||||
MOZ_ASSERT(aTransaction);
|
||||
aTransaction->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mRequest);
|
||||
MOZ_ASSERT_IF(aType == Type_ObjectStore || aType == Type_ObjectStoreKey,
|
||||
mSourceObjectStore);
|
||||
MOZ_ASSERT_IF(aType == Type_Index || aType == Type_IndexKey, mSourceIndex);
|
||||
MOZ_ASSERT(mTransaction);
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
MOZ_ASSERT(mScriptOwner);
|
||||
|
||||
@ -80,25 +78,18 @@ IDBCursor::~IDBCursor()
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo)
|
||||
{
|
||||
MOZ_ASSERT(aObjectStore);
|
||||
aObjectStore->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_ObjectStore,
|
||||
aObjectStore,
|
||||
nullptr,
|
||||
aObjectStore->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_ObjectStore, aBackgroundActor, aKey);
|
||||
|
||||
cursor->mCloneInfo = Move(aCloneInfo);
|
||||
|
||||
@ -107,51 +98,37 @@ IDBCursor::Create(IDBObjectStore* aObjectStore,
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey)
|
||||
{
|
||||
MOZ_ASSERT(aObjectStore);
|
||||
aObjectStore->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_ObjectStoreKey,
|
||||
aObjectStore,
|
||||
nullptr,
|
||||
aObjectStore->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_ObjectStoreKey, aBackgroundActor, aKey);
|
||||
|
||||
return cursor.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo)
|
||||
{
|
||||
MOZ_ASSERT(aIndex);
|
||||
aIndex->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
MOZ_ASSERT(!aPrimaryKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_Index,
|
||||
nullptr,
|
||||
aIndex,
|
||||
aIndex->ObjectStore()->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_Index, aBackgroundActor, aKey);
|
||||
|
||||
cursor->mPrimaryKey = Move(aPrimaryKey);
|
||||
cursor->mCloneInfo = Move(aCloneInfo);
|
||||
@ -161,26 +138,19 @@ IDBCursor::Create(IDBIndex* aIndex,
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBCursor>
|
||||
IDBCursor::Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
IDBCursor::Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey)
|
||||
{
|
||||
MOZ_ASSERT(aIndex);
|
||||
aIndex->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor);
|
||||
aBackgroundActor->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBackgroundActor->GetIndex());
|
||||
MOZ_ASSERT(!aBackgroundActor->GetObjectStore());
|
||||
MOZ_ASSERT(!aKey.IsUnset());
|
||||
MOZ_ASSERT(!aPrimaryKey.IsUnset());
|
||||
|
||||
nsRefPtr<IDBCursor> cursor =
|
||||
new IDBCursor(Type_IndexKey,
|
||||
nullptr,
|
||||
aIndex,
|
||||
aIndex->ObjectStore()->Transaction(),
|
||||
aBackgroundActor,
|
||||
aDirection,
|
||||
aKey);
|
||||
new IDBCursor(Type_IndexKey, aBackgroundActor, aKey);
|
||||
|
||||
cursor->mPrimaryKey = Move(aPrimaryKey);
|
||||
|
||||
@ -800,9 +770,9 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBCursor)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBCursor)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceObjectStore)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceIndex)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
|
||||
@ -819,7 +789,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBCursor)
|
||||
// Don't unlink mSourceObjectStore or mSourceIndex or mTransaction!
|
||||
// Don't unlink mRequest, mSourceObjectStore, or mSourceIndex!
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->DropJSObjects();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -59,11 +59,14 @@ private:
|
||||
Type_IndexKey,
|
||||
};
|
||||
|
||||
BackgroundCursorChild* mBackgroundActor;
|
||||
|
||||
nsRefPtr<IDBRequest> mRequest;
|
||||
nsRefPtr<IDBObjectStore> mSourceObjectStore;
|
||||
nsRefPtr<IDBIndex> mSourceIndex;
|
||||
nsRefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
BackgroundCursorChild* mBackgroundActor;
|
||||
// mSourceObjectStore or mSourceIndex will hold this alive.
|
||||
IDBTransaction* mTransaction;
|
||||
|
||||
JS::Heap<JSObject*> mScriptOwner;
|
||||
|
||||
@ -88,30 +91,22 @@ private:
|
||||
|
||||
public:
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBObjectStore* aObjectStore,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey,
|
||||
StructuredCloneReadInfo&& aCloneInfo);
|
||||
|
||||
static already_AddRefed<IDBCursor>
|
||||
Create(IDBIndex* aIndex,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
Create(BackgroundCursorChild* aBackgroundActor,
|
||||
const Key& aKey,
|
||||
const Key& aPrimaryKey);
|
||||
|
||||
@ -194,11 +189,7 @@ public:
|
||||
|
||||
private:
|
||||
IDBCursor(Type aType,
|
||||
IDBObjectStore* aSourceObjectStore,
|
||||
IDBIndex* aSourceIndex,
|
||||
IDBTransaction* aTransaction,
|
||||
BackgroundCursorChild* aBackgroundActor,
|
||||
Direction aDirection,
|
||||
const Key& aKey);
|
||||
|
||||
~IDBCursor();
|
||||
|
@ -46,6 +46,7 @@ support-files =
|
||||
unit/test_indexes.js
|
||||
unit/test_indexes_bad_values.js
|
||||
unit/test_indexes_funny_things.js
|
||||
unit/test_invalid_cursor.js
|
||||
unit/test_invalid_version.js
|
||||
unit/test_invalidate.js
|
||||
unit/test_key_requirements.js
|
||||
@ -267,6 +268,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_indexes_funny_things.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_invalid_cursor.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_invalid_version.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_invalidate.html]
|
||||
|
18
dom/indexedDB/test/test_invalid_cursor.html
Normal file
18
dom/indexedDB/test/test_invalid_cursor.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>IndexedDB Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_invalid_cursor.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
62
dom/indexedDB/test/unit/test_invalid_cursor.js
Normal file
62
dom/indexedDB/test/unit/test_invalid_cursor.js
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
let testGenerator = testSteps();
|
||||
|
||||
function testSteps()
|
||||
{
|
||||
const dbName = ("window" in this) ? window.location.pathname : "test";
|
||||
const dbVersion = 1;
|
||||
const objectStoreName = "foo";
|
||||
const data = 0;
|
||||
|
||||
let req = indexedDB.open(dbName, dbVersion);
|
||||
req.onerror = errorHandler;
|
||||
req.onupgradeneeded = grabEventAndContinueHandler;
|
||||
req.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got upgradeneeded event");
|
||||
|
||||
let db = event.target.result;
|
||||
|
||||
let objectStore =
|
||||
db.createObjectStore(objectStoreName, { autoIncrement: true });
|
||||
objectStore.add(data);
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event for open");
|
||||
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
|
||||
objectStore.openCursor().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got success event for openCursor");
|
||||
|
||||
let cursor = event.target.result;
|
||||
is(cursor.value, data, "Got correct cursor value");
|
||||
|
||||
objectStore.get(cursor.key).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data, "Got correct get value");
|
||||
|
||||
info("Collecting garbage");
|
||||
|
||||
gc();
|
||||
|
||||
info("Done collecting garbage");
|
||||
|
||||
cursor.continue();
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "No more entries");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
@ -36,6 +36,7 @@ skip-if = toolkit == 'android' # bug 1079278
|
||||
[test_indexes.js]
|
||||
[test_indexes_bad_values.js]
|
||||
[test_indexes_funny_things.js]
|
||||
[test_invalid_cursor.js]
|
||||
[test_invalid_version.js]
|
||||
[test_key_requirements.js]
|
||||
[test_keys.js]
|
||||
|
@ -345,11 +345,9 @@ DOMMediaStream::CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
|
||||
switch (aType) {
|
||||
case MediaSegment::AUDIO:
|
||||
track = new AudioStreamTrack(this, aTrackID);
|
||||
mTrackTypesAvailable |= HINT_CONTENTS_AUDIO;
|
||||
break;
|
||||
case MediaSegment::VIDEO:
|
||||
track = new VideoStreamTrack(this, aTrackID);
|
||||
mTrackTypesAvailable |= HINT_CONTENTS_VIDEO;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unhandled track type");
|
||||
@ -369,7 +367,7 @@ DOMMediaStream::BindDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
|
||||
track = mTracks[i]->AsAudioStreamTrack();
|
||||
if (track) {
|
||||
track->BindTrackID(aTrackID);
|
||||
MOZ_ASSERT(mTrackTypesAvailable & HINT_CONTENTS_AUDIO);
|
||||
mTrackTypesAvailable |= HINT_CONTENTS_AUDIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -380,7 +378,7 @@ DOMMediaStream::BindDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
|
||||
track = mTracks[i]->AsVideoStreamTrack();
|
||||
if (track) {
|
||||
track->BindTrackID(aTrackID);
|
||||
MOZ_ASSERT(mTrackTypesAvailable & HINT_CONTENTS_VIDEO);
|
||||
mTrackTypesAvailable |= HINT_CONTENTS_VIDEO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ protected:
|
||||
|
||||
// Indicate what track types we eventually expect to add to this stream
|
||||
uint8_t mHintContents;
|
||||
// Indicate what track types have been added to this stream
|
||||
// Indicate what track types have arrived in this stream
|
||||
uint8_t mTrackTypesAvailable;
|
||||
bool mNotifiedOfMediaStreamGraphShutdown;
|
||||
|
||||
|
@ -1823,11 +1823,15 @@ MediaCacheStream::FlushPartialBlockInternal(bool aNotifyAll)
|
||||
BLOCK_SIZE - blockOffset);
|
||||
gMediaCache->AllocateAndWriteBlock(this, mPartialBlockBuffer,
|
||||
mMetadataInPartialBlockBuffer ? MODE_METADATA : MODE_PLAYBACK);
|
||||
if (aNotifyAll) {
|
||||
}
|
||||
|
||||
// |mChannelOffset == 0| means download ends with no bytes received.
|
||||
// We should also wake up those readers who are waiting for data
|
||||
// that will never come.
|
||||
if ((blockOffset > 0 || mChannelOffset == 0) && aNotifyAll) {
|
||||
// Wake up readers who may be waiting for this data
|
||||
mon.NotifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -91,6 +91,19 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
|
||||
size_t* aBytesRead) MOZ_OVERRIDE
|
||||
{
|
||||
nsresult rv = mResource->ReadFromCache(reinterpret_cast<char*>(aBuffer),
|
||||
aOffset, aCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aBytesRead = 0;
|
||||
return false;
|
||||
}
|
||||
*aBytesRead = aCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool Length(int64_t* aSize) MOZ_OVERRIDE
|
||||
{
|
||||
if (mResource->GetLength() < 0)
|
||||
@ -785,14 +798,7 @@ void
|
||||
MP4Reader::NotifyDataArrived(const char* aBuffer, uint32_t aLength,
|
||||
int64_t aOffset)
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
if (GetTaskQueue()) {
|
||||
GetTaskQueue()->Dispatch(
|
||||
NS_NewRunnableMethod(this, &MP4Reader::UpdateIndex));
|
||||
}
|
||||
} else {
|
||||
UpdateIndex();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -135,7 +135,8 @@ SourceBufferResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCo
|
||||
this, aBuffer, aOffset, aCount);
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
int64_t oldOffset = mOffset;
|
||||
nsresult rv = ReadAt(aOffset, aBuffer, aCount, nullptr);
|
||||
uint32_t bytesRead;
|
||||
nsresult rv = ReadAt(aOffset, aBuffer, aCount, &bytesRead);
|
||||
mOffset = oldOffset;
|
||||
return rv;
|
||||
}
|
||||
|
@ -366,6 +366,7 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
[test_eme_stream_capture_blocked.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
[test_empty_resource.html]
|
||||
[test_error_in_video_document.html]
|
||||
skip-if = toolkit == 'android' || (os == 'win' && !debug) || (os == 'mac' && !debug) # bug 608634
|
||||
[test_error_on_404.html]
|
||||
@ -436,8 +437,8 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
[test_play_events_2.html]
|
||||
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
[test_play_twice.html]
|
||||
# Seamonkey: Bug 598252, B2G: Bug 982100, Android: Bug 758476, bug 981086
|
||||
skip-if = appname == "seamonkey" || toolkit == 'gonk' || toolkit == 'android'
|
||||
# Seamonkey: Bug 598252
|
||||
skip-if = appname == "seamonkey"
|
||||
[test_playback.html]
|
||||
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
|
||||
[test_playback_errors.html]
|
||||
|
65
dom/media/test/test_empty_resource.html
Normal file
65
dom/media/test/test_empty_resource.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1094549
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1094549</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094549">Mozilla Bug 1094549</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
function onTimeout() {
|
||||
ok(false, "timed out without getting an error event");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// We expect this test to finish very soon.
|
||||
// A timeout of 15s should be enough for the slow B2G emulator.
|
||||
var timer = setTimeout(onTimeout, 15000);
|
||||
|
||||
function finish(v) {
|
||||
clearTimeout(timer);
|
||||
isnot(v.error, null, "should've got an error event");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function onload() {
|
||||
info("iframe loaded");
|
||||
var v = document.body.getElementsByTagName("iframe")[0]
|
||||
.contentDocument.body.getElementsByTagName("video")[0];
|
||||
|
||||
// Got 'error' as expected, finish the test.
|
||||
if (v.error) {
|
||||
finish(v);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, wait for it.
|
||||
v.onerror = function() {
|
||||
finish(v);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var f = document.createElement("iframe");
|
||||
// Assign a resource file with zero length and expect the error event from
|
||||
// the video element since decoding metadata will fail.
|
||||
f.src = "data:video/webm,";
|
||||
f.addEventListener("load", onload, false);
|
||||
document.body.appendChild(f);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -14,51 +14,67 @@ var manager = new MediaTestManager;
|
||||
|
||||
function startTest(test, token) {
|
||||
var v = document.createElement('video');
|
||||
v.preload = "metadata";
|
||||
v.token = token;
|
||||
manager.started(token);
|
||||
v.src = test.name;
|
||||
v.name = test.name;
|
||||
v.playingCount = 0;
|
||||
v._playedOnce = false;
|
||||
|
||||
var check = function(test, v) { return function() {
|
||||
checkMetadata(test.name, v, test);
|
||||
}}(test, v);
|
||||
|
||||
var noLoad = function(test, v) { return function() {
|
||||
ok(false, test.name + " should not fire 'load' event");
|
||||
}}(test, v);
|
||||
|
||||
function finish(v) {
|
||||
removeNodeAndSource(v);
|
||||
manager.finished(v.token);
|
||||
}
|
||||
|
||||
function mayFinish(v) {
|
||||
if (v.seenEnded && v.seenSuspend) {
|
||||
finish(v);
|
||||
}
|
||||
}
|
||||
|
||||
var checkEnded = function(test, v) { return function() {
|
||||
if (test.duration) {
|
||||
ok(Math.abs(v.currentTime - test.duration) < 0.1,
|
||||
test.name + " current time at end: " + v.currentTime);
|
||||
}
|
||||
|
||||
is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
|
||||
ok(v.readyState != v.NETWORK_LOADED, test.name + " shouldn't report NETWORK_LOADED");
|
||||
ok(v.ended, test.name + " checking playback has ended");
|
||||
ok(v.playingCount > 0, "Expect at least one playing event");
|
||||
v.playingCount = 0;
|
||||
if (v._playedOnce && v.seenSuspend) {
|
||||
v.parentNode.removeChild(v);
|
||||
manager.finished(v.token);
|
||||
|
||||
if (v._playedOnce) {
|
||||
v.seenEnded = true;
|
||||
mayFinish(v);
|
||||
} else {
|
||||
v._playedOnce = true;
|
||||
v.play();
|
||||
}
|
||||
}}(test, v);
|
||||
|
||||
var checkSuspended = function(test, v) { return function() {
|
||||
if (v.seenSuspend)
|
||||
if (v.seenSuspend) {
|
||||
return;
|
||||
}
|
||||
|
||||
v.seenSuspend = true;
|
||||
ok(true, test.name + " got suspend");
|
||||
if (v._playedOnce && v.seenSuspend) {
|
||||
v.parentNode.removeChild(v);
|
||||
manager.finished(v.token);
|
||||
}
|
||||
mayFinish(v);
|
||||
}}(test, v);
|
||||
|
||||
var checkPlaying = function(test, v) { return function() {
|
||||
is(test.name, v.name, "Should be testing file we think we're testing...");
|
||||
v.playingCount++;
|
||||
}}(test, v);
|
||||
|
||||
v.addEventListener("load", noLoad, false);
|
||||
v.addEventListener("loadedmetadata", check, false);
|
||||
v.addEventListener("playing", checkPlaying, false);
|
||||
|
@ -158,8 +158,8 @@ NPObjWrapper_newEnumerate(JSContext *cx, JS::Handle<JSObject*> obj, JSIterateOp
|
||||
JS::Value *statep, jsid *idp);
|
||||
|
||||
static bool
|
||||
NPObjWrapper_NewResolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSObject*> objp);
|
||||
NPObjWrapper_Resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
bool *resolvedp);
|
||||
|
||||
static bool
|
||||
NPObjWrapper_Convert(JSContext *cx, JS::Handle<JSObject*> obj, JSType type, JS::MutableHandle<JS::Value> vp);
|
||||
@ -184,13 +184,13 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
||||
const static js::Class sNPObjectJSWrapperClass =
|
||||
{
|
||||
NPRUNTIME_JSCLASS_NAME,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_NEW_ENUMERATE,
|
||||
NPObjWrapper_AddProperty,
|
||||
NPObjWrapper_DelProperty,
|
||||
NPObjWrapper_GetProperty,
|
||||
NPObjWrapper_SetProperty,
|
||||
(JSEnumerateOp)NPObjWrapper_newEnumerate,
|
||||
(JSResolveOp)NPObjWrapper_NewResolve,
|
||||
NPObjWrapper_Resolve,
|
||||
NPObjWrapper_Convert,
|
||||
NPObjWrapper_Finalize,
|
||||
NPObjWrapper_Call,
|
||||
@ -201,7 +201,6 @@ const static js::Class sNPObjectJSWrapperClass =
|
||||
{
|
||||
nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
NPObjWrapper_ObjectMoved
|
||||
@ -1654,8 +1653,8 @@ NPObjWrapper_newEnumerate(JSContext *cx, JS::Handle<JSObject*> obj, JSIterateOp
|
||||
}
|
||||
|
||||
static bool
|
||||
NPObjWrapper_NewResolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSObject*> objp)
|
||||
NPObjWrapper_Resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
bool *resolvedp)
|
||||
{
|
||||
if (JSID_IS_SYMBOL(id))
|
||||
return true;
|
||||
@ -1685,7 +1684,7 @@ NPObjWrapper_NewResolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsi
|
||||
return false;
|
||||
}
|
||||
|
||||
objp.set(obj);
|
||||
*resolvedp = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1701,7 +1700,7 @@ NPObjWrapper_NewResolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsi
|
||||
JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallNPMethod, 0,
|
||||
JSPROP_ENUMERATE);
|
||||
|
||||
objp.set(obj);
|
||||
*resolvedp = true;
|
||||
|
||||
return fnc != nullptr;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ support-files =
|
||||
[test_event_stopping.html]
|
||||
[test_template.html]
|
||||
[test_template_xhtml.html]
|
||||
[test_template_custom_elements.html]
|
||||
[test_shadowroot.html]
|
||||
[test_shadowroot_inert_element.html]
|
||||
[test_shadowroot_host.html]
|
||||
|
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1091425
|
||||
-->
|
||||
<head>
|
||||
<title>Test for custom elements in template</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<template>
|
||||
<x-foo></x-foo>
|
||||
</template>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1091425">Bug 1091425</a>
|
||||
<script>
|
||||
|
||||
var p = {};
|
||||
p.createdCallback = function() {
|
||||
ok(false, "Created callback should not be called for custom elements in templates.");
|
||||
};
|
||||
|
||||
document.registerElement("x-foo", { prototype: p });
|
||||
|
||||
ok(true, "Created callback should not be called for custom elements in templates.");
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<x-foo></x-foo>
|
||||
</template>
|
||||
</body>
|
||||
</html>
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-applet-element
|
||||
[NeedNewResolve]
|
||||
[NeedResolve]
|
||||
interface HTMLAppletElement : HTMLElement {
|
||||
[Pure, SetterThrows]
|
||||
attribute DOMString align;
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-embed-element
|
||||
[NeedNewResolve]
|
||||
[NeedResolve]
|
||||
interface HTMLEmbedElement : HTMLElement {
|
||||
[Pure, SetterThrows]
|
||||
attribute DOMString src;
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-object-element
|
||||
[NeedNewResolve]
|
||||
[NeedResolve]
|
||||
interface HTMLObjectElement : HTMLElement {
|
||||
[Pure, SetterThrows]
|
||||
attribute DOMString data;
|
||||
|
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-navigator-object
|
||||
[HeaderFile="Navigator.h", NeedNewResolve]
|
||||
[HeaderFile="Navigator.h", NeedResolve]
|
||||
interface Navigator {
|
||||
// objects implementing this interface also implement the interfaces given below
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ interface nsIDOMCrypto;
|
||||
typedef any Transferable;
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/
|
||||
[PrimaryGlobal, NeedNewResolve]
|
||||
[PrimaryGlobal, NeedResolve]
|
||||
/*sealed*/ interface Window : EventTarget {
|
||||
// the current browsing context
|
||||
[Unforgeable, Throws,
|
||||
|
@ -15,12 +15,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1027221
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var x = "x";
|
||||
// Trigger some incremental gc
|
||||
SpecialPowers.Cu.getJSTestingFunctions().gcslice(0);
|
||||
SpecialPowers.Cu.getJSTestingFunctions().gcslice(1);
|
||||
|
||||
// Kick off a worker that uses this same atom
|
||||
var w = new Worker("data:text/plain,Promise.resolve('x').then(function() { postMessage(1); });");
|
||||
// Maybe trigger some more incremental gc
|
||||
SpecialPowers.Cu.getJSTestingFunctions().gcslice(0);
|
||||
SpecialPowers.Cu.getJSTestingFunctions().gcslice(1);
|
||||
|
||||
w.onmessage = function() {
|
||||
ok(true, "Got here");
|
||||
|
@ -90,7 +90,6 @@ XBLEnumerate(JSContext *cx, JS::Handle<JSObject*> obj)
|
||||
static const JSClass gPrototypeJSClass = {
|
||||
"XBL prototype JSClass",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_NEW_RESOLVE |
|
||||
// Our one reserved slot holds the relevant nsXBLPrototypeBinding
|
||||
JSCLASS_HAS_RESERVED_SLOTS(1),
|
||||
JS_PropertyStub, JS_DeletePropertyStub,
|
||||
|
@ -598,7 +598,6 @@ gfxFontconfigUtils::UpdateFontListInternal(bool aForce)
|
||||
mFontsByFamily.Clear();
|
||||
mFontsByFullname.Clear();
|
||||
mLangSupportTable.Clear();
|
||||
mAliasForMultiFonts.Clear();
|
||||
|
||||
// Record the existing font families
|
||||
for (unsigned fs = 0; fs < ArrayLength(fontSets); ++fs) {
|
||||
@ -632,36 +631,6 @@ gfxFontconfigUtils::UpdateFontListInternal(bool aForce)
|
||||
}
|
||||
}
|
||||
|
||||
// XXX we don't support all alias names.
|
||||
// Because if we don't check whether the given font name is alias name,
|
||||
// fontconfig converts the non existing font to sans-serif.
|
||||
// This is not good if the web page specifies font-family
|
||||
// that has Windows font name in the first.
|
||||
NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
|
||||
nsAdoptingCString list = Preferences::GetCString("font.alias-list");
|
||||
|
||||
if (!list.IsEmpty()) {
|
||||
const char kComma = ',';
|
||||
const char *p, *p_end;
|
||||
list.BeginReading(p);
|
||||
list.EndReading(p_end);
|
||||
while (p < p_end) {
|
||||
while (nsCRT::IsAsciiSpace(*p)) {
|
||||
if (++p == p_end)
|
||||
break;
|
||||
}
|
||||
if (p == p_end)
|
||||
break;
|
||||
const char *start = p;
|
||||
while (++p != p_end && *p != kComma)
|
||||
/* nothing */ ;
|
||||
nsAutoCString name(Substring(start, p));
|
||||
name.CompressWhitespace(false, true);
|
||||
mAliasForMultiFonts.AppendElement(name);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
mLastConfig = currentConfig;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -302,8 +302,6 @@ protected:
|
||||
nsTHashtable<LangSupportEntry> mLangSupportTable;
|
||||
const nsTArray< nsCountedRef<FcPattern> > mEmptyPatternArray;
|
||||
|
||||
nsTArray<nsCString> mAliasForMultiFonts;
|
||||
|
||||
FcConfig *mLastConfig;
|
||||
|
||||
#ifdef MOZ_BUNDLED_FONTS
|
||||
|
@ -1227,12 +1227,6 @@ PrepareSortPattern(FcPattern *aPattern, double aFallbackSize,
|
||||
cairo_font_options_destroy(options);
|
||||
FcPatternAddBool(aPattern, PRINTING_FC_PROPERTY, FcTrue);
|
||||
} else {
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
cairo_font_options_t *options = cairo_font_options_create();
|
||||
cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE);
|
||||
cairo_ft_font_options_substitute(options, aPattern);
|
||||
cairo_font_options_destroy(options);
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
ApplyGdkScreenFontOptions(aPattern);
|
||||
#endif
|
||||
@ -1965,15 +1959,11 @@ CreateScaledFont(FcPattern *aPattern, cairo_font_face_t *aFace)
|
||||
// font will be used, but currently we don't have different gfxFonts for
|
||||
// different surface font_options, so we'll create a font suitable for the
|
||||
// Screen. Image and xlib surfaces default to CAIRO_HINT_METRICS_ON.
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
|
||||
#else
|
||||
if (printing) {
|
||||
cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
|
||||
} else {
|
||||
cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_ON);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The remaining options have been recorded on the pattern and the face.
|
||||
// _cairo_ft_options_merge has some logic to decide which options from the
|
||||
@ -1998,11 +1988,10 @@ CreateScaledFont(FcPattern *aPattern, cairo_font_face_t *aFace)
|
||||
//
|
||||
// Fallback values here mirror treatment of defaults in cairo-ft-font.c.
|
||||
FcBool hinting = FcFalse;
|
||||
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
if (FcPatternGetBool(aPattern, FC_HINTING, 0, &hinting) != FcResultMatch) {
|
||||
hinting = FcTrue;
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_hint_style_t hint_style;
|
||||
if (printing || !hinting) {
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
|
@ -949,7 +949,8 @@ gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength,
|
||||
|
||||
gfxFloat
|
||||
gfxTextRun::GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider *aProvider)
|
||||
PropertyProvider *aProvider,
|
||||
PropertyProvider::Spacing* aSpacing)
|
||||
{
|
||||
NS_ASSERTION(aStart + aLength <= GetLength(), "Substring out of range");
|
||||
|
||||
@ -960,6 +961,10 @@ gfxTextRun::GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
gfxFloat result = ComputePartialLigatureWidth(aStart, ligatureRunStart, aProvider) +
|
||||
ComputePartialLigatureWidth(ligatureRunEnd, aStart + aLength, aProvider);
|
||||
|
||||
if (aSpacing) {
|
||||
aSpacing->mBefore = aSpacing->mAfter = 0;
|
||||
}
|
||||
|
||||
// Account for all remaining spacing here. This is more efficient than
|
||||
// processing it along with the glyphs.
|
||||
if (aProvider && (mFlags & gfxTextRunFactory::TEXT_ENABLE_SPACING)) {
|
||||
@ -972,6 +977,10 @@ gfxTextRun::GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider::Spacing *space = &spacingBuffer[i];
|
||||
result += space->mBefore + space->mAfter;
|
||||
}
|
||||
if (aSpacing) {
|
||||
aSpacing->mBefore = spacingBuffer[0].mBefore;
|
||||
aSpacing->mAfter = spacingBuffer.LastElement().mAfter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,9 +267,13 @@ public:
|
||||
/**
|
||||
* Computes just the advance width for a substring.
|
||||
* Uses GetSpacing from aBreakProvider.
|
||||
* If aSpacing is not null, the spacing attached before and after
|
||||
* the substring would be returned in it. NOTE: the spacing is
|
||||
* included in the advance width.
|
||||
*/
|
||||
gfxFloat GetAdvanceWidth(uint32_t aStart, uint32_t aLength,
|
||||
PropertyProvider *aProvider);
|
||||
PropertyProvider *aProvider,
|
||||
PropertyProvider::Spacing* aSpacing = nullptr);
|
||||
|
||||
/**
|
||||
* Clear all stored line breaks for the given range (both before and after),
|
||||
|
@ -26,6 +26,9 @@ interface nsITextToSubURI : nsISupports
|
||||
* give the original escaped string
|
||||
* <li> In case of a conversion error, the URI fragment (escaped) is
|
||||
* assumed to be in UTF-8 and converted to AString (UTF-16)
|
||||
* <li> In case of successful conversion to unicode but it contains
|
||||
* any characters in network.IDN.blacklist_chars (except space)
|
||||
* then the final result is escaped
|
||||
* <li> Always succeeeds (callers don't need to do error checking)
|
||||
* </ul>
|
||||
*
|
||||
|
@ -10,11 +10,38 @@
|
||||
#include "nsTextToSubURI.h"
|
||||
#include "nsCRT.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
using mozilla::dom::EncodingUtils;
|
||||
|
||||
// Fallback value for the pref "network.IDN.blacklist_chars".
|
||||
// UnEscapeURIForUI allows unescaped space; other than that, this is
|
||||
// the same as the default "network.IDN.blacklist_chars" value.
|
||||
static const char16_t sNetworkIDNBlacklistChars[] =
|
||||
{
|
||||
/*0x0020,*/
|
||||
0x00A0, 0x00BC, 0x00BD, 0x00BE, 0x01C3, 0x02D0, 0x0337,
|
||||
0x0338, 0x0589, 0x05C3, 0x05F4, 0x0609, 0x060A, 0x066A, 0x06D4,
|
||||
0x0701, 0x0702, 0x0703, 0x0704, 0x115F, 0x1160, 0x1735, 0x2000,
|
||||
0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008,
|
||||
0x2009, 0x200A, 0x200B, 0x200E, 0x200F, 0x2024, 0x2027, 0x2028,
|
||||
0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, 0x202F, 0x2039,
|
||||
0x203A, 0x2041, 0x2044, 0x2052, 0x205F, 0x2153, 0x2154, 0x2155,
|
||||
0x2156, 0x2157, 0x2158, 0x2159, 0x215A, 0x215B, 0x215C, 0x215D,
|
||||
0x215E, 0x215F, 0x2215, 0x2236, 0x23AE, 0x2571, 0x29F6, 0x29F8,
|
||||
0x2AFB, 0x2AFD, 0x2FF0, 0x2FF1, 0x2FF2, 0x2FF3, 0x2FF4, 0x2FF5,
|
||||
0x2FF6, 0x2FF7, 0x2FF8, 0x2FF9, 0x2FFA, 0x2FFB, 0x3000, 0x3002,
|
||||
0x3014, 0x3015, 0x3033, 0x3164, 0x321D, 0x321E, 0x33AE, 0x33AF,
|
||||
0x33C6, 0x33DF, 0xA789, 0xFE14, 0xFE15, 0xFE3F, 0xFE5D, 0xFE5E,
|
||||
0xFEFF, 0xFF0E, 0xFF0F, 0xFF61, 0xFFA0, 0xFFF9, 0xFFFA, 0xFFFB,
|
||||
0xFFFC, 0xFFFD,
|
||||
'\0'
|
||||
};
|
||||
|
||||
nsTextToSubURI::nsTextToSubURI()
|
||||
{
|
||||
mUnsafeChars.SetIsVoid(true);
|
||||
}
|
||||
nsTextToSubURI::~nsTextToSubURI()
|
||||
{
|
||||
@ -213,9 +240,36 @@ NS_IMETHODIMP nsTextToSubURI::UnEscapeURIForUI(const nsACString & aCharset,
|
||||
// sequences are also considered failure in this context
|
||||
if (convertURItoUnicode(
|
||||
PromiseFlatCString(aCharset), unescapedSpec, true, _retval)
|
||||
!= NS_OK)
|
||||
!= NS_OK) {
|
||||
// assume UTF-8 instead of ASCII because hostname (IDN) may be in UTF-8
|
||||
CopyUTF8toUTF16(aURIFragment, _retval);
|
||||
}
|
||||
|
||||
// if there are any characters that are unsafe for IRIs, reescape.
|
||||
if (mUnsafeChars.IsVoid()) {
|
||||
nsCOMPtr<nsISupportsString> blacklist;
|
||||
nsresult rv = mozilla::Preferences::GetComplex("network.IDN.blacklist_chars",
|
||||
NS_GET_IID(nsISupportsString),
|
||||
getter_AddRefs(blacklist));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
blacklist->ToString(getter_Copies(mUnsafeChars));
|
||||
mUnsafeChars.StripChars(" "); // we allow SPACE in this method
|
||||
MOZ_ASSERT(!mUnsafeChars.IsVoid());
|
||||
} else {
|
||||
NS_WARNING("Failed to get the 'network.IDN.blacklist_chars' preference");
|
||||
}
|
||||
}
|
||||
// We check IsEmpty() intentionally here instead of IsVoid() because an
|
||||
// empty (or just spaces) pref value is likely a mistake/error of some sort.
|
||||
const char16_t* unsafeChars =
|
||||
mUnsafeChars.IsEmpty() ? sNetworkIDNBlacklistChars : mUnsafeChars;
|
||||
if (PromiseFlatString(_retval).FindCharInSet(unsafeChars) != kNotFound) {
|
||||
// Note that this reescapes all non-ASCII characters in the URI, not just
|
||||
// the unsafe characters.
|
||||
nsString reescapedSpec;
|
||||
_retval = NS_EscapeURL(_retval, esc_OnlyNonASCII, reescapedSpec);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,9 @@ private:
|
||||
const nsAFlatCString &aURI,
|
||||
bool aIRI,
|
||||
nsAString &_retval);
|
||||
|
||||
// Void until we get the pref "network.IDN.blacklist_chars" successfully.
|
||||
nsXPIDLString mUnsafeChars;
|
||||
};
|
||||
|
||||
#endif // nsTextToSubURI_h__
|
||||
|
@ -119,24 +119,12 @@ typedef bool
|
||||
// (e.g., the DOM attributes for a given node reflected as obj) on demand.
|
||||
//
|
||||
// JS looks for a property in an object, and if not found, tries to resolve
|
||||
// the given id. If resolve succeeds, the engine looks again in case resolve
|
||||
// defined obj[id]. If no such property exists directly in obj, the process
|
||||
// is repeated with obj's prototype, etc.
|
||||
// the given id. *resolvedp should be set to true iff the property was
|
||||
// was defined on |obj|.
|
||||
//
|
||||
// NB: JSNewResolveOp provides a cheaper way to resolve lazy properties.
|
||||
typedef bool
|
||||
(* JSResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
|
||||
|
||||
// Like JSResolveOp, except the *objp out parameter, on success, should be null
|
||||
// to indicate that id was not resolved; and non-null, referring to obj or one
|
||||
// of its prototypes, if id was resolved. The hook may assume *objp is null on
|
||||
// entry.
|
||||
//
|
||||
// This hook instead of JSResolveOp is called via the JSClass.resolve member
|
||||
// if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
|
||||
typedef bool
|
||||
(* JSNewResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleObject objp);
|
||||
(* JSResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
bool *resolvedp);
|
||||
|
||||
// Convert obj to the given type, returning true with the resulting value in
|
||||
// *vp on success, and returning false on error or exception.
|
||||
@ -177,11 +165,6 @@ typedef bool
|
||||
typedef void
|
||||
(* JSTraceOp)(JSTracer *trc, JSObject *obj);
|
||||
|
||||
// Hook that creates an iterator object for a given object. Returns the
|
||||
// iterator object or null if an error or exception was thrown on cx.
|
||||
typedef JSObject *
|
||||
(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, bool keysonly);
|
||||
|
||||
typedef JSObject *
|
||||
(* JSWeakmapKeyDelegateOp)(JSObject *obj);
|
||||
|
||||
@ -325,7 +308,6 @@ struct ClassExtension
|
||||
{
|
||||
ObjectOp outerObject;
|
||||
InnerObjectOp innerObject;
|
||||
JSIteratorOp iteratorObject;
|
||||
|
||||
/*
|
||||
* isWrappedNative is true only if the class is an XPCWrappedNative.
|
||||
@ -361,7 +343,7 @@ struct ClassExtension
|
||||
};
|
||||
|
||||
#define JS_NULL_CLASS_SPEC {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}
|
||||
#define JS_NULL_CLASS_EXT {nullptr,nullptr,nullptr,false,nullptr,nullptr}
|
||||
#define JS_NULL_CLASS_EXT {nullptr,nullptr,false,nullptr,nullptr}
|
||||
|
||||
struct ObjectOps
|
||||
{
|
||||
@ -401,12 +383,11 @@ typedef void (*JSClassInternal)();
|
||||
struct JSClass {
|
||||
JS_CLASS_MEMBERS(JSFinalizeOp);
|
||||
|
||||
void *reserved[33];
|
||||
void *reserved[32];
|
||||
};
|
||||
|
||||
#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot
|
||||
#define JSCLASS_NEW_ENUMERATE (1<<1) // has JSNewEnumerateOp hook
|
||||
#define JSCLASS_NEW_RESOLVE (1<<2) // has JSNewResolveOp hook
|
||||
#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) // private is (nsISupports *)
|
||||
#define JSCLASS_IS_DOMJSCLASS (1<<4) // objects are DOM
|
||||
#define JSCLASS_IMPLEMENTS_BARRIERS (1<<5) // Correctly implements GC read
|
||||
|
@ -11,11 +11,25 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
struct JS_PUBLIC_API(TimeBudget)
|
||||
{
|
||||
int64_t budget;
|
||||
|
||||
explicit TimeBudget(int64_t milliseconds) { budget = milliseconds; }
|
||||
};
|
||||
|
||||
struct JS_PUBLIC_API(WorkBudget)
|
||||
{
|
||||
int64_t budget;
|
||||
|
||||
explicit WorkBudget(int64_t work) { budget = work; }
|
||||
};
|
||||
|
||||
/*
|
||||
* This class records how much work has been done in a given collection slice, so that
|
||||
* we can return before pausing for too long. Some slices are allowed to run for
|
||||
* unlimited time, and others are bounded. To reduce the number of gettimeofday
|
||||
* calls, we only check the time every 1000 operations.
|
||||
* This class records how much work has been done in a given collection slice,
|
||||
* so that we can return before pausing for too long. Some slices are allowed
|
||||
* to run for unlimited time, and others are bounded. To reduce the number of
|
||||
* gettimeofday calls, we only check the time every 1000 operations.
|
||||
*/
|
||||
struct JS_PUBLIC_API(SliceBudget)
|
||||
{
|
||||
@ -24,17 +38,18 @@ struct JS_PUBLIC_API(SliceBudget)
|
||||
|
||||
static const intptr_t CounterReset = 1000;
|
||||
|
||||
static const int64_t Unlimited = 0;
|
||||
static int64_t TimeBudget(int64_t millis);
|
||||
static int64_t WorkBudget(int64_t work);
|
||||
static const int64_t Unlimited = -1;
|
||||
|
||||
/* Equivalent to SliceBudget(UnlimitedBudget). */
|
||||
/* Use to create an unlimited budget. */
|
||||
SliceBudget();
|
||||
|
||||
/* Instantiate as SliceBudget(Time/WorkBudget(n)). */
|
||||
explicit SliceBudget(int64_t budget);
|
||||
/* Instantiate as SliceBudget(TimeBudget(n)). */
|
||||
explicit SliceBudget(TimeBudget time);
|
||||
|
||||
void reset() {
|
||||
/* Instantiate as SliceBudget(WorkBudget(n)). */
|
||||
explicit SliceBudget(WorkBudget work);
|
||||
|
||||
void makeUnlimited() {
|
||||
deadline = unlimitedDeadline;
|
||||
counter = unlimitedStartCounter;
|
||||
}
|
||||
@ -43,10 +58,8 @@ struct JS_PUBLIC_API(SliceBudget)
|
||||
counter -= amt;
|
||||
}
|
||||
|
||||
bool checkOverBudget();
|
||||
|
||||
bool isOverBudget() {
|
||||
if (counter >= 0)
|
||||
if (counter > 0)
|
||||
return false;
|
||||
return checkOverBudget();
|
||||
}
|
||||
@ -55,10 +68,11 @@ struct JS_PUBLIC_API(SliceBudget)
|
||||
return deadline == unlimitedDeadline;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
bool checkOverBudget();
|
||||
|
||||
static const int64_t unlimitedDeadline = INT64_MAX;
|
||||
static const intptr_t unlimitedStartCounter = INTPTR_MAX;
|
||||
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
@ -9,8 +9,11 @@
|
||||
|
||||
#include "mozilla/NullPtr.h"
|
||||
|
||||
#include "jsalloc.h"
|
||||
#include "jspubtd.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
class JS_PUBLIC_API(JSTracer);
|
||||
|
||||
namespace JS {
|
||||
@ -212,6 +215,15 @@ JS_TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_TraceRuntime(JSTracer *trc);
|
||||
|
||||
namespace JS {
|
||||
typedef js::HashSet<Zone *, js::DefaultHasher<Zone *>, js::SystemAllocPolicy> ZoneSet;
|
||||
}
|
||||
|
||||
// Trace every value within |zones| that is wrapped by a cross-compartment
|
||||
// wrapper from a zone that is not an element of |zones|.
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_TraceIncomingCCWs(JSTracer *trc, const JS::ZoneSet &zones);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_GetTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
|
||||
void *thing, JSGCTraceKind kind, bool includeDetails);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/TracingAPI.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
// JS::ubi::Node
|
||||
@ -135,7 +136,6 @@
|
||||
// teach the GC how to root ubi::Nodes, fix up hash tables that use them as
|
||||
// keys, etc.
|
||||
|
||||
|
||||
namespace JS {
|
||||
namespace ubi {
|
||||
|
||||
|
@ -560,14 +560,15 @@ TryEnablingIon(JSContext *cx, AsmJSModule &module, HandleFunction fun, uint32_t
|
||||
return true;
|
||||
}
|
||||
|
||||
// Enable
|
||||
// The exit may have become optimized while executing the FFI.
|
||||
if (module.exitIsOptimized(exitIndex))
|
||||
return true;
|
||||
|
||||
IonScript *ionScript = script->ionScript();
|
||||
if (!ionScript->addDependentAsmJSModule(cx, DependentAsmJSModuleExit(&module, exitIndex)))
|
||||
return false;
|
||||
|
||||
AsmJSModule::ExitDatum &exitDatum = module.exitIndexToGlobalDatum(exitIndex);
|
||||
exitDatum.exit = module.ionExitTrampoline(module.exit(exitIndex));
|
||||
exitDatum.ionScript = ionScript;
|
||||
module.optimizeExit(exitIndex, ionScript);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1280,6 +1280,7 @@ class AsmJSModule
|
||||
MOZ_ASSERT(isFinished());
|
||||
return pc >= code_ && pc < (code_ + codeBytes());
|
||||
}
|
||||
private:
|
||||
uint8_t *interpExitTrampoline(const Exit &exit) const {
|
||||
MOZ_ASSERT(isFinished());
|
||||
MOZ_ASSERT(exit.interpCodeOffset_);
|
||||
@ -1290,6 +1291,7 @@ class AsmJSModule
|
||||
MOZ_ASSERT(exit.ionCodeOffset_);
|
||||
return code_ + exit.ionCodeOffset_;
|
||||
}
|
||||
public:
|
||||
|
||||
// Lookup a callsite by the return pc (from the callee to the caller).
|
||||
// Return null if no callsite was found.
|
||||
@ -1417,6 +1419,17 @@ class AsmJSModule
|
||||
MOZ_ASSERT(isFinished());
|
||||
return *(ExitDatum *)(globalData() + exitIndexToGlobalDataOffset(exitIndex));
|
||||
}
|
||||
bool exitIsOptimized(unsigned exitIndex) const {
|
||||
MOZ_ASSERT(isFinished());
|
||||
ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
|
||||
return exitDatum.exit != interpExitTrampoline(exit(exitIndex));
|
||||
}
|
||||
void optimizeExit(unsigned exitIndex, jit::IonScript *ionScript) const {
|
||||
MOZ_ASSERT(!exitIsOptimized(exitIndex));
|
||||
ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
|
||||
exitDatum.exit = ionExitTrampoline(exit(exitIndex));
|
||||
exitDatum.ionScript = ionScript;
|
||||
}
|
||||
void detachIonCompilation(size_t exitIndex) const {
|
||||
MOZ_ASSERT(isFinished());
|
||||
ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
|
||||
|
@ -628,16 +628,15 @@ GCSlice(JSContext *cx, unsigned argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool limit = true;
|
||||
uint32_t budget = 0;
|
||||
SliceBudget budget;
|
||||
if (args.length() == 1) {
|
||||
if (!ToUint32(cx, args[0], &budget))
|
||||
uint32_t work = 0;
|
||||
if (!ToUint32(cx, args[0], &work))
|
||||
return false;
|
||||
} else {
|
||||
limit = false;
|
||||
budget = SliceBudget(WorkBudget(work));
|
||||
}
|
||||
|
||||
cx->runtime()->gc.gcDebugSlice(limit, budget);
|
||||
cx->runtime()->gc.gcDebugSlice(budget);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ function loadCallgraph(file)
|
||||
suppressedFunctions[name] = true;
|
||||
}
|
||||
|
||||
for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, int64, uint32, uint32)',
|
||||
for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, js::SliceBudget*, uint32, uint32)',
|
||||
'void js::gc::GCRuntime::minorGC(uint32)',
|
||||
'void js::gc::GCRuntime::minorGC(uint32)' ])
|
||||
{
|
||||
|
@ -281,7 +281,7 @@ class GCRuntime
|
||||
void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
void gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
|
||||
void gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
void gcDebugSlice(bool limit, int64_t objCount);
|
||||
void gcDebugSlice(SliceBudget &budget);
|
||||
|
||||
void runDebugGC();
|
||||
inline void poke();
|
||||
@ -510,14 +510,14 @@ class GCRuntime
|
||||
|
||||
bool initZeal();
|
||||
void requestMajorGC(JS::gcreason::Reason reason);
|
||||
void collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
void collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
bool gcCycle(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
bool gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
gcstats::ZoneGCStats scanZonesBeforeGC();
|
||||
void budgetIncrementalGC(int64_t *budget);
|
||||
void budgetIncrementalGC(SliceBudget &budget);
|
||||
void resetIncrementalGC(const char *reason);
|
||||
void incrementalCollectSlice(int64_t budget, JS::gcreason::Reason reason);
|
||||
void incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason reason);
|
||||
void pushZealSelectedObjects();
|
||||
void purgeRuntime();
|
||||
bool beginMarkPhase(JS::gcreason::Reason reason);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "gc/GCInternals.h"
|
||||
#include "gc/Marking.h"
|
||||
#include "gc/Zone.h"
|
||||
|
||||
#include "vm/Symbol.h"
|
||||
|
||||
@ -119,6 +120,37 @@ JS_TraceRuntime(JSTracer *trc)
|
||||
TraceRuntime(trc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_TraceIncomingCCWs(JSTracer *trc, const JS::ZoneSet &zones)
|
||||
{
|
||||
for (js::ZonesIter z(trc->runtime(), SkipAtoms); !z.done(); z.next()) {
|
||||
Zone *zone = z.get();
|
||||
if (!zone || zones.has(zone))
|
||||
continue;
|
||||
|
||||
for (js::CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
|
||||
JSCompartment *comp = c.get();
|
||||
if (!comp)
|
||||
continue;
|
||||
|
||||
for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
|
||||
const CrossCompartmentKey &key = e.front().key();
|
||||
// StringWrappers are just used to avoid copying strings across
|
||||
// zones multiple times, and don't hold a strong reference.
|
||||
if (key.kind == CrossCompartmentKey::StringWrapper)
|
||||
continue;
|
||||
// Ignore CCWs whose wrapped value doesn't live in our given set
|
||||
// of zones.
|
||||
if (!zones.has(static_cast<JSObject *>(key.wrapped)->zone()))
|
||||
continue;
|
||||
|
||||
void *thing = key.wrapped;
|
||||
trc->callback(trc, &thing, GetGCThingTraceKind(key.wrapped));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
CountDecimalDigits(size_t num)
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "gc/FindSCCs.h"
|
||||
#include "gc/GCRuntime.h"
|
||||
#include "js/TracingAPI.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
@ -259,7 +260,6 @@ struct Zone : public JS::shadow::Zone,
|
||||
//
|
||||
// This is used during GC while calculating zone groups to record edges that
|
||||
// can't be determined by examining this zone by itself.
|
||||
typedef js::HashSet<Zone *, js::DefaultHasher<Zone *>, js::SystemAllocPolicy> ZoneSet;
|
||||
ZoneSet gcZoneGroupEdges;
|
||||
|
||||
// Malloc counter to measure memory pressure for GC scheduling. It runs from
|
||||
|
@ -28,7 +28,7 @@ gcPreserveCode();
|
||||
try {
|
||||
mjitChunkLimit(1);
|
||||
} catch(exc1) {}
|
||||
gcslice(0);
|
||||
gcslice(1);
|
||||
m(1);
|
||||
gc();
|
||||
m(2);
|
||||
|
@ -3,4 +3,4 @@
|
||||
//
|
||||
|
||||
gc();
|
||||
evaluate("gcslice(0);");
|
||||
evaluate("gcslice(1);");
|
||||
|
@ -20,7 +20,7 @@ function h(code) {
|
||||
h("\
|
||||
p=m();\
|
||||
gcPreserveCode();\
|
||||
gcslice(7);\
|
||||
gcslice(8);\
|
||||
")
|
||||
h("\"\"")
|
||||
h("")
|
||||
|
@ -3,7 +3,7 @@
|
||||
//
|
||||
gc()
|
||||
schedulegc(this)
|
||||
gcslice(2)
|
||||
gcslice(3)
|
||||
function f() {
|
||||
this["x"] = this["x"] = {}
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
function printBugNumber (num) {
|
||||
BUGNUMBER = num;
|
||||
}
|
||||
gcslice(0)
|
||||
gcslice(1)
|
||||
schedulegc(this);
|
||||
gcslice(1);
|
||||
gcslice(2);
|
||||
var BUGNUMBER = ("one");
|
||||
printBugNumber();
|
||||
|
@ -116,7 +116,12 @@ var proxyObj = {
|
||||
};
|
||||
|
||||
var p = new Proxy([1, 2, 3, 4, 5], proxyObj);
|
||||
assertDeepEq(Array.prototype.copyWithin.call(p, 0, 3), [6, 7, , , 5]);
|
||||
Array.prototype.copyWithin.call(p, 0, 3);
|
||||
for (name of Object.getOwnPropertyNames(p)) {
|
||||
print(name + ": " + uneval(Object.getOwnPropertyDescriptor(p, name)));
|
||||
}
|
||||
|
||||
assertDeepEq(p, [6, 7, , , 5]);
|
||||
|
||||
// test if we throw in between
|
||||
arr = [1, 2, 3, 4, 5];
|
||||
|
@ -1,6 +1,6 @@
|
||||
var g1 = newGlobal();
|
||||
schedulegc(g1);
|
||||
gcslice(0);
|
||||
gcslice(1);
|
||||
function testEq(b) {
|
||||
var a = deserialize(serialize(b));
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ function gen()
|
||||
yield 1;
|
||||
local = null;
|
||||
gc();
|
||||
gcslice(0);
|
||||
gcslice(0); // Start IGC, but don't mark anything.
|
||||
yield 2;
|
||||
}
|
||||
|
||||
|
@ -12,5 +12,5 @@ function recur(n)
|
||||
}
|
||||
|
||||
validategc(false);
|
||||
gcslice(0);
|
||||
gcslice(1);
|
||||
recur(10);
|
||||
|
@ -11,8 +11,8 @@ expect = "generator function foo returns a value";
|
||||
actual = (function (j) {}).message;
|
||||
reportCompare(expect, actual, summary + ": 1");
|
||||
reportCompare(expect, actual, summary + ": 2");
|
||||
gcslice(0);
|
||||
gcslice(1);
|
||||
gcslice(2);
|
||||
gc();
|
||||
var strings = [ (0), ];
|
||||
for (var i = 0; i < strings.length; i++)
|
||||
|
@ -4,7 +4,7 @@ evalcx("\
|
||||
gcslice = function() { };\
|
||||
array = new Uint8Array;\
|
||||
t0 = array.subarray();\
|
||||
gcslice(11); \
|
||||
gcslice(12); \
|
||||
array.subarray();\
|
||||
gc();\
|
||||
gc();\
|
||||
|
@ -3,7 +3,7 @@
|
||||
if (typeof evalInWorker == "undefined")
|
||||
quit();
|
||||
|
||||
gcslice(10);
|
||||
gcslice(11);
|
||||
evalInWorker("print('helo world');");
|
||||
for (i = 0; i < 100000; i++) {}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
if (this.hasOwnProperty('Intl')) {
|
||||
gc();
|
||||
gcslice(0);
|
||||
gcslice(1);
|
||||
var thisValues = [ "x" ];
|
||||
thisValues.forEach(function (value) {
|
||||
var format = Intl.DateTimeFormat.call(value);
|
||||
|
@ -1,5 +1,5 @@
|
||||
gc();
|
||||
gcslice(0);
|
||||
gcslice(1);
|
||||
function isClone(a, b) {
|
||||
var rmemory = new WeakMap();
|
||||
rmemory.set(a,b);
|
||||
|
@ -9,5 +9,5 @@ var recursiveFunctions = [{
|
||||
eval(a.text.replace(/@/g, ""))
|
||||
}
|
||||
})();
|
||||
gcslice(2868);
|
||||
gcslice(2869);
|
||||
Function("v={c:[{x:[[]],N:{x:[{}[d]]}}]}=minorgc(true)")()
|
||||
|
@ -10,5 +10,5 @@ var recursiveFunctions = [{
|
||||
eval(a.text.replace(/@/g, ""))
|
||||
}
|
||||
})();
|
||||
gcslice(2868);
|
||||
gcslice(2869);
|
||||
Function("v={c:[{x:[[]],N:{x:[{}[d]]}}]}=minorgc(true)")()
|
||||
|
@ -10,5 +10,5 @@ var recursiveFunctions = [{
|
||||
eval(a.text.replace(/@/g, ""))
|
||||
}
|
||||
})();
|
||||
gcslice(2868);
|
||||
gcslice(2869);
|
||||
Function("v={c:[{x:[[]],N:{x:[{}[d]]}}]}=minorgc(true)")()
|
||||
|
@ -4,6 +4,6 @@ var juneDate = new Date(2000, 5, 20, 0, 0, 0, 0);
|
||||
for (var i = 0; i < function(x) myObj(Date.prototype.toString.apply(x)); void i) {
|
||||
eval(a.text.replace(/@/g, ""))
|
||||
}
|
||||
gcslice(2600);
|
||||
gcslice(2601);
|
||||
function testcase() {}
|
||||
new Uint16Array(testcase);
|
||||
|
@ -23,7 +23,7 @@ function init()
|
||||
*/
|
||||
eval("init()");
|
||||
|
||||
gcslice(0);
|
||||
gcslice(0); // Start IGC, but don't mark anything.
|
||||
selectforgc(objs.root2);
|
||||
gcslice(1);
|
||||
objs.root2.ptr = objs.root1.ptr;
|
||||
|
@ -22,7 +22,7 @@ function init()
|
||||
*/
|
||||
eval("init()");
|
||||
|
||||
gcslice(0);
|
||||
gcslice(0); // Start IGC, but don't mark anything.
|
||||
selectforgc(objs.root);
|
||||
gcslice(1);
|
||||
delete objs.root.b;
|
||||
|
@ -4,7 +4,7 @@ var g1 = newGlobal();
|
||||
var g2 = newGlobal();
|
||||
|
||||
schedulegc(g1);
|
||||
gcslice(0);
|
||||
gcslice(0); // Start IGC, but don't mark anything.
|
||||
schedulegc(g2);
|
||||
gcslice(1);
|
||||
gcslice();
|
||||
|
@ -5,7 +5,7 @@ var g2 = newGlobal();
|
||||
|
||||
schedulegc(g1);
|
||||
schedulegc(g2);
|
||||
gcslice(0);
|
||||
gcslice(0); // Start IGC, but don't mark anything.
|
||||
schedulegc(g1);
|
||||
gcslice(1);
|
||||
gcslice();
|
||||
|
20
js/src/jit-test/tests/proxy/testDirectProxySet7.js
Normal file
20
js/src/jit-test/tests/proxy/testDirectProxySet7.js
Normal file
@ -0,0 +1,20 @@
|
||||
// Assigning to a proxy with no set handler calls the defineProperty handler
|
||||
// when no such property already exists.
|
||||
|
||||
var hits = 0;
|
||||
var t = {};
|
||||
var p = new Proxy(t, {
|
||||
defineProperty(t, id, desc) { hits++; }
|
||||
});
|
||||
p.x = 1;
|
||||
assertEq(hits, 1);
|
||||
assertEq("x" in t, false);
|
||||
|
||||
// Same thing, but the receiver is a plain object inheriting from p:
|
||||
var receiver = Object.create(p);
|
||||
hits = 0;
|
||||
receiver.x = 2;
|
||||
assertEq(hits, 0);
|
||||
assertEq("x" in t, false);
|
||||
assertEq(receiver.hasOwnProperty("x"), true);
|
||||
assertEq(receiver.x, 2);
|
21
js/src/jit-test/tests/proxy/testDirectProxySet8.js
Normal file
21
js/src/jit-test/tests/proxy/testDirectProxySet8.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Assigning to a proxy with no set handler calls the defineProperty handler
|
||||
// when an existing inherited data property already exists.
|
||||
|
||||
var hits = 0;
|
||||
var proto = {x: 1};
|
||||
var t = Object.create(proto);
|
||||
var p = new Proxy(t, {
|
||||
defineProperty(t, id, desc) { hits++; }
|
||||
});
|
||||
p.x = 2;
|
||||
assertEq(hits, 1);
|
||||
assertEq(proto.x, 1);
|
||||
assertEq(t.hasOwnProperty("x"), false);
|
||||
|
||||
// Same thing, but the receiver is a plain object inheriting from p:
|
||||
var receiver = Object.create(p);
|
||||
receiver.x = 2;
|
||||
assertEq(hits, 1);
|
||||
assertEq(t.hasOwnProperty("x"), false);
|
||||
assertEq(receiver.hasOwnProperty("x"), true);
|
||||
assertEq(receiver.x, 2);
|
24
js/src/jit-test/tests/proxy/testDirectProxySetArray1.js
Normal file
24
js/src/jit-test/tests/proxy/testDirectProxySetArray1.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Assigning to a missing array element (a hole) via a proxy with no set handler
|
||||
// calls the defineProperty handler.
|
||||
|
||||
function test(id) {
|
||||
var arr = [, 1, 2, 3];
|
||||
var p = new Proxy(arr, {
|
||||
defineProperty(t, id, desc) {
|
||||
hits++;
|
||||
assertEq(desc.value, "ponies");
|
||||
assertEq(desc.enumerable, true);
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.writable, true);
|
||||
}
|
||||
});
|
||||
var hits = 0;
|
||||
p[id] = "ponies";
|
||||
assertEq(hits, 1);
|
||||
assertEq(id in arr, false);
|
||||
assertEq(arr.length, 4);
|
||||
}
|
||||
|
||||
test(0);
|
||||
test(4);
|
||||
test("str");
|
15
js/src/jit-test/tests/proxy/testDirectProxySetArray2.js
Normal file
15
js/src/jit-test/tests/proxy/testDirectProxySetArray2.js
Normal file
@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
if (this.Reflect && Reflect.set)
|
||||
throw new Error("Congrats on implementing Reflect.set! Uncomment this test for 1 karma point.");
|
||||
|
||||
/*
|
||||
load("asserts.js");
|
||||
|
||||
var a = [0, 1, 2, 3];
|
||||
var p = new Proxy({}, {});
|
||||
Reflect.set(p, "length", 2, a);
|
||||
assertEq("length" in p, false);
|
||||
assertEq(a.length, 2);
|
||||
assertDeepEq(a, [0, 1]);
|
||||
*/
|
15
js/src/jit-test/tests/proxy/testDirectProxySetNested.js
Normal file
15
js/src/jit-test/tests/proxy/testDirectProxySetNested.js
Normal file
@ -0,0 +1,15 @@
|
||||
// The receiver argument is passed through proxies with no "set" handler.
|
||||
|
||||
var hits;
|
||||
var a = new Proxy({}, {
|
||||
set(t, id, value, receiver) {
|
||||
assertEq(id, "prop");
|
||||
assertEq(value, 3);
|
||||
assertEq(receiver, b);
|
||||
hits++;
|
||||
}
|
||||
});
|
||||
var b = new Proxy(a, {});
|
||||
hits = 0;
|
||||
b.prop = 3;
|
||||
assertEq(hits, 1);
|
26
js/src/jit-test/tests/proxy/testIndirectProxySet.js
Normal file
26
js/src/jit-test/tests/proxy/testIndirectProxySet.js
Normal file
@ -0,0 +1,26 @@
|
||||
// BaseProxyHandler::set correctly defines a property on receiver if the
|
||||
// property being assigned doesn't exist anywhere on the proto chain.
|
||||
|
||||
var p = Proxy.create({
|
||||
getOwnPropertyDescriptor() { return undefined; },
|
||||
getPropertyDescriptor() { return undefined; },
|
||||
defineProperty() { throw "FAIL"; }
|
||||
});
|
||||
var q = new Proxy(p, {
|
||||
defineProperty(t, id, desc) {
|
||||
assertEq(t, p);
|
||||
assertEq(id, "x");
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, true);
|
||||
assertEq(desc.writable, true);
|
||||
assertEq(desc.value, 3);
|
||||
hits++;
|
||||
}
|
||||
});
|
||||
var hits = 0;
|
||||
|
||||
// This assignment eventually reaches ScriptedIndirectProxyHandler::set
|
||||
// with arguments (proxy=p, receiver=q). Test that it finishes by defining
|
||||
// a property on receiver, not on proxy.
|
||||
q.x = 3;
|
||||
assertEq(hits, 1);
|
8
js/src/jit-test/tests/proxy/testWrapWithProtoSet.js
Normal file
8
js/src/jit-test/tests/proxy/testWrapWithProtoSet.js
Normal file
@ -0,0 +1,8 @@
|
||||
// A scripted proxy can delegate a [[Set]] along to a target
|
||||
// that's a different kind of proxy.
|
||||
|
||||
var target = {};
|
||||
var wrapper = wrapWithProto(target, null);
|
||||
var p = new Proxy(wrapper, {});
|
||||
p.prop = 3;
|
||||
assertEq(target.prop, 3);
|
@ -6533,12 +6533,12 @@ ClassHasResolveHook(CompileCompartment *comp, const Class *clasp, PropertyName *
|
||||
if (clasp->resolve == JS_ResolveStub)
|
||||
return false;
|
||||
|
||||
if (clasp->resolve == (JSResolveOp)str_resolve) {
|
||||
if (clasp->resolve == str_resolve) {
|
||||
// str_resolve only resolves integers, not names.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clasp->resolve == (JSResolveOp)fun_resolve)
|
||||
if (clasp->resolve == fun_resolve)
|
||||
return FunctionHasResolveHook(comp->runtime()->names(), name);
|
||||
|
||||
return true;
|
||||
|
@ -354,6 +354,7 @@ class MacroAssemblerNone : public Assembler
|
||||
template <typename T> void unboxObject(T, Register) { MOZ_CRASH(); }
|
||||
template <typename T> void unboxDouble(T, FloatRegister) { MOZ_CRASH(); }
|
||||
void unboxValue(const ValueOperand &, AnyRegister) { MOZ_CRASH(); }
|
||||
void unboxNonDouble(const ValueOperand &, Register ) { MOZ_CRASH();}
|
||||
void notBoolean(ValueOperand) { MOZ_CRASH(); }
|
||||
Register extractObject(Address, Register) { MOZ_CRASH(); }
|
||||
Register extractObject(ValueOperand, Register) { MOZ_CRASH(); }
|
||||
|
@ -19,7 +19,6 @@ UNIFIED_SOURCES += [
|
||||
'testClassGetter.cpp',
|
||||
'testCloneScript.cpp',
|
||||
'testContexts.cpp',
|
||||
'testCustomIterator.cpp',
|
||||
'testDebugger.cpp',
|
||||
'testDeepFreeze.cpp',
|
||||
'testDefineGetterSetterNonEnumerable.cpp',
|
||||
@ -38,6 +37,7 @@ UNIFIED_SOURCES += [
|
||||
'testGCExactRooting.cpp',
|
||||
'testGCFinalizeCallback.cpp',
|
||||
'testGCHeapPostBarriers.cpp',
|
||||
'testGCMarking.cpp',
|
||||
'testGCOutOfMemory.cpp',
|
||||
'testGCStoreBufferRemoval.cpp',
|
||||
'testHashTable.cpp',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user