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
ad27337e2a
@ -122,4 +122,10 @@ LoadInfo::GetBaseURI(nsIURI** aBaseURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIURI*
|
||||
LoadInfo::BaseURI()
|
||||
{
|
||||
return mBaseURI;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -17,7 +17,7 @@ typedef unsigned long nsSecurityFlags;
|
||||
/**
|
||||
* An nsILoadOwner represents per-load information about who started the load.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(da363267-236d-49bf-83a2-33da8d892728)]
|
||||
[scriptable, builtinclass, uuid(768a1f20-57d4-462a-812a-41c04e5d1e19)]
|
||||
interface nsILoadInfo : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -156,7 +156,7 @@ interface nsILoadInfo : nsISupports
|
||||
* The contentPolicyType of the channel, used for security checks
|
||||
* like Mixed Content Blocking and Content Security Policy.
|
||||
*/
|
||||
readonly attribute nsContentPolicyType contentPolicyType;
|
||||
readonly attribute nsContentPolicyType contentPolicyType;
|
||||
|
||||
%{ C++
|
||||
inline nsContentPolicyType GetContentPolicyType()
|
||||
@ -173,5 +173,11 @@ interface nsILoadInfo : nsISupports
|
||||
* This attribute may be null. The value of this attribute may be
|
||||
* ignored if the base URI can be inferred by the channel's URI.
|
||||
*/
|
||||
readonly attribute nsIURI baseURI;
|
||||
readonly attribute nsIURI baseURI;
|
||||
|
||||
/**
|
||||
* A C++-friendly version of baseURI.
|
||||
*/
|
||||
[noscript, notxpcom, nostdcall, binaryname(BaseURI)]
|
||||
nsIURI binaryBaseURI();
|
||||
};
|
||||
|
@ -1857,18 +1857,6 @@ public:
|
||||
MOZ_ASSERT_UNREACHABLE("There are no storages");
|
||||
}
|
||||
|
||||
virtual void
|
||||
AbortTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("There are no storages");
|
||||
}
|
||||
|
||||
virtual bool
|
||||
HasTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void
|
||||
ShutdownTransactionService() MOZ_OVERRIDE
|
||||
{ }
|
||||
|
@ -104,11 +104,18 @@ InitScriptSettings()
|
||||
sScriptSettingsTLS.set(nullptr);
|
||||
}
|
||||
|
||||
void DestroyScriptSettings()
|
||||
void
|
||||
DestroyScriptSettings()
|
||||
{
|
||||
MOZ_ASSERT(sScriptSettingsTLS.get() == nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptSettingsInitialized()
|
||||
{
|
||||
return sScriptSettingsTLS.initialized();
|
||||
}
|
||||
|
||||
ScriptSettingsStackEntry::ScriptSettingsStackEntry(nsIGlobalObject *aGlobal,
|
||||
bool aCandidate)
|
||||
: mGlobalObject(aGlobal)
|
||||
|
@ -63,6 +63,7 @@ private:
|
||||
*/
|
||||
void InitScriptSettings();
|
||||
void DestroyScriptSettings();
|
||||
bool ScriptSettingsInitialized();
|
||||
|
||||
/*
|
||||
* Static helpers in ScriptSettings which track the number of listeners
|
||||
|
@ -1211,39 +1211,114 @@ BrowserElementChild.prototype = {
|
||||
} catch (e) {}
|
||||
sendAsyncMsg('loadend', {backgroundColor: bgColor});
|
||||
|
||||
// Ignoring NS_BINDING_ABORTED, which is set when loading page is
|
||||
// stopped.
|
||||
if (status == Cr.NS_OK ||
|
||||
status == Cr.NS_BINDING_ABORTED) {
|
||||
return;
|
||||
}
|
||||
switch (status) {
|
||||
case Cr.NS_OK :
|
||||
case Cr.NS_BINDING_ABORTED :
|
||||
// Ignoring NS_BINDING_ABORTED, which is set when loading page is
|
||||
// stopped.
|
||||
return;
|
||||
|
||||
// getErrorClass() will throw if the error code passed in is not a NSS
|
||||
// error code.
|
||||
try {
|
||||
let nssErrorsService = Cc['@mozilla.org/nss_errors_service;1']
|
||||
.getService(Ci.nsINSSErrorsService);
|
||||
if (nssErrorsService.getErrorClass(status)
|
||||
== Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT) {
|
||||
// XXX Is there a point firing the event if the error page is not
|
||||
// certerror? If yes, maybe we should add a property to the
|
||||
// event to to indicate whether there is a custom page. That would
|
||||
// let the embedder have more control over the desired behavior.
|
||||
let errorPage = null;
|
||||
// TODO See nsDocShell::DisplayLoadError to see what extra
|
||||
// information we should be annotating this first block of errors
|
||||
// with. Bug 1107091.
|
||||
case Cr.NS_ERROR_UNKNOWN_PROTOCOL :
|
||||
sendAsyncMsg('error', { type: 'unknownProtocolFound' });
|
||||
return;
|
||||
case Cr.NS_ERROR_FILE_NOT_FOUND :
|
||||
sendAsyncMsg('error', { type: 'fileNotFound' });
|
||||
return;
|
||||
case Cr.NS_ERROR_UNKNOWN_HOST :
|
||||
sendAsyncMsg('error', { type: 'dnsNotFound' });
|
||||
return;
|
||||
case Cr.NS_ERROR_CONNECTION_REFUSED :
|
||||
sendAsyncMsg('error', { type: 'connectionFailure' });
|
||||
return;
|
||||
case Cr.NS_ERROR_NET_INTERRUPT :
|
||||
sendAsyncMsg('error', { type: 'netInterrupt' });
|
||||
return;
|
||||
case Cr.NS_ERROR_NET_TIMEOUT :
|
||||
sendAsyncMsg('error', { type: 'netTimeout' });
|
||||
return;
|
||||
case Cr.NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION :
|
||||
sendAsyncMsg('error', { type: 'cspBlocked' });
|
||||
return;
|
||||
case Cr.NS_ERROR_PHISHING_URI :
|
||||
sendAsyncMsg('error', { type: 'phishingBlocked' });
|
||||
return;
|
||||
case Cr.NS_ERROR_MALWARE_URI :
|
||||
sendAsyncMsg('error', { type: 'malwareBlocked' });
|
||||
return;
|
||||
|
||||
case Cr.NS_ERROR_OFFLINE :
|
||||
sendAsyncMsg('error', { type: 'offline' });
|
||||
return;
|
||||
case Cr.NS_ERROR_MALFORMED_URI :
|
||||
sendAsyncMsg('error', { type: 'malformedURI' });
|
||||
return;
|
||||
case Cr.NS_ERROR_REDIRECT_LOOP :
|
||||
sendAsyncMsg('error', { type: 'redirectLoop' });
|
||||
return;
|
||||
case Cr.NS_ERROR_UNKNOWN_SOCKET_TYPE :
|
||||
sendAsyncMsg('error', { type: 'unknownSocketType' });
|
||||
return;
|
||||
case Cr.NS_ERROR_NET_RESET :
|
||||
sendAsyncMsg('error', { type: 'netReset' });
|
||||
return;
|
||||
case Cr.NS_ERROR_DOCUMENT_NOT_CACHED :
|
||||
sendAsyncMsg('error', { type: 'notCached' });
|
||||
return;
|
||||
case Cr.NS_ERROR_DOCUMENT_IS_PRINTMODE :
|
||||
sendAsyncMsg('error', { type: 'isprinting' });
|
||||
return;
|
||||
case Cr.NS_ERROR_PORT_ACCESS_NOT_ALLOWED :
|
||||
sendAsyncMsg('error', { type: 'deniedPortAccess' });
|
||||
return;
|
||||
case Cr.NS_ERROR_UNKNOWN_PROXY_HOST :
|
||||
sendAsyncMsg('error', { type: 'proxyResolveFailure' });
|
||||
return;
|
||||
case Cr.NS_ERROR_PROXY_CONNECTION_REFUSED :
|
||||
sendAsyncMsg('error', { type: 'proxyConnectFailure' });
|
||||
return;
|
||||
case Cr.NS_ERROR_INVALID_CONTENT_ENCODING :
|
||||
sendAsyncMsg('error', { type: 'contentEncodingFailure' });
|
||||
return;
|
||||
case Cr.NS_ERROR_REMOTE_XUL :
|
||||
sendAsyncMsg('error', { type: 'remoteXUL' });
|
||||
return;
|
||||
case Cr.NS_ERROR_UNSAFE_CONTENT_TYPE :
|
||||
sendAsyncMsg('error', { type: 'unsafeContentType' });
|
||||
return;
|
||||
case Cr.NS_ERROR_CORRUPTED_CONTENT :
|
||||
sendAsyncMsg('error', { type: 'corruptedContentError' });
|
||||
return;
|
||||
|
||||
default:
|
||||
// getErrorClass() will throw if the error code passed in is not a NSS
|
||||
// error code.
|
||||
try {
|
||||
errorPage = Services.prefs.getCharPref(CERTIFICATE_ERROR_PAGE_PREF);
|
||||
let nssErrorsService = Cc['@mozilla.org/nss_errors_service;1']
|
||||
.getService(Ci.nsINSSErrorsService);
|
||||
if (nssErrorsService.getErrorClass(status)
|
||||
== Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT) {
|
||||
// XXX Is there a point firing the event if the error page is not
|
||||
// certerror? If yes, maybe we should add a property to the
|
||||
// event to to indicate whether there is a custom page. That would
|
||||
// let the embedder have more control over the desired behavior.
|
||||
let errorPage = null;
|
||||
try {
|
||||
errorPage = Services.prefs.getCharPref(CERTIFICATE_ERROR_PAGE_PREF);
|
||||
} catch (e) {}
|
||||
|
||||
if (errorPage == 'certerror') {
|
||||
sendAsyncMsg('error', { type: 'certerror' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (errorPage == 'certerror') {
|
||||
sendAsyncMsg('error', { type: 'certerror' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
// TODO See nsDocShell::DisplayLoadError for a list of all the error
|
||||
// codes (the status param) we should eventually handle here.
|
||||
sendAsyncMsg('error', { type: 'other' });
|
||||
sendAsyncMsg('error', { type: 'other' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -15,14 +15,14 @@ function runTest() {
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
checkForGenericError();
|
||||
checkForDnsError();
|
||||
}
|
||||
|
||||
function checkForGenericError() {
|
||||
iframe.addEventListener("mozbrowsererror", function onGenericError(e) {
|
||||
iframe.removeEventListener(e.type, onGenericError);
|
||||
function checkForDnsError() {
|
||||
iframe.addEventListener("mozbrowsererror", function onDnsError(e) {
|
||||
iframe.removeEventListener(e.type, onDnsError);
|
||||
ok(true, "Got mozbrowsererror event.");
|
||||
ok(e.detail.type == "other", "Event's detail has a |type| param with the value '" + e.detail.type + "'.");
|
||||
ok(e.detail.type == "dnsNotFound", "Event's detail has a |type| param with the value '" + e.detail.type + "'.");
|
||||
|
||||
checkForExpiredCertificateError();
|
||||
});
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
@ -47,72 +48,92 @@ WebGL2Context::WrapObject(JSContext* cx)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// WebGL 2 initialisation
|
||||
|
||||
// These WebGL 1 extensions are natively supported by WebGL 2.
|
||||
static const WebGLExtensionID kNativelySupportedExtensions[] = {
|
||||
WebGLExtensionID::ANGLE_instanced_arrays,
|
||||
WebGLExtensionID::EXT_blend_minmax,
|
||||
WebGLExtensionID::EXT_sRGB,
|
||||
WebGLExtensionID::OES_element_index_uint,
|
||||
WebGLExtensionID::OES_standard_derivatives,
|
||||
WebGLExtensionID::OES_texture_float,
|
||||
WebGLExtensionID::OES_texture_float_linear,
|
||||
WebGLExtensionID::OES_texture_half_float,
|
||||
WebGLExtensionID::OES_texture_half_float_linear,
|
||||
WebGLExtensionID::OES_vertex_array_object,
|
||||
WebGLExtensionID::WEBGL_depth_texture,
|
||||
WebGLExtensionID::WEBGL_draw_buffers
|
||||
};
|
||||
|
||||
static const gl::GLFeature kRequiredFeatures[] = {
|
||||
gl::GLFeature::blend_minmax,
|
||||
gl::GLFeature::clear_buffers,
|
||||
gl::GLFeature::copy_buffer,
|
||||
gl::GLFeature::depth_texture,
|
||||
gl::GLFeature::draw_instanced,
|
||||
gl::GLFeature::draw_range_elements,
|
||||
gl::GLFeature::element_index_uint,
|
||||
gl::GLFeature::frag_color_float,
|
||||
gl::GLFeature::frag_depth,
|
||||
gl::GLFeature::framebuffer_blit,
|
||||
gl::GLFeature::framebuffer_multisample,
|
||||
gl::GLFeature::get_integer_indexed,
|
||||
gl::GLFeature::get_integer64_indexed,
|
||||
gl::GLFeature::gpu_shader4,
|
||||
gl::GLFeature::instanced_arrays,
|
||||
gl::GLFeature::instanced_non_arrays,
|
||||
gl::GLFeature::invalidate_framebuffer,
|
||||
gl::GLFeature::map_buffer_range,
|
||||
gl::GLFeature::occlusion_query2,
|
||||
gl::GLFeature::packed_depth_stencil,
|
||||
gl::GLFeature::query_objects,
|
||||
gl::GLFeature::renderbuffer_color_float,
|
||||
gl::GLFeature::renderbuffer_color_half_float,
|
||||
gl::GLFeature::sRGB,
|
||||
gl::GLFeature::sampler_objects,
|
||||
gl::GLFeature::standard_derivatives,
|
||||
gl::GLFeature::texture_3D,
|
||||
gl::GLFeature::texture_3D_compressed,
|
||||
gl::GLFeature::texture_3D_copy,
|
||||
gl::GLFeature::texture_float,
|
||||
gl::GLFeature::texture_float_linear,
|
||||
gl::GLFeature::texture_half_float,
|
||||
gl::GLFeature::texture_half_float_linear,
|
||||
gl::GLFeature::texture_non_power_of_two,
|
||||
gl::GLFeature::texture_storage,
|
||||
gl::GLFeature::transform_feedback2,
|
||||
gl::GLFeature::uniform_buffer_object,
|
||||
gl::GLFeature::uniform_matrix_nonsquare,
|
||||
gl::GLFeature::vertex_array_object
|
||||
};
|
||||
|
||||
bool
|
||||
WebGLContext::InitWebGL2()
|
||||
{
|
||||
MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!");
|
||||
|
||||
const WebGLExtensionID sExtensionNativelySupportedArr[] = {
|
||||
WebGLExtensionID::ANGLE_instanced_arrays,
|
||||
WebGLExtensionID::EXT_blend_minmax,
|
||||
WebGLExtensionID::EXT_sRGB,
|
||||
WebGLExtensionID::OES_element_index_uint,
|
||||
WebGLExtensionID::OES_standard_derivatives,
|
||||
WebGLExtensionID::OES_texture_float,
|
||||
WebGLExtensionID::OES_texture_float_linear,
|
||||
WebGLExtensionID::OES_texture_half_float,
|
||||
WebGLExtensionID::OES_texture_half_float_linear,
|
||||
WebGLExtensionID::OES_vertex_array_object,
|
||||
WebGLExtensionID::WEBGL_depth_texture,
|
||||
WebGLExtensionID::WEBGL_draw_buffers
|
||||
};
|
||||
const gl::GLFeature sFeatureRequiredArr[] = {
|
||||
gl::GLFeature::instanced_non_arrays,
|
||||
gl::GLFeature::transform_feedback2,
|
||||
gl::GLFeature::invalidate_framebuffer
|
||||
};
|
||||
|
||||
// check WebGL extensions that are supposed to be natively supported
|
||||
size_t len = MOZ_ARRAY_LENGTH(sExtensionNativelySupportedArr);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
WebGLExtensionID extension = sExtensionNativelySupportedArr[i];
|
||||
|
||||
if (!IsExtensionSupported(extension)) {
|
||||
GenerateWarning("WebGL 2 requires %s!", GetExtensionString(extension));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check required OpenGL extensions
|
||||
if (!gl->IsExtensionSupported(gl::GLContext::EXT_gpu_shader4)) {
|
||||
GenerateWarning("WebGL 2 requires GL_EXT_gpu_shader4!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check OpenGL features
|
||||
if (!gl->IsSupported(gl::GLFeature::occlusion_query) &&
|
||||
!gl->IsSupported(gl::GLFeature::occlusion_query_boolean))
|
||||
{
|
||||
// On desktop, we fake occlusion_query_boolean with occlusion_query if
|
||||
//necessary. (See WebGLContextAsyncQueries.cpp)
|
||||
GenerateWarning("WebGL 2 requires occlusion queries!");
|
||||
// necessary. (See WebGL2ContextQueries.cpp)
|
||||
GenerateWarning("WebGL 2 unavailable. Requires occlusion queries.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size_t(MOZ_ARRAY_LENGTH(sFeatureRequiredArr)); i++) {
|
||||
if (!gl->IsSupported(sFeatureRequiredArr[i])) {
|
||||
GenerateWarning("WebGL 2 requires GLFeature::%s!",
|
||||
gl::GLContext::GetFeatureName(sFeatureRequiredArr[i]));
|
||||
for (size_t i = 0; i < ArrayLength(kRequiredFeatures); i++) {
|
||||
if (!gl->IsSupported(kRequiredFeatures[i])) {
|
||||
GenerateWarning("WebGL 2 unavailable. Requires feature %s.",
|
||||
gl::GLContext::GetFeatureName(kRequiredFeatures[i]));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ok WebGL 2 is compatible, we can enable natively supported extensions.
|
||||
len = MOZ_ARRAY_LENGTH(sExtensionNativelySupportedArr);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
EnableExtension(sExtensionNativelySupportedArr[i]);
|
||||
for (size_t i = 0; i < ArrayLength(kNativelySupportedExtensions); i++) {
|
||||
EnableExtension(kNativelySupportedExtensions[i]);
|
||||
|
||||
MOZ_ASSERT(IsExtensionEnabled(sExtensionNativelySupportedArr[i]));
|
||||
MOZ_ASSERT(IsExtensionEnabled(kNativelySupportedExtensions[i]));
|
||||
}
|
||||
|
||||
// we initialise WebGL 2 related stuff.
|
||||
|
@ -291,20 +291,6 @@ FileService::AbortFileHandlesForStorage(nsIOfflineStorage* aStorage)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FileService::HasFileHandlesForStorage(nsIOfflineStorage* aStorage)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
|
||||
MOZ_ASSERT(aStorage, "Null pointer!");
|
||||
|
||||
StorageInfo* storageInfo;
|
||||
if (!mStorageInfos.Get(aStorage->Id(), &storageInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return storageInfo->HasRunningFileHandles(aStorage);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(FileService, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -493,18 +479,6 @@ FileService::StorageInfo::RemoveFileHandleQueue(FileHandleBase* aFileHandle)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
FileService::StorageInfo::HasRunningFileHandles(nsIOfflineStorage* aStorage)
|
||||
{
|
||||
for (uint32_t index = 0; index < mFileHandleQueues.Length(); index++) {
|
||||
FileHandleBase* fileHandle = mFileHandleQueues[index]->mFileHandle;
|
||||
if (fileHandle->MutableFile()->Storage() == aStorage) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FileService::DelayedEnqueueInfo*
|
||||
FileService::StorageInfo::CreateDelayedEnqueueInfo(FileHandleBase* aFileHandle,
|
||||
FileHelper* aFileHelper)
|
||||
|
@ -62,9 +62,6 @@ public:
|
||||
void
|
||||
AbortFileHandlesForStorage(nsIOfflineStorage* aStorage);
|
||||
|
||||
bool
|
||||
HasFileHandlesForStorage(nsIOfflineStorage* aStorage);
|
||||
|
||||
nsIEventTarget*
|
||||
StreamTransportTarget()
|
||||
{
|
||||
@ -135,9 +132,6 @@ private:
|
||||
return !mFileHandleQueues.IsEmpty();
|
||||
}
|
||||
|
||||
inline bool
|
||||
HasRunningFileHandles(nsIOfflineStorage* aStorage);
|
||||
|
||||
inline DelayedEnqueueInfo*
|
||||
CreateDelayedEnqueueInfo(FileHandleBase* aFileHandle,
|
||||
FileHelper* aFileHelper);
|
||||
|
@ -2779,19 +2779,17 @@ class Factory MOZ_FINAL
|
||||
// ActorDestroy called.
|
||||
static uint64_t sFactoryInstanceCount;
|
||||
|
||||
const OptionalWindowId mOptionalWindowId;
|
||||
|
||||
DebugOnly<bool> mActorDestroyed;
|
||||
|
||||
public:
|
||||
static already_AddRefed<Factory>
|
||||
Create(const OptionalWindowId& aOptionalWindowId);
|
||||
Create();
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::dom::indexedDB::Factory)
|
||||
|
||||
private:
|
||||
// Only constructed in Create().
|
||||
explicit Factory(const OptionalWindowId& aOptionalWindowId);
|
||||
explicit Factory();
|
||||
|
||||
// Reference counted.
|
||||
~Factory();
|
||||
@ -2844,7 +2842,6 @@ class Database MOZ_FINAL
|
||||
const nsCString mOrigin;
|
||||
const nsCString mId;
|
||||
const nsString mFilePath;
|
||||
Atomic<bool> mInvalidatedOnAnyThread;
|
||||
const PersistenceType mPersistenceType;
|
||||
const bool mChromeWriteAccessAllowed;
|
||||
bool mClosed;
|
||||
@ -4050,8 +4047,7 @@ class OpenDatabaseOp MOZ_FINAL
|
||||
|
||||
class VersionChangeOp;
|
||||
|
||||
const OptionalWindowId mOptionalWindowId;
|
||||
const OptionalWindowId mOptionalContentParentId;
|
||||
const OptionalContentId mOptionalContentParentId;
|
||||
|
||||
nsRefPtr<FullDatabaseMetadata> mMetadata;
|
||||
|
||||
@ -4067,15 +4063,15 @@ class OpenDatabaseOp MOZ_FINAL
|
||||
public:
|
||||
OpenDatabaseOp(Factory* aFactory,
|
||||
already_AddRefed<ContentParent> aContentParent,
|
||||
const OptionalWindowId& aOptionalWindowId,
|
||||
const CommonFactoryRequestParams& aParams);
|
||||
|
||||
bool
|
||||
IsOtherProcessActor() const
|
||||
{
|
||||
MOZ_ASSERT(mOptionalContentParentId.type() != OptionalWindowId::T__None);
|
||||
MOZ_ASSERT(mOptionalContentParentId.type() != OptionalContentId::T__None);
|
||||
|
||||
return mOptionalContentParentId.type() == OptionalWindowId::Tuint64_t;
|
||||
return mOptionalContentParentId.type() ==
|
||||
OptionalContentId::TContentParentId;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -5146,12 +5142,6 @@ public:
|
||||
WaitForStoragesToComplete(nsTArray<nsIOfflineStorage*>& aStorages,
|
||||
nsIRunnable* aCallback) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
AbortTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
HasTransactionsForStorage(nsIOfflineStorage* aStorage) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
ShutdownTransactionService() MOZ_OVERRIDE;
|
||||
|
||||
@ -5264,12 +5254,10 @@ class DatabaseOfflineStorage MOZ_FINAL
|
||||
// Only used on the background thread.
|
||||
Database* mDatabase;
|
||||
|
||||
const OptionalWindowId mOptionalWindowId;
|
||||
const OptionalWindowId mOptionalContentParentId;
|
||||
const OptionalContentId mOptionalContentParentId;
|
||||
const nsCString mOrigin;
|
||||
const nsCString mId;
|
||||
nsCOMPtr<nsIEventTarget> mOwningThread;
|
||||
Atomic<uint32_t> mTransactionCount;
|
||||
|
||||
bool mClosedOnMainThread;
|
||||
bool mClosedOnOwningThread;
|
||||
@ -5280,8 +5268,7 @@ class DatabaseOfflineStorage MOZ_FINAL
|
||||
|
||||
public:
|
||||
DatabaseOfflineStorage(QuotaClient* aQuotaClient,
|
||||
const OptionalWindowId& aOptionalWindowId,
|
||||
const OptionalWindowId& aOptionalContentParentId,
|
||||
const OptionalContentId& aOptionalContentParentId,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const nsACString& aId,
|
||||
@ -5302,33 +5289,6 @@ public:
|
||||
mDatabase = aDatabase;
|
||||
}
|
||||
|
||||
void
|
||||
NoteNewTransaction()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mTransactionCount < UINT32_MAX);
|
||||
|
||||
mTransactionCount++;
|
||||
}
|
||||
|
||||
void
|
||||
NoteFinishedTransaction()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mTransactionCount);
|
||||
|
||||
mTransactionCount--;
|
||||
}
|
||||
|
||||
bool
|
||||
HasOpenTransactions() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// XXX This is racy, is this correct?
|
||||
return !!mTransactionCount;
|
||||
}
|
||||
|
||||
nsIEventTarget*
|
||||
OwningThread() const
|
||||
{
|
||||
@ -5577,31 +5537,20 @@ StaticRefPtr<DEBUGThreadSlower> gDEBUGThreadSlower;
|
||||
******************************************************************************/
|
||||
|
||||
PBackgroundIDBFactoryParent*
|
||||
AllocPBackgroundIDBFactoryParent(PBackgroundParent* aManager,
|
||||
const OptionalWindowId& aOptionalWindowId)
|
||||
AllocPBackgroundIDBFactoryParent()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aOptionalWindowId.type() != OptionalWindowId::T__None);
|
||||
|
||||
if (BackgroundParent::IsOtherProcessActor(aManager)) {
|
||||
if (NS_WARN_IF(aOptionalWindowId.type() != OptionalWindowId::Tvoid_t)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Factory> actor = Factory::Create(aOptionalWindowId);
|
||||
nsRefPtr<Factory> actor = Factory::Create();
|
||||
return actor.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
RecvPBackgroundIDBFactoryConstructor(PBackgroundParent* /* aManager */,
|
||||
PBackgroundIDBFactoryParent* aActor,
|
||||
const OptionalWindowId& aOptionalWindowId)
|
||||
RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
@ -5784,9 +5733,8 @@ FullDatabaseMetadata::Duplicate() const
|
||||
|
||||
uint64_t Factory::sFactoryInstanceCount = 0;
|
||||
|
||||
Factory::Factory(const OptionalWindowId& aOptionalWindowId)
|
||||
: mOptionalWindowId(aOptionalWindowId)
|
||||
, mActorDestroyed(false)
|
||||
Factory::Factory()
|
||||
: mActorDestroyed(false)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||
@ -5799,7 +5747,7 @@ Factory::~Factory()
|
||||
|
||||
// static
|
||||
already_AddRefed<Factory>
|
||||
Factory::Create(const OptionalWindowId& aOptionalWindowId)
|
||||
Factory::Create()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread());
|
||||
@ -5847,7 +5795,7 @@ Factory::Create(const OptionalWindowId& aOptionalWindowId)
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
nsRefPtr<Factory> actor = new Factory(aOptionalWindowId);
|
||||
nsRefPtr<Factory> actor = new Factory();
|
||||
|
||||
sFactoryInstanceCount++;
|
||||
|
||||
@ -5966,7 +5914,6 @@ Factory::AllocPBackgroundIDBFactoryRequestParent(
|
||||
if (aParams.type() == FactoryRequestParams::TOpenDatabaseRequestParams) {
|
||||
actor = new OpenDatabaseOp(this,
|
||||
contentParent.forget(),
|
||||
mOptionalWindowId,
|
||||
*commonParams);
|
||||
} else {
|
||||
actor = new DeleteDatabaseOp(this, contentParent.forget(), *commonParams);
|
||||
@ -6155,7 +6102,6 @@ Database::RegisterTransaction(TransactionBase* aTransaction)
|
||||
return false;
|
||||
}
|
||||
|
||||
mOfflineStorage->NoteNewTransaction();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -6168,14 +6114,10 @@ Database::UnregisterTransaction(TransactionBase* aTransaction)
|
||||
|
||||
mTransactions.RemoveEntry(aTransaction);
|
||||
|
||||
if (mOfflineStorage) {
|
||||
mOfflineStorage->NoteFinishedTransaction();
|
||||
|
||||
if (!mTransactions.Count() && IsClosed()) {
|
||||
DatabaseOfflineStorage::UnregisterOnOwningThread(
|
||||
mOfflineStorage.forget());
|
||||
CleanupMetadata();
|
||||
}
|
||||
if (mOfflineStorage && !mTransactions.Count() && IsClosed()) {
|
||||
DatabaseOfflineStorage::UnregisterOnOwningThread(
|
||||
mOfflineStorage.forget());
|
||||
CleanupMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
@ -9515,30 +9457,6 @@ QuotaClient::WaitForStoragesToComplete(nsTArray<nsIOfflineStorage*>& aStorages,
|
||||
backgroundThread->Dispatch(runnable, NS_DISPATCH_NORMAL)));
|
||||
}
|
||||
|
||||
void
|
||||
QuotaClient::AbortTransactionsForStorage(nsIOfflineStorage* aStorage)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aStorage);
|
||||
MOZ_ASSERT(aStorage->GetClient() == this);
|
||||
|
||||
static_cast<DatabaseOfflineStorage*>(aStorage)->
|
||||
AssertInvalidatedOnMainThread();
|
||||
|
||||
// Nothing to do here, calling DatabaseOfflineStorage::Close() should have
|
||||
// aborted any transactions already.
|
||||
}
|
||||
|
||||
bool
|
||||
QuotaClient::HasTransactionsForStorage(nsIOfflineStorage* aStorage)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aStorage);
|
||||
MOZ_ASSERT(aStorage->GetClient() == this);
|
||||
|
||||
return static_cast<DatabaseOfflineStorage*>(aStorage)->HasOpenTransactions();
|
||||
}
|
||||
|
||||
void
|
||||
QuotaClient::ShutdownTransactionService()
|
||||
{
|
||||
@ -9802,23 +9720,20 @@ ShutdownTransactionThreadPoolRunnable::Run()
|
||||
******************************************************************************/
|
||||
|
||||
DatabaseOfflineStorage::DatabaseOfflineStorage(
|
||||
QuotaClient* aQuotaClient,
|
||||
const OptionalWindowId& aOptionalWindowId,
|
||||
const OptionalWindowId& aOptionalContentParentId,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const nsACString& aId,
|
||||
PersistenceType aPersistenceType,
|
||||
nsIEventTarget* aOwningThread)
|
||||
QuotaClient* aQuotaClient,
|
||||
const OptionalContentId& aOptionalContentParentId,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const nsACString& aId,
|
||||
PersistenceType aPersistenceType,
|
||||
nsIEventTarget* aOwningThread)
|
||||
: mStrongQuotaClient(aQuotaClient)
|
||||
, mWeakQuotaClient(aQuotaClient)
|
||||
, mDatabase(nullptr)
|
||||
, mOptionalWindowId(aOptionalWindowId)
|
||||
, mOptionalContentParentId(aOptionalContentParentId)
|
||||
, mOrigin(aOrigin)
|
||||
, mId(aId)
|
||||
, mOwningThread(aOwningThread)
|
||||
, mTransactionCount(0)
|
||||
, mClosedOnMainThread(false)
|
||||
, mClosedOnOwningThread(false)
|
||||
, mInvalidatedOnMainThread(false)
|
||||
@ -9827,12 +9742,6 @@ DatabaseOfflineStorage::DatabaseOfflineStorage(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aQuotaClient);
|
||||
MOZ_ASSERT(aOptionalWindowId.type() != OptionalWindowId::T__None);
|
||||
MOZ_ASSERT_IF(aOptionalWindowId.type() == OptionalWindowId::Tuint64_t,
|
||||
aOptionalContentParentId.type() == OptionalWindowId::Tvoid_t);
|
||||
MOZ_ASSERT(aOptionalContentParentId.type() != OptionalWindowId::T__None);
|
||||
MOZ_ASSERT_IF(aOptionalContentParentId.type() == OptionalWindowId::Tuint64_t,
|
||||
aOptionalWindowId.type() == OptionalWindowId::Tvoid_t);
|
||||
MOZ_ASSERT(aOwningThread);
|
||||
|
||||
DebugOnly<bool> current;
|
||||
@ -9892,11 +9801,6 @@ DatabaseOfflineStorage::CloseOnMainThread()
|
||||
}
|
||||
|
||||
mClosedOnMainThread = true;
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
quotaManager->OnStorageClosed(this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -9974,25 +9878,15 @@ DatabaseOfflineStorage::GetClient()
|
||||
return mWeakQuotaClient;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
DatabaseOfflineStorage::IsOwnedByWindow(nsPIDOMWindow* aOwner)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(aOwner->IsInnerWindow());
|
||||
|
||||
return mOptionalWindowId.type() == OptionalWindowId::Tuint64_t &&
|
||||
mOptionalWindowId.get_uint64_t() == aOwner->WindowID();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
DatabaseOfflineStorage::IsOwnedByProcess(ContentParent* aOwner)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aOwner);
|
||||
|
||||
return mOptionalContentParentId.type() == OptionalWindowId::Tuint64_t &&
|
||||
mOptionalContentParentId.get_uint64_t() == aOwner->ChildID();
|
||||
return mOptionalContentParentId.type() ==
|
||||
OptionalContentId::TContentParentId &&
|
||||
mOptionalContentParentId.get_ContentParentId() == aOwner->ChildID();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(const nsACString&)
|
||||
@ -10010,14 +9904,6 @@ DatabaseOfflineStorage::Close()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
DatabaseOfflineStorage::IsClosed()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
return mClosedOnMainThread;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
DatabaseOfflineStorage::Invalidate()
|
||||
{
|
||||
@ -11121,18 +11007,13 @@ FactoryOp::RecvPermissionRetry()
|
||||
|
||||
OpenDatabaseOp::OpenDatabaseOp(Factory* aFactory,
|
||||
already_AddRefed<ContentParent> aContentParent,
|
||||
const OptionalWindowId& aOptionalWindowId,
|
||||
const CommonFactoryRequestParams& aParams)
|
||||
: FactoryOp(aFactory, Move(aContentParent), aParams, /* aDeleting */ false)
|
||||
, mOptionalWindowId(aOptionalWindowId)
|
||||
, mMetadata(new FullDatabaseMetadata(aParams.metadata()))
|
||||
, mRequestedVersion(aParams.metadata().version())
|
||||
{
|
||||
MOZ_ASSERT_IF(mContentParent,
|
||||
mOptionalWindowId.type() == OptionalWindowId::Tvoid_t);
|
||||
|
||||
auto& optionalContentParentId =
|
||||
const_cast<OptionalWindowId&>(mOptionalContentParentId);
|
||||
const_cast<OptionalContentId&>(mOptionalContentParentId);
|
||||
|
||||
if (mContentParent) {
|
||||
// This is a little scary but it looks safe to call this off the main thread
|
||||
@ -11162,7 +11043,6 @@ OpenDatabaseOp::QuotaManagerOpen()
|
||||
|
||||
nsRefPtr<DatabaseOfflineStorage> offlineStorage =
|
||||
new DatabaseOfflineStorage(quotaClient,
|
||||
mOptionalWindowId,
|
||||
mOptionalContentParentId,
|
||||
mGroup,
|
||||
mOrigin,
|
||||
|
@ -11,12 +11,6 @@ class nsIPrincipal;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class PBackgroundParent;
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
class TabParent;
|
||||
@ -29,18 +23,14 @@ class Client;
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class OptionalWindowId;
|
||||
class PBackgroundIDBFactoryParent;
|
||||
class PIndexedDBPermissionRequestParent;
|
||||
|
||||
PBackgroundIDBFactoryParent*
|
||||
AllocPBackgroundIDBFactoryParent(mozilla::ipc::PBackgroundParent* aManager,
|
||||
const OptionalWindowId& aOptionalWindowId);
|
||||
AllocPBackgroundIDBFactoryParent();
|
||||
|
||||
bool
|
||||
RecvPBackgroundIDBFactoryConstructor(mozilla::ipc::PBackgroundParent* aManager,
|
||||
PBackgroundIDBFactoryParent* aActor,
|
||||
const OptionalWindowId& aOptionalWindowId);
|
||||
RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor);
|
||||
|
||||
bool
|
||||
DeallocPBackgroundIDBFactoryParent(PBackgroundIDBFactoryParent* aActor);
|
||||
|
@ -593,18 +593,9 @@ IDBFactory::BackgroundActorCreated(PBackgroundChild* aBackgroundActor)
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Fix this windowId stuff for workers!");
|
||||
|
||||
OptionalWindowId windowId;
|
||||
if (mWindow && IndexedDatabaseManager::IsMainProcess()) {
|
||||
MOZ_ASSERT(mWindow->IsInnerWindow());
|
||||
windowId = mWindow->WindowID();
|
||||
} else {
|
||||
windowId = void_t();
|
||||
}
|
||||
|
||||
mBackgroundActor =
|
||||
static_cast<BackgroundFactoryChild*>(
|
||||
aBackgroundActor->SendPBackgroundIDBFactoryConstructor(actor,
|
||||
windowId));
|
||||
aBackgroundActor->SendPBackgroundIDBFactoryConstructor(actor));
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mBackgroundActor)) {
|
||||
|
@ -733,24 +733,6 @@ TransactionThreadPool::FindTransaction(const uint64_t& aTransactionId,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
bool
|
||||
TransactionThreadPool::HasTransactionsForDatabase(const nsACString& aDatabaseId)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(!aDatabaseId.IsEmpty(), "An empty DatabaseId!");
|
||||
|
||||
DatabaseTransactionInfo* dbTransactionInfo = nullptr;
|
||||
dbTransactionInfo = mTransactionsInProgress.Get(aDatabaseId);
|
||||
if (!dbTransactionInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TransactionSearchInfo info(aDatabaseId);
|
||||
dbTransactionInfo->transactions.EnumerateRead(FindTransaction, &info);
|
||||
|
||||
return info.found;
|
||||
}
|
||||
|
||||
bool
|
||||
TransactionThreadPool::MaybeFireCallback(DatabasesCompleteCallback* aCallback)
|
||||
{
|
||||
|
@ -72,9 +72,6 @@ public:
|
||||
void WaitForDatabasesToComplete(nsTArray<nsCString>& aDatabaseIds,
|
||||
nsIRunnable* aCallback);
|
||||
|
||||
// Returns true if there are running or pending transactions for aDatabase.
|
||||
bool HasTransactionsForDatabase(const nsACString& aDatabaseId);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(TransactionThreadPool)
|
||||
|
||||
void Shutdown();
|
||||
|
@ -331,6 +331,12 @@ union MaybeFileDesc {
|
||||
void_t;
|
||||
};
|
||||
|
||||
union OptionalContentId
|
||||
{
|
||||
ContentParentId;
|
||||
void_t;
|
||||
};
|
||||
|
||||
prio(normal upto urgent) intr protocol PContent
|
||||
{
|
||||
parent spawns PPluginModule;
|
||||
|
@ -282,6 +282,10 @@ void MediaDecoder::DestroyDecodedStream()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
if (GetDecodedStream()) {
|
||||
GetStateMachine()->ResyncMediaStreamClock();
|
||||
}
|
||||
|
||||
// All streams are having their SourceMediaStream disconnected, so they
|
||||
// need to be explicitly blocked again.
|
||||
for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
|
||||
|
@ -1138,6 +1138,17 @@ void MediaDecoderStateMachine::SetSyncPointForMediaStream()
|
||||
mSyncPointInDecodedStream = mStartTime + mPlayDuration;
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::ResyncMediaStreamClock()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
MOZ_ASSERT(mDecoder->GetDecodedStream());
|
||||
|
||||
if (IsPlaying()) {
|
||||
SetPlayStartTime(TimeStamp::Now());
|
||||
mPlayDuration = GetCurrentTimeViaMediaStreamSync() - mStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t MediaDecoderStateMachine::GetCurrentTimeViaMediaStreamSync() const
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
@ -333,6 +333,11 @@ public:
|
||||
// call this while we're not playing (while the MediaStream is blocked). Can
|
||||
// be called on any thread with the decoder monitor held.
|
||||
void SetSyncPointForMediaStream();
|
||||
|
||||
// Called when the decoded stream is destroyed. |mPlayStartTime| and
|
||||
// |mPlayDuration| are updated to provide a good base for calculating video
|
||||
// stream time using the system clock.
|
||||
void ResyncMediaStreamClock();
|
||||
int64_t GetCurrentTimeViaMediaStreamSync() const;
|
||||
|
||||
// Copy queued audio/video data in the reader to any output MediaStreams that
|
||||
@ -747,7 +752,8 @@ protected:
|
||||
// The amount of time we've spent playing already the media. The current
|
||||
// playback position is therefore |Now() - mPlayStartTime +
|
||||
// mPlayDuration|, which must be adjusted by mStartTime if used with media
|
||||
// timestamps. Accessed only via the state machine thread.
|
||||
// timestamps. Accessed on state machine and main threads. Access controlled
|
||||
// by decoder monitor.
|
||||
int64_t mPlayDuration;
|
||||
|
||||
// Time that buffering started. Used for buffering timeout and only
|
||||
|
@ -1101,27 +1101,6 @@ RTCPeerConnection.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function RTCError(code, message) {
|
||||
this.name = this.reasonName[Math.min(code, this.reasonName.length - 1)];
|
||||
this.message = (typeof message === "string")? message : this.name;
|
||||
this.__exposedProps__ = { name: "rw", message: "rw" };
|
||||
}
|
||||
RTCError.prototype = {
|
||||
// These strings must match those defined in the WebRTC spec.
|
||||
reasonName: [
|
||||
"NO_ERROR", // Should never happen -- only used for testing
|
||||
"INVALID_CONSTRAINTS_TYPE",
|
||||
"INVALID_CANDIDATE_TYPE",
|
||||
"INVALID_MEDIASTREAM_TRACK",
|
||||
"INVALID_STATE",
|
||||
"INVALID_SESSION_DESCRIPTION",
|
||||
"INCOMPATIBLE_SESSION_DESCRIPTION",
|
||||
"INCOMPATIBLE_CONSTRAINTS",
|
||||
"INCOMPATIBLE_MEDIASTREAMTRACK",
|
||||
"INTERNAL_ERROR"
|
||||
]
|
||||
};
|
||||
|
||||
// This is a separate object because we don't want to expose it to DOM.
|
||||
function PeerConnectionObserver() {
|
||||
this._dompc = null;
|
||||
@ -1138,6 +1117,24 @@ PeerConnectionObserver.prototype = {
|
||||
this._dompc = dompc._innerObject;
|
||||
},
|
||||
|
||||
newError: function(code, message) {
|
||||
// These strings must match those defined in the WebRTC spec.
|
||||
const reasonName = [
|
||||
"",
|
||||
"InternalError",
|
||||
"InternalError",
|
||||
"InvalidParameter",
|
||||
"InvalidStateError",
|
||||
"InvalidSessionDescriptionError",
|
||||
"IncompatibleSessionDescriptionError",
|
||||
"InternalError",
|
||||
"IncompatibleMediaStreamTrackError",
|
||||
"InternalError"
|
||||
];
|
||||
let name = reasonName[Math.min(code, reasonName.length - 1)];
|
||||
return new this._dompc._win.DOMError(name, message);
|
||||
},
|
||||
|
||||
dispatchEvent: function(event) {
|
||||
this._dompc.dispatchEvent(event);
|
||||
},
|
||||
@ -1157,7 +1154,7 @@ PeerConnectionObserver.prototype = {
|
||||
},
|
||||
|
||||
onCreateOfferError: function(code, message) {
|
||||
this._dompc.callCB(this._dompc._onCreateOfferFailure, new RTCError(code, message));
|
||||
this._dompc.callCB(this._dompc._onCreateOfferFailure, this.newError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
@ -1177,7 +1174,7 @@ PeerConnectionObserver.prototype = {
|
||||
|
||||
onCreateAnswerError: function(code, message) {
|
||||
this._dompc.callCB(this._dompc._onCreateAnswerFailure,
|
||||
new RTCError(code, message));
|
||||
this.newError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
@ -1194,14 +1191,14 @@ PeerConnectionObserver.prototype = {
|
||||
onSetLocalDescriptionError: function(code, message) {
|
||||
this._localType = null;
|
||||
this._dompc.callCB(this._dompc._onSetLocalDescriptionFailure,
|
||||
new RTCError(code, message));
|
||||
this.newError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onSetRemoteDescriptionError: function(code, message) {
|
||||
this._remoteType = null;
|
||||
this._dompc.callCB(this._dompc._onSetRemoteDescriptionFailure,
|
||||
new RTCError(code, message));
|
||||
this.newError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
@ -1212,7 +1209,7 @@ PeerConnectionObserver.prototype = {
|
||||
|
||||
onAddIceCandidateError: function(code, message) {
|
||||
this._dompc.callCB(this._dompc._onAddIceCandidateError,
|
||||
new RTCError(code, message));
|
||||
this.newError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
@ -1343,7 +1340,7 @@ PeerConnectionObserver.prototype = {
|
||||
|
||||
onGetStatsError: function(code, message) {
|
||||
this._dompc.callCB(this._dompc._onGetStatsFailure,
|
||||
new RTCError(code, message));
|
||||
this.newError(code, message));
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
@ -1381,7 +1378,7 @@ PeerConnectionObserver.prototype = {
|
||||
var pc = this._dompc;
|
||||
pc._onReplaceTrackWithTrack = null;
|
||||
pc._onReplaceTrackSender = null;
|
||||
pc.callCB(pc._onReplaceTrackError, new RTCError(code, message));
|
||||
pc.callCB(pc._onReplaceTrackError, this.newError(code, message));
|
||||
},
|
||||
|
||||
foundIceCandidate: function(cand) {
|
||||
|
@ -59,13 +59,10 @@ interface IPeerConnection : nsISupports
|
||||
|
||||
/* Constants for 'name' in error callbacks */
|
||||
const unsigned long kNoError = 0; // Test driver only
|
||||
const unsigned long kInvalidConstraintsType = 1;
|
||||
const unsigned long kInvalidCandidateType = 2;
|
||||
const unsigned long kInvalidMediastreamTrack = 3;
|
||||
const unsigned long kInvalidState = 4;
|
||||
const unsigned long kInvalidSessionDescription = 5;
|
||||
const unsigned long kIncompatibleSessionDescription = 6;
|
||||
const unsigned long kIncompatibleConstraints = 7;
|
||||
const unsigned long kIncompatibleMediaStreamTrack = 8;
|
||||
const unsigned long kInternalError = 9;
|
||||
const unsigned long kMaxErrorType = 9; // Same as final error
|
||||
|
@ -31,7 +31,7 @@
|
||||
{candidate:"1 1 UDP 2130706431 192.168.2.1 50005 typ host",
|
||||
sdpMLineIndex: 1}),
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
test.pcLocal._latest_offer.type="answer";
|
||||
test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._latest_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
test.pcLocal._latest_offer.type="answer";
|
||||
test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._latest_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
function (test) {
|
||||
test.pcRemote.setLocalDescriptionAndFail(test.pcLocal._latest_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
test.pcLocal._latest_offer.type="answer";
|
||||
test.pcRemote.setRemoteDescriptionAndFail(test.pcLocal._latest_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
test.pcLocal._latest_offer.type="answer";
|
||||
test.pcLocal.setRemoteDescriptionAndFail(test.pcLocal._latest_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
function (test) {
|
||||
test.pcLocal.setRemoteDescriptionAndFail(test.pcLocal._latest_offer,
|
||||
function(err) {
|
||||
is(err.name, "INVALID_STATE", "Error is INVALID_STATE");
|
||||
is(err.name, "InvalidStateError", "Error is InvalidStateError");
|
||||
test.next();
|
||||
} );
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_quota_acquirelistener_h__
|
||||
#define mozilla_dom_quota_acquirelistener_h__
|
||||
|
||||
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||
|
||||
BEGIN_QUOTA_NAMESPACE
|
||||
|
||||
class AcquireListener
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
AddRef() = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
Release() = 0;
|
||||
|
||||
virtual nsresult
|
||||
OnExclusiveAccessAcquired() = 0;
|
||||
};
|
||||
|
||||
END_QUOTA_NAMESPACE
|
||||
|
||||
#endif // mozilla_dom_quota_acquirelistener_h__
|
@ -113,12 +113,6 @@ public:
|
||||
WaitForStoragesToComplete(nsTArray<nsIOfflineStorage*>& aStorages,
|
||||
nsIRunnable* aCallback) = 0;
|
||||
|
||||
virtual void
|
||||
AbortTransactionsForStorage(nsIOfflineStorage* aStorage) = 0;
|
||||
|
||||
virtual bool
|
||||
HasTransactionsForStorage(nsIOfflineStorage* aStorage) = 0;
|
||||
|
||||
virtual void
|
||||
ShutdownTransactionService() = 0;
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
#include "AcquireListener.h"
|
||||
#include "CheckQuotaHelper.h"
|
||||
#include "OriginCollection.h"
|
||||
#include "OriginOrPatternString.h"
|
||||
@ -158,9 +157,8 @@ struct SynchronizedOp
|
||||
const OriginOrPatternString mOriginOrPattern;
|
||||
Nullable<PersistenceType> mPersistenceType;
|
||||
nsCString mId;
|
||||
nsRefPtr<AcquireListener> mListener;
|
||||
nsCOMPtr<nsIRunnable> mRunnable;
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > mDelayedRunnables;
|
||||
ArrayCluster<nsIOfflineStorage*> mStorages;
|
||||
};
|
||||
|
||||
class CollectOriginsHelper MOZ_FINAL : public nsRunnable
|
||||
@ -199,8 +197,7 @@ private:
|
||||
// them before dispatching itself back to the main thread. When back on the main
|
||||
// thread the runnable will notify the QuotaManager that the job has been
|
||||
// completed.
|
||||
class OriginClearRunnable MOZ_FINAL : public nsRunnable,
|
||||
public AcquireListener
|
||||
class OriginClearRunnable MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
enum CallbackState {
|
||||
// Not yet run.
|
||||
@ -229,10 +226,6 @@ public:
|
||||
NS_IMETHOD
|
||||
Run();
|
||||
|
||||
// AcquireListener override
|
||||
virtual nsresult
|
||||
OnExclusiveAccessAcquired() MOZ_OVERRIDE;
|
||||
|
||||
void
|
||||
AdvanceState()
|
||||
{
|
||||
@ -251,10 +244,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
InvalidateOpenedStorages(nsTArray<nsCOMPtr<nsIOfflineStorage> >& aStorages,
|
||||
void* aClosure);
|
||||
|
||||
void
|
||||
DeleteFiles(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType);
|
||||
@ -354,8 +343,7 @@ private:
|
||||
const bool mIsApp;
|
||||
};
|
||||
|
||||
class ResetOrClearRunnable MOZ_FINAL : public nsRunnable,
|
||||
public AcquireListener
|
||||
class ResetOrClearRunnable MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
enum CallbackState {
|
||||
// Not yet run.
|
||||
@ -382,10 +370,6 @@ public:
|
||||
NS_IMETHOD
|
||||
Run();
|
||||
|
||||
// AcquireListener override
|
||||
virtual nsresult
|
||||
OnExclusiveAccessAcquired() MOZ_OVERRIDE;
|
||||
|
||||
void
|
||||
AdvanceState()
|
||||
{
|
||||
@ -404,10 +388,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
InvalidateOpenedStorages(nsTArray<nsCOMPtr<nsIOfflineStorage> >& aStorages,
|
||||
void* aClosure);
|
||||
|
||||
void
|
||||
DeleteFiles(QuotaManager* aQuotaManager);
|
||||
|
||||
@ -540,8 +520,7 @@ public:
|
||||
: mOp(aOp), mCountdown(1)
|
||||
{
|
||||
NS_ASSERTION(mOp, "Why don't we have a runnable?");
|
||||
NS_ASSERTION(mOp->mStorages.IsEmpty(), "We're here too early!");
|
||||
NS_ASSERTION(mOp->mListener,
|
||||
NS_ASSERTION(mOp->mRunnable,
|
||||
"What are we supposed to do when we're done?");
|
||||
NS_ASSERTION(mCountdown, "Wrong countdown!");
|
||||
}
|
||||
@ -1766,69 +1745,10 @@ QuotaManager::UnregisterStorage(nsIOfflineStorage* aStorage)
|
||||
}
|
||||
|
||||
void
|
||||
QuotaManager::OnStorageClosed(nsIOfflineStorage* aStorage)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aStorage, "Null pointer!");
|
||||
|
||||
// Check through the list of SynchronizedOps to see if any are waiting for
|
||||
// this storage to close before proceeding.
|
||||
SynchronizedOp* op =
|
||||
FindSynchronizedOp(aStorage->Origin(),
|
||||
Nullable<PersistenceType>(aStorage->Type()),
|
||||
aStorage->Id());
|
||||
if (op) {
|
||||
Client::Type clientType = aStorage->GetClient()->GetType();
|
||||
|
||||
// This storage is in the scope of this SynchronizedOp. Remove it
|
||||
// from the list if necessary.
|
||||
if (op->mStorages[clientType].RemoveElement(aStorage)) {
|
||||
// Now set up the helper if there are no more live storages.
|
||||
NS_ASSERTION(op->mListener,
|
||||
"How did we get rid of the listener before removing the "
|
||||
"last storage?");
|
||||
if (op->mStorages[clientType].IsEmpty()) {
|
||||
// At this point, all storages are closed, so no new transactions
|
||||
// can be started. There may, however, still be outstanding
|
||||
// transactions that have not completed. We need to wait for those
|
||||
// before we dispatch the helper.
|
||||
if (NS_FAILED(RunSynchronizedOp(aStorage, op))) {
|
||||
NS_WARNING("Failed to run synchronized op!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class OwnerClass>
|
||||
struct OwnerTraits;
|
||||
|
||||
template <>
|
||||
struct OwnerTraits<nsPIDOMWindow>
|
||||
{
|
||||
static bool
|
||||
IsOwned(nsIOfflineStorage* aStorage, nsPIDOMWindow* aOwner)
|
||||
{
|
||||
return aStorage->IsOwnedByWindow(aOwner);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OwnerTraits<mozilla::dom::ContentParent>
|
||||
{
|
||||
static bool
|
||||
IsOwned(nsIOfflineStorage* aStorage, mozilla::dom::ContentParent* aOwner)
|
||||
{
|
||||
return aStorage->IsOwnedByProcess(aOwner);
|
||||
}
|
||||
};
|
||||
|
||||
template <class OwnerClass>
|
||||
void
|
||||
QuotaManager::AbortCloseStoragesFor(OwnerClass* aOwnerClass)
|
||||
QuotaManager::AbortCloseStoragesForProcess(ContentParent* aContentParent)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aOwnerClass);
|
||||
MOZ_ASSERT(aContentParent);
|
||||
|
||||
FileService* service = FileService::Get();
|
||||
|
||||
@ -1838,78 +1758,24 @@ QuotaManager::AbortCloseStoragesFor(OwnerClass* aOwnerClass)
|
||||
for (uint32_t i = 0; i < Client::TYPE_MAX; i++) {
|
||||
nsRefPtr<Client>& client = mClients[i];
|
||||
bool utilized = service && client->IsFileServiceUtilized();
|
||||
bool activated = client->IsTransactionServiceActivated();
|
||||
|
||||
nsTArray<nsIOfflineStorage*>& array = liveStorages[i];
|
||||
for (uint32_t j = 0; j < array.Length(); j++) {
|
||||
nsCOMPtr<nsIOfflineStorage> storage = array[j];
|
||||
|
||||
if (OwnerTraits<OwnerClass>::IsOwned(storage, aOwnerClass)) {
|
||||
if (storage->IsOwnedByProcess(aContentParent)) {
|
||||
if (NS_FAILED(storage->Close())) {
|
||||
NS_WARNING("Failed to close storage for dying window!");
|
||||
NS_WARNING("Failed to close storage for dying process!");
|
||||
}
|
||||
|
||||
if (utilized) {
|
||||
service->AbortFileHandlesForStorage(storage);
|
||||
}
|
||||
|
||||
if (activated) {
|
||||
client->AbortTransactionsForStorage(storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QuotaManager::AbortCloseStoragesForWindow(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
AbortCloseStoragesFor(aWindow);
|
||||
}
|
||||
|
||||
void
|
||||
QuotaManager::AbortCloseStoragesForProcess(ContentParent* aContentParent)
|
||||
{
|
||||
AbortCloseStoragesFor(aContentParent);
|
||||
}
|
||||
|
||||
bool
|
||||
QuotaManager::HasOpenTransactions(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aWindow, "Null pointer!");
|
||||
|
||||
FileService* service = FileService::Get();
|
||||
|
||||
nsAutoPtr<StorageMatcher<ArrayCluster<nsIOfflineStorage*> > > liveStorages;
|
||||
|
||||
for (uint32_t i = 0; i < Client::TYPE_MAX; i++) {
|
||||
nsRefPtr<Client>& client = mClients[i];
|
||||
bool utilized = service && client->IsFileServiceUtilized();
|
||||
bool activated = client->IsTransactionServiceActivated();
|
||||
|
||||
if (utilized || activated) {
|
||||
if (!liveStorages) {
|
||||
liveStorages = new StorageMatcher<ArrayCluster<nsIOfflineStorage*> >();
|
||||
liveStorages->Find(mLiveStorages);
|
||||
}
|
||||
|
||||
nsTArray<nsIOfflineStorage*>& storages = liveStorages->ArrayAt(i);
|
||||
for (uint32_t j = 0; j < storages.Length(); j++) {
|
||||
nsIOfflineStorage*& storage = storages[j];
|
||||
|
||||
if (storage->IsOwnedByWindow(aWindow) &&
|
||||
((utilized && service->HasFileHandlesForStorage(storage)) ||
|
||||
(activated && client->HasTransactionsForStorage(storage)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
QuotaManager::WaitForOpenAllowed(const OriginOrPatternString& aOriginOrPattern,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
@ -1982,8 +1848,6 @@ QuotaManager::AllowNextSynchronizedOp(
|
||||
op->mOriginOrPattern == aOriginOrPattern &&
|
||||
op->mPersistenceType == aPersistenceType) {
|
||||
if (op->mId == aId) {
|
||||
NS_ASSERTION(op->mStorages.IsEmpty(), "How did this happen?");
|
||||
|
||||
op->DispatchDelayedRunnables();
|
||||
|
||||
mSynchronizedOps.RemoveElementAt(index);
|
||||
@ -3360,170 +3224,81 @@ QuotaManager::LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
|
||||
nsresult
|
||||
QuotaManager::AcquireExclusiveAccess(const nsACString& aPattern,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
nsIOfflineStorage* aStorage,
|
||||
AcquireListener* aListener,
|
||||
WaitingOnStoragesCallback aCallback,
|
||||
void* aClosure)
|
||||
nsIRunnable* aRunnable)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aListener, "Need a listener!");
|
||||
NS_ASSERTION(aRunnable, "Need a runnable!");
|
||||
|
||||
// Find the right SynchronizedOp.
|
||||
SynchronizedOp* op =
|
||||
FindSynchronizedOp(aPattern, aPersistenceType,
|
||||
aStorage ? aStorage->Id() : EmptyCString());
|
||||
FindSynchronizedOp(aPattern, aPersistenceType, EmptyCString());
|
||||
|
||||
NS_ASSERTION(op, "We didn't find a SynchronizedOp?");
|
||||
NS_ASSERTION(!op->mListener, "SynchronizedOp already has a listener?!?");
|
||||
NS_ASSERTION(!op->mRunnable, "SynchronizedOp already has a runnable?!?");
|
||||
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage> > liveStorages;
|
||||
ArrayCluster<nsIOfflineStorage*> liveStorages;
|
||||
|
||||
if (aStorage) {
|
||||
// We need to wait for the storages to go away.
|
||||
// Hold on to all storage objects that represent the same storage file
|
||||
// (except the one that is requesting this version change).
|
||||
|
||||
Client::Type clientType = aStorage->GetClient()->GetType();
|
||||
|
||||
StorageMatcher<nsAutoTArray<nsIOfflineStorage*, 20> > matches;
|
||||
matches.Find(mLiveStorages, aPattern, clientType);
|
||||
|
||||
if (!matches.IsEmpty()) {
|
||||
// Grab all storages that are not yet closed but whose storage id match
|
||||
// the one we're looking for.
|
||||
for (uint32_t index = 0; index < matches.Length(); index++) {
|
||||
nsIOfflineStorage*& storage = matches[index];
|
||||
if (!storage->IsClosed() &&
|
||||
storage != aStorage &&
|
||||
storage->Id() == aStorage->Id() &&
|
||||
(aPersistenceType.IsNull() ||
|
||||
aPersistenceType.Value() == storage->Type())) {
|
||||
liveStorages.AppendElement(storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!liveStorages.IsEmpty()) {
|
||||
NS_ASSERTION(op->mStorages[clientType].IsEmpty(),
|
||||
"How do we already have storages here?");
|
||||
op->mStorages[clientType].AppendElements(liveStorages);
|
||||
}
|
||||
StorageMatcher<ArrayCluster<nsIOfflineStorage*> > matches;
|
||||
if (aPattern.IsVoid()) {
|
||||
matches.Find(mLiveStorages);
|
||||
}
|
||||
else {
|
||||
StorageMatcher<ArrayCluster<nsIOfflineStorage*> > matches;
|
||||
if (aPattern.IsVoid()) {
|
||||
matches.Find(mLiveStorages);
|
||||
}
|
||||
else {
|
||||
matches.Find(mLiveStorages, aPattern);
|
||||
}
|
||||
matches.Find(mLiveStorages, aPattern);
|
||||
}
|
||||
|
||||
NS_ASSERTION(op->mStorages.IsEmpty(),
|
||||
"How do we already have storages here?");
|
||||
|
||||
// We want *all* storages that match the given persistence type, even those
|
||||
// that are closed, when we're going to clear the origin.
|
||||
if (!matches.IsEmpty()) {
|
||||
for (uint32_t i = 0; i < Client::TYPE_MAX; i++) {
|
||||
nsTArray<nsIOfflineStorage*>& storages = matches.ArrayAt(i);
|
||||
for (uint32_t j = 0; j < storages.Length(); j++) {
|
||||
nsIOfflineStorage* storage = storages[j];
|
||||
if (aPersistenceType.IsNull() ||
|
||||
aPersistenceType.Value() == storage->Type()) {
|
||||
liveStorages.AppendElement(storage);
|
||||
op->mStorages[i].AppendElement(storage);
|
||||
}
|
||||
// We want *all* storages that match the given persistence type, even those
|
||||
// that are closed, when we're going to clear the origin.
|
||||
if (!matches.IsEmpty()) {
|
||||
for (uint32_t i = 0; i < Client::TYPE_MAX; i++) {
|
||||
nsTArray<nsIOfflineStorage*>& storages = matches.ArrayAt(i);
|
||||
for (uint32_t j = 0; j < storages.Length(); j++) {
|
||||
nsIOfflineStorage* storage = storages[j];
|
||||
if (aPersistenceType.IsNull() ||
|
||||
aPersistenceType.Value() == storage->Type()) {
|
||||
storage->Invalidate();
|
||||
liveStorages[i].AppendElement(storage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
op->mListener = aListener;
|
||||
|
||||
if (!liveStorages.IsEmpty()) {
|
||||
// Give our callback the storages so it can decide what to do with them.
|
||||
aCallback(liveStorages, aClosure);
|
||||
|
||||
NS_ASSERTION(liveStorages.IsEmpty(),
|
||||
"Should have done something with the array!");
|
||||
|
||||
if (aStorage) {
|
||||
// Wait for those storages to close.
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're trying to open a storage and nothing blocks it, or if we're
|
||||
// clearing an origin, then go ahead and schedule the op.
|
||||
nsresult rv = RunSynchronizedOp(aStorage, op);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
QuotaManager::RunSynchronizedOp(nsIOfflineStorage* aStorage,
|
||||
SynchronizedOp* aOp)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aOp, "Null pointer!");
|
||||
NS_ASSERTION(aOp->mListener, "No listener on this op!");
|
||||
NS_ASSERTION(!aStorage ||
|
||||
aOp->mStorages[aStorage->GetClient()->GetType()].IsEmpty(),
|
||||
"This op isn't ready to run!");
|
||||
|
||||
ArrayCluster<nsIOfflineStorage*> storages;
|
||||
|
||||
uint32_t startIndex;
|
||||
uint32_t endIndex;
|
||||
|
||||
if (aStorage) {
|
||||
Client::Type clientType = aStorage->GetClient()->GetType();
|
||||
|
||||
storages[clientType].AppendElement(aStorage);
|
||||
|
||||
startIndex = clientType;
|
||||
endIndex = clientType + 1;
|
||||
}
|
||||
else {
|
||||
aOp->mStorages.SwapElements(storages);
|
||||
|
||||
startIndex = 0;
|
||||
endIndex = Client::TYPE_MAX;
|
||||
}
|
||||
op->mRunnable = aRunnable;
|
||||
|
||||
nsRefPtr<WaitForTransactionsToFinishRunnable> runnable =
|
||||
new WaitForTransactionsToFinishRunnable(aOp);
|
||||
new WaitForTransactionsToFinishRunnable(op);
|
||||
|
||||
// Ask the file service to call us back when it's done with this storage.
|
||||
FileService* service = FileService::Get();
|
||||
if (!liveStorages.IsEmpty()) {
|
||||
// Ask the file service to call us back when it's done with this storage.
|
||||
FileService* service = FileService::Get();
|
||||
|
||||
if (service) {
|
||||
// Have to copy here in case a transaction service needs a list too.
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage>> array;
|
||||
if (service) {
|
||||
// Have to copy here in case a transaction service needs a list too.
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage>> array;
|
||||
|
||||
for (uint32_t index = startIndex; index < endIndex; index++) {
|
||||
if (!storages[index].IsEmpty() &&
|
||||
mClients[index]->IsFileServiceUtilized()) {
|
||||
array.AppendElements(storages[index]);
|
||||
for (uint32_t index = 0; index < Client::TYPE_MAX; index++) {
|
||||
if (!liveStorages[index].IsEmpty() &&
|
||||
mClients[index]->IsFileServiceUtilized()) {
|
||||
array.AppendElements(liveStorages[index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!array.IsEmpty()) {
|
||||
runnable->AddRun();
|
||||
|
||||
service->WaitForStoragesToComplete(array, runnable);
|
||||
}
|
||||
}
|
||||
|
||||
if (!array.IsEmpty()) {
|
||||
runnable->AddRun();
|
||||
// Ask each transaction service to call us back when they're done with this
|
||||
// storage.
|
||||
for (uint32_t index = 0; index < Client::TYPE_MAX; index++) {
|
||||
nsRefPtr<Client>& client = mClients[index];
|
||||
if (!liveStorages[index].IsEmpty() &&
|
||||
client->IsTransactionServiceActivated()) {
|
||||
runnable->AddRun();
|
||||
|
||||
service->WaitForStoragesToComplete(array, runnable);
|
||||
}
|
||||
}
|
||||
|
||||
// Ask each transaction service to call us back when they're done with this
|
||||
// storage.
|
||||
for (uint32_t index = startIndex; index < endIndex; index++) {
|
||||
nsRefPtr<Client>& client = mClients[index];
|
||||
if (!storages[index].IsEmpty() && client->IsTransactionServiceActivated()) {
|
||||
runnable->AddRun();
|
||||
|
||||
client->WaitForStoragesToComplete(storages[index], runnable);
|
||||
client->WaitForStoragesToComplete(liveStorages[index], runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4147,7 +3922,7 @@ void
|
||||
SynchronizedOp::DispatchDelayedRunnables()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!mListener, "Any listener should be gone by now!");
|
||||
NS_ASSERTION(!mRunnable, "Any runnable should be gone by now!");
|
||||
|
||||
uint32_t count = mDelayedRunnables.Length();
|
||||
for (uint32_t index = 0; index < count; index++) {
|
||||
@ -4210,34 +3985,6 @@ CollectOriginsHelper::Run()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
OriginClearRunnable::OnExclusiveAccessAcquired()
|
||||
{
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
NS_ASSERTION(quotaManager, "This should never fail!");
|
||||
|
||||
nsresult rv = quotaManager->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
OriginClearRunnable::InvalidateOpenedStorages(
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage> >& aStorages,
|
||||
void* aClosure)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage> > storages;
|
||||
storages.SwapElements(aStorages);
|
||||
|
||||
for (uint32_t index = 0; index < storages.Length(); index++) {
|
||||
storages[index]->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OriginClearRunnable::DeleteFiles(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType)
|
||||
@ -4349,8 +4096,7 @@ OriginClearRunnable::Run()
|
||||
// storages we care about.
|
||||
nsresult rv =
|
||||
quotaManager->AcquireExclusiveAccess(mOriginOrPattern, mPersistenceType,
|
||||
this, InvalidateOpenedStorages,
|
||||
nullptr);
|
||||
this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@ -4640,34 +4386,6 @@ AsyncUsageRunnable::Cancel()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ResetOrClearRunnable::OnExclusiveAccessAcquired()
|
||||
{
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
NS_ASSERTION(quotaManager, "This should never fail!");
|
||||
|
||||
nsresult rv = quotaManager->IOThread()->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
ResetOrClearRunnable::InvalidateOpenedStorages(
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage> >& aStorages,
|
||||
void* aClosure)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsTArray<nsCOMPtr<nsIOfflineStorage> > storages;
|
||||
storages.SwapElements(aStorages);
|
||||
|
||||
for (uint32_t index = 0; index < storages.Length(); index++) {
|
||||
storages[index]->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResetOrClearRunnable::DeleteFiles(QuotaManager* aQuotaManager)
|
||||
{
|
||||
@ -4715,8 +4433,7 @@ ResetOrClearRunnable::Run()
|
||||
// storages we care about.
|
||||
nsresult rv =
|
||||
quotaManager->AcquireExclusiveAccess(NullCString(),
|
||||
Nullable<PersistenceType>(), this,
|
||||
InvalidateOpenedStorages, nullptr);
|
||||
Nullable<PersistenceType>(), this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@ -4861,20 +4578,24 @@ WaitForTransactionsToFinishRunnable::Run()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(mOp, "Null op!");
|
||||
NS_ASSERTION(mOp->mListener, "Nothing to run!");
|
||||
NS_ASSERTION(mOp->mRunnable, "Nothing to run!");
|
||||
NS_ASSERTION(mCountdown, "Wrong countdown!");
|
||||
|
||||
if (--mCountdown) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't hold the listener alive longer than necessary.
|
||||
nsRefPtr<AcquireListener> listener;
|
||||
listener.swap(mOp->mListener);
|
||||
// Don't hold the runnable alive longer than necessary.
|
||||
nsCOMPtr<nsIRunnable> runnable;
|
||||
runnable.swap(mOp->mRunnable);
|
||||
|
||||
mOp = nullptr;
|
||||
|
||||
nsresult rv = listener->OnExclusiveAccessAcquired();
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
NS_ASSERTION(quotaManager, "This should never fail!");
|
||||
|
||||
nsresult rv =
|
||||
quotaManager->IOThread()->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The listener is responsible for calling
|
||||
|
@ -90,9 +90,6 @@ class QuotaManager MOZ_FINAL : public nsIQuotaManager,
|
||||
IgnoreMozBrowser
|
||||
};
|
||||
|
||||
typedef void
|
||||
(*WaitingOnStoragesCallback)(nsTArray<nsCOMPtr<nsIOfflineStorage> >&, void*);
|
||||
|
||||
typedef nsClassHashtable<nsCStringHashKey,
|
||||
nsTArray<nsIOfflineStorage*>> LiveStorageTable;
|
||||
|
||||
@ -193,25 +190,11 @@ public:
|
||||
void
|
||||
UnregisterStorage(nsIOfflineStorage* aStorage);
|
||||
|
||||
// Called when a storage has been closed.
|
||||
void
|
||||
OnStorageClosed(nsIOfflineStorage* aStorage);
|
||||
|
||||
// Called when a window is being purged from the bfcache or the user leaves
|
||||
// a page which isn't going into the bfcache. Forces any live storage
|
||||
// objects to close themselves and aborts any running transactions.
|
||||
void
|
||||
AbortCloseStoragesForWindow(nsPIDOMWindow* aWindow);
|
||||
|
||||
// Called when a process is being shot down. Forces any live storage objects
|
||||
// to close themselves and aborts any running transactions.
|
||||
void
|
||||
AbortCloseStoragesForProcess(ContentParent* aContentParent);
|
||||
|
||||
// Used to check if there are running transactions in a given window.
|
||||
bool
|
||||
HasOpenTransactions(nsPIDOMWindow* aWindow);
|
||||
|
||||
// Waits for storages to be cleared and for version change transactions to
|
||||
// complete before dispatching the given runnable.
|
||||
nsresult
|
||||
@ -219,33 +202,6 @@ public:
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
const nsACString& aId, nsIRunnable* aRunnable);
|
||||
|
||||
// Acquire exclusive access to the storage given (waits for all others to
|
||||
// close). If storages need to close first, the callback will be invoked
|
||||
// with an array of said storages.
|
||||
nsresult
|
||||
AcquireExclusiveAccess(nsIOfflineStorage* aStorage,
|
||||
const nsACString& aOrigin,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
AcquireListener* aListener,
|
||||
WaitingOnStoragesCallback aCallback,
|
||||
void* aClosure)
|
||||
{
|
||||
NS_ASSERTION(aStorage, "Need a storage here!");
|
||||
return AcquireExclusiveAccess(aOrigin, aPersistenceType, aStorage,
|
||||
aListener, aCallback, aClosure);
|
||||
}
|
||||
|
||||
nsresult
|
||||
AcquireExclusiveAccess(const nsACString& aOrigin,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
AcquireListener* aListener,
|
||||
WaitingOnStoragesCallback aCallback,
|
||||
void* aClosure)
|
||||
{
|
||||
return AcquireExclusiveAccess(aOrigin, aPersistenceType, nullptr,
|
||||
aListener, aCallback, aClosure);
|
||||
}
|
||||
|
||||
void
|
||||
AllowNextSynchronizedOp(const OriginOrPatternString& aOriginOrPattern,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
@ -433,19 +389,12 @@ private:
|
||||
nsresult
|
||||
AcquireExclusiveAccess(const nsACString& aOrigin,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
nsIOfflineStorage* aStorage,
|
||||
AcquireListener* aListener,
|
||||
WaitingOnStoragesCallback aCallback,
|
||||
void* aClosure);
|
||||
nsIRunnable* aRunnable);
|
||||
|
||||
void
|
||||
AddSynchronizedOp(const OriginOrPatternString& aOriginOrPattern,
|
||||
Nullable<PersistenceType> aPersistenceType);
|
||||
|
||||
nsresult
|
||||
RunSynchronizedOp(nsIOfflineStorage* aStorage,
|
||||
SynchronizedOp* aOp);
|
||||
|
||||
SynchronizedOp*
|
||||
FindSynchronizedOp(const nsACString& aPattern,
|
||||
Nullable<PersistenceType> aPersistenceType,
|
||||
@ -505,10 +454,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template <class OwnerClass>
|
||||
void
|
||||
AbortCloseStoragesFor(OwnerClass* aOwnerClass);
|
||||
|
||||
LiveStorageTable&
|
||||
GetLiveStorageTable(PersistenceType aPersistenceType);
|
||||
|
||||
|
@ -17,7 +17,6 @@ EXPORTS += [
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom.quota += [
|
||||
'AcquireListener.h',
|
||||
'ArrayCluster.h',
|
||||
'Client.h',
|
||||
'FileStreams.h',
|
||||
|
@ -42,9 +42,6 @@ public:
|
||||
NS_IMETHOD_(Client*)
|
||||
GetClient() = 0;
|
||||
|
||||
NS_IMETHOD_(bool)
|
||||
IsOwnedByWindow(nsPIDOMWindow* aOwner) = 0;
|
||||
|
||||
NS_IMETHOD_(bool)
|
||||
IsOwnedByProcess(ContentParent* aOwner) = 0;
|
||||
|
||||
@ -68,10 +65,6 @@ public:
|
||||
NS_IMETHOD_(nsresult)
|
||||
Close() = 0;
|
||||
|
||||
// Whether or not the storage has had Close called on it.
|
||||
NS_IMETHOD_(bool)
|
||||
IsClosed() = 0;
|
||||
|
||||
// Implementation of this method should close the storage, all running
|
||||
// operations should be aborted and pending operations should be discarded.
|
||||
NS_IMETHOD_(void)
|
||||
@ -99,9 +92,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIOfflineStorage, NS_OFFLINESTORAGE_IID)
|
||||
GetClient() MOZ_OVERRIDE; \
|
||||
\
|
||||
NS_IMETHOD_(bool) \
|
||||
IsOwnedByWindow(nsPIDOMWindow* aOwner) MOZ_OVERRIDE; \
|
||||
\
|
||||
NS_IMETHOD_(bool) \
|
||||
IsOwnedByProcess(ContentParent* aOwner) MOZ_OVERRIDE; \
|
||||
\
|
||||
NS_IMETHOD_(const nsACString&) \
|
||||
@ -110,9 +100,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIOfflineStorage, NS_OFFLINESTORAGE_IID)
|
||||
NS_IMETHOD_(nsresult) \
|
||||
Close() MOZ_OVERRIDE; \
|
||||
\
|
||||
NS_IMETHOD_(bool) \
|
||||
IsClosed() MOZ_OVERRIDE; \
|
||||
\
|
||||
NS_IMETHOD_(void) \
|
||||
Invalidate() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
callback RTCSessionDescriptionCallback = void (mozRTCSessionDescription sdp);
|
||||
callback RTCPeerConnectionErrorCallback = void (DOMString errorInformation);
|
||||
callback RTCPeerConnectionErrorCallback = void (DOMError error);
|
||||
callback VoidFunction = void ();
|
||||
callback RTCStatsCallback = void (RTCStatsReport report);
|
||||
|
||||
|
@ -106,3 +106,5 @@ MOCHITEST_MANIFESTS += [
|
||||
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
4
dom/workers/test/browser.ini
Normal file
4
dom/workers/test/browser.ini
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
|
||||
[browser_bug1104623.js]
|
||||
run-if = buildapp == 'browser'
|
48
dom/workers/test/browser_bug1104623.js
Normal file
48
dom/workers/test/browser_bug1104623.js
Normal file
@ -0,0 +1,48 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function whenBrowserLoaded(aBrowser, aCallback) {
|
||||
aBrowser.addEventListener("load", function onLoad(event) {
|
||||
if (event.target == aBrowser.contentDocument) {
|
||||
aBrowser.removeEventListener("load", onLoad, true);
|
||||
executeSoon(aCallback);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let testURL = "chrome://mochitests/content/chrome/dom/base/test/file_empty.html";
|
||||
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
whenBrowserLoaded(tab.linkedBrowser, function() {
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
|
||||
let blob = new tab.linkedBrowser.contentWindow.Blob(['onmessage = function() { postMessage(true); }']);
|
||||
ok(blob, "Blob has been created");
|
||||
|
||||
let blobURL = tab.linkedBrowser.contentWindow.URL.createObjectURL(blob);
|
||||
ok(blobURL, "Blob URL has been created");
|
||||
|
||||
let worker = new tab.linkedBrowser.contentWindow.Worker(blobURL);
|
||||
ok(worker, "Worker has been created");
|
||||
|
||||
worker.onerror = function(error) {
|
||||
ok(false, "Worker.onerror:" + error.message);
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
worker.onmessage = function() {
|
||||
ok(true, "Worker.onmessage");
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
worker.postMessage(true);
|
||||
});
|
||||
}
|
@ -78,7 +78,6 @@ nsXBLPrototypeResources::FlushSkinSheets()
|
||||
// We have scoped stylesheets. Reload any chrome stylesheets we
|
||||
// encounter. (If they aren't skin sheets, it doesn't matter, since
|
||||
// they'll still be in the chrome cache.
|
||||
mRuleProcessor = nullptr;
|
||||
|
||||
nsTArray<nsRefPtr<CSSStyleSheet>> oldSheets;
|
||||
|
||||
@ -144,7 +143,8 @@ nsXBLPrototypeResources::GatherRuleProcessor()
|
||||
{
|
||||
mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList,
|
||||
nsStyleSet::eDocSheet,
|
||||
nullptr);
|
||||
nullptr,
|
||||
mRuleProcessor);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -40,7 +40,10 @@ public:
|
||||
virtual DrawTargetType GetType() const MOZ_OVERRIDE { return mTiles[0].mDrawTarget->GetType(); }
|
||||
virtual BackendType GetBackendType() const { return mTiles[0].mDrawTarget->GetBackendType(); }
|
||||
virtual TemporaryRef<SourceSurface> Snapshot();
|
||||
virtual IntSize GetSize() { return IntSize(mRect.XMost(), mRect.YMost()); }
|
||||
virtual IntSize GetSize() {
|
||||
MOZ_ASSERT(mRect.width > 0 && mRect.height > 0);
|
||||
return IntSize(mRect.XMost(), mRect.YMost());
|
||||
}
|
||||
|
||||
virtual void Flush();
|
||||
virtual void DrawSurface(SourceSurface *aSurface,
|
||||
@ -162,7 +165,10 @@ public:
|
||||
}
|
||||
|
||||
virtual SurfaceType GetType() const { return SurfaceType::TILED; }
|
||||
virtual IntSize GetSize() const { return IntSize(mRect.XMost(), mRect.YMost()); }
|
||||
virtual IntSize GetSize() const {
|
||||
MOZ_ASSERT(mRect.width > 0 && mRect.height > 0);
|
||||
return IntSize(mRect.XMost(), mRect.YMost());
|
||||
}
|
||||
virtual SurfaceFormat GetFormat() const { return mSnapshots[0]->GetFormat(); }
|
||||
|
||||
virtual TemporaryRef<DataSourceSurface> GetDataSurface()
|
||||
|
@ -517,7 +517,6 @@ public:
|
||||
|
||||
static const char* GetFeatureName(GLFeature feature);
|
||||
|
||||
|
||||
private:
|
||||
std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
|
||||
|
||||
|
@ -399,7 +399,7 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
*/
|
||||
},
|
||||
{
|
||||
"renderbuffer_float",
|
||||
"renderbuffer_color_float",
|
||||
GLVersion::GL3,
|
||||
GLESVersion::ES3,
|
||||
GLContext::Extension_None,
|
||||
@ -410,7 +410,7 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
}
|
||||
},
|
||||
{
|
||||
"renderbuffer_half_float",
|
||||
"renderbuffer_color_half_float",
|
||||
GLVersion::GL3,
|
||||
GLESVersion::ES3,
|
||||
GLContext::Extension_None,
|
||||
|
@ -34,13 +34,6 @@ void ImageLayer::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSu
|
||||
gfxRect sourceRect(0, 0, 0, 0);
|
||||
if (mContainer) {
|
||||
sourceRect.SizeTo(gfx::ThebesIntSize(mContainer->GetCurrentSize()));
|
||||
if (mScaleMode != ScaleMode::SCALE_NONE &&
|
||||
sourceRect.width != 0.0 && sourceRect.height != 0.0) {
|
||||
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
|
||||
"No other scalemodes than stretch and none supported yet.");
|
||||
local.PreScale(mScaleToSize.width / sourceRect.width,
|
||||
mScaleToSize.height / sourceRect.height, 1.0);
|
||||
}
|
||||
}
|
||||
// Snap our local transform first, and snap the inherited transform as well.
|
||||
// This makes our snapping equivalent to what would happen if our content
|
||||
@ -49,6 +42,21 @@ void ImageLayer::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSu
|
||||
mEffectiveTransform =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
|
||||
if (mScaleMode != ScaleMode::SCALE_NONE &&
|
||||
sourceRect.width != 0.0 && sourceRect.height != 0.0) {
|
||||
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
|
||||
"No other scalemodes than stretch and none supported yet.");
|
||||
local.PreScale(mScaleToSize.width / sourceRect.width,
|
||||
mScaleToSize.height / sourceRect.height, 1.0);
|
||||
|
||||
mEffectiveTransformForBuffer =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
} else {
|
||||
mEffectiveTransformForBuffer = mEffectiveTransform;
|
||||
}
|
||||
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,12 @@ public:
|
||||
|
||||
MOZ_LAYER_DECL_NAME("ImageLayer", TYPE_IMAGE)
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface);
|
||||
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) MOZ_OVERRIDE;
|
||||
|
||||
virtual const gfx::Matrix4x4& GetEffectiveTransformForBuffer() const MOZ_OVERRIDE
|
||||
{
|
||||
return mEffectiveTransformForBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* if true, the image will only be backed by a single tile texture
|
||||
@ -94,6 +99,7 @@ protected:
|
||||
gfx::IntSize mScaleToSize;
|
||||
ScaleMode mScaleMode;
|
||||
bool mDisallowBigImage;
|
||||
gfx::Matrix4x4 mEffectiveTransformForBuffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1388,6 +1388,23 @@ public:
|
||||
*/
|
||||
const gfx::Matrix4x4& GetEffectiveTransform() const { return mEffectiveTransform; }
|
||||
|
||||
/**
|
||||
* This returns the effective transform for Layer's buffer computed by
|
||||
* ComputeEffectiveTransforms. Typically this is a transform that transforms
|
||||
* this layer's buffer all the way to some intermediate surface or destination
|
||||
* surface. For non-BasicLayers this will be a transform to the nearest
|
||||
* ancestor with UseIntermediateSurface() (or to the root, if there is no
|
||||
* such ancestor), but for BasicLayers it's different.
|
||||
*
|
||||
* By default, its value is same to GetEffectiveTransform().
|
||||
* When ImageLayer is rendered with ScaleMode::STRETCH,
|
||||
* it becomes different from GetEffectiveTransform().
|
||||
*/
|
||||
virtual const gfx::Matrix4x4& GetEffectiveTransformForBuffer() const
|
||||
{
|
||||
return mEffectiveTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aTransformToSurface the composition of the transforms
|
||||
* from the parent layer (if any) to the destination pixel grid.
|
||||
|
@ -150,7 +150,7 @@ public:
|
||||
bool Setup2DTransform()
|
||||
{
|
||||
// Will return an identity matrix for 3d transforms.
|
||||
return mLayer->GetEffectiveTransform().CanDraw2D(&mTransform);
|
||||
return mLayer->GetEffectiveTransformForBuffer().CanDraw2D(&mTransform);
|
||||
}
|
||||
|
||||
// Applies the effective transform if it's 2D. If it's a 3D transform then
|
||||
@ -875,7 +875,8 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
temp->Paint();
|
||||
}
|
||||
#endif
|
||||
gfx3DMatrix effectiveTransform = gfx::To3DMatrix(aLayer->GetEffectiveTransform());
|
||||
gfx3DMatrix effectiveTransform;
|
||||
effectiveTransform = gfx::To3DMatrix(aLayer->GetEffectiveTransform());
|
||||
nsRefPtr<gfxASurface> result =
|
||||
Transform3D(untransformedDT->Snapshot(), aTarget, bounds,
|
||||
effectiveTransform, destRect);
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -110,7 +111,7 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D10:
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
#ifdef XP_WIN
|
||||
if (mGLContext->IsANGLE()) {
|
||||
if (mGLContext->IsANGLE() && DoesD3D11DeviceWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) {
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
|
||||
}
|
||||
#endif
|
||||
|
@ -1056,6 +1056,9 @@ ClientTiledLayerBuffer::PostValidate(const nsIntRegion& aPaintRegion)
|
||||
{
|
||||
if (gfxPrefs::TiledDrawTargetEnabled() && mMoz2DTiles.size() > 0) {
|
||||
gfx::TileSet tileset;
|
||||
for (size_t i = 0; i < mMoz2DTiles.size(); ++i) {
|
||||
mMoz2DTiles[i].mTileOrigin -= mTilingOrigin;
|
||||
}
|
||||
tileset.mTiles = &mMoz2DTiles[0];
|
||||
tileset.mTileCount = mMoz2DTiles.size();
|
||||
RefPtr<DrawTarget> drawTarget = gfx::Factory::CreateTiledDrawTarget(tileset);
|
||||
@ -1063,10 +1066,13 @@ ClientTiledLayerBuffer::PostValidate(const nsIntRegion& aPaintRegion)
|
||||
|
||||
RefPtr<gfxContext> ctx = new gfxContext(drawTarget);
|
||||
ctx->SetMatrix(
|
||||
ctx->CurrentMatrix().Scale(mResolution, mResolution));
|
||||
ctx->CurrentMatrix().Scale(mResolution, mResolution).Translate(ThebesPoint(-mTilingOrigin)));
|
||||
|
||||
mCallback(mPaintedLayer, ctx, aPaintRegion, DrawRegionClip::DRAW, nsIntRegion(), mCallbackData);
|
||||
mMoz2DTiles.clear();
|
||||
// Reset:
|
||||
mTilingOrigin = IntPoint(std::numeric_limits<int32_t>::max(),
|
||||
std::numeric_limits<int32_t>::max());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1188,6 +1194,8 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
|
||||
}
|
||||
|
||||
mMoz2DTiles.push_back(moz2DTile);
|
||||
mTilingOrigin.x = std::min(mTilingOrigin.x, moz2DTile.mTileOrigin.x);
|
||||
mTilingOrigin.y = std::min(mTilingOrigin.y, moz2DTile.mTileOrigin.y);
|
||||
|
||||
nsIntRegionRectIterator it(aDirtyRegion);
|
||||
for (const nsIntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint16_t
|
||||
#include <algorithm> // for swap
|
||||
#include <limits>
|
||||
#include "Layers.h" // for LayerManager, etc
|
||||
#include "TiledLayerBuffer.h" // for TiledLayerBuffer
|
||||
#include "Units.h" // for CSSPoint
|
||||
@ -399,6 +400,8 @@ public:
|
||||
, mLastPaintContentType(gfxContentType::COLOR)
|
||||
, mLastPaintSurfaceMode(SurfaceMode::SURFACE_OPAQUE)
|
||||
, mSharedFrameMetricsHelper(nullptr)
|
||||
, mTilingOrigin(std::numeric_limits<int32_t>::max(),
|
||||
std::numeric_limits<int32_t>::max())
|
||||
{}
|
||||
|
||||
void PaintThebes(const nsIntRegion& aNewValidRegion,
|
||||
@ -475,6 +478,16 @@ private:
|
||||
SharedFrameMetricsHelper* mSharedFrameMetricsHelper;
|
||||
// When using Moz2D's CreateTiledDrawTarget we maintain a list of gfx::Tiles
|
||||
std::vector<gfx::Tile> mMoz2DTiles;
|
||||
/**
|
||||
* While we're adding tiles, this is used to keep track of the position of
|
||||
* the top-left of the top-left-most tile. When we come to wrap the tiles in
|
||||
* TiledDrawTarget we subtract the value of this member from each tile's
|
||||
* offset so that all the tiles have a positive offset, then add a
|
||||
* translation to the TiledDrawTarget to compensate. This is important so
|
||||
* that the mRect of the TiledDrawTarget is always at a positive x/y
|
||||
* position, otherwise its GetSize() methods will be broken.
|
||||
*/
|
||||
gfx::IntPoint mTilingOrigin;
|
||||
/**
|
||||
* Calculates the region to update in a single progressive update transaction.
|
||||
* This employs some heuristics to update the most 'sensible' region to
|
||||
|
@ -105,7 +105,7 @@ ImageLayerComposite::RenderLayer(const nsIntRect& aClipRect)
|
||||
mImageHost->SetCompositor(mCompositor);
|
||||
mImageHost->Composite(effectChain,
|
||||
GetEffectiveOpacity(),
|
||||
GetEffectiveTransform(),
|
||||
GetEffectiveTransformForBuffer(),
|
||||
GetEffectFilter(),
|
||||
clipRect);
|
||||
mImageHost->BumpFlashCounter();
|
||||
@ -122,13 +122,6 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransform
|
||||
mImageHost->IsAttached()) {
|
||||
IntSize size = mImageHost->GetImageSize();
|
||||
sourceRect.SizeTo(size.width, size.height);
|
||||
if (mScaleMode != ScaleMode::SCALE_NONE &&
|
||||
sourceRect.width != 0.0 && sourceRect.height != 0.0) {
|
||||
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
|
||||
"No other scalemodes than stretch and none supported yet.");
|
||||
local.PreScale(mScaleToSize.width / sourceRect.width,
|
||||
mScaleToSize.height / sourceRect.height, 1.0);
|
||||
}
|
||||
}
|
||||
// Snap our local transform first, and snap the inherited transform as well.
|
||||
// This makes our snapping equivalent to what would happen if our content
|
||||
@ -137,6 +130,21 @@ ImageLayerComposite::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransform
|
||||
mEffectiveTransform =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
|
||||
if (mScaleMode != ScaleMode::SCALE_NONE &&
|
||||
sourceRect.width != 0.0 && sourceRect.height != 0.0) {
|
||||
NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
|
||||
"No other scalemodes than stretch and none supported yet.");
|
||||
local.PreScale(mScaleToSize.width / sourceRect.width,
|
||||
mScaleToSize.height / sourceRect.height, 1.0);
|
||||
|
||||
mEffectiveTransformForBuffer =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
} else {
|
||||
mEffectiveTransformForBuffer = mEffectiveTransform;
|
||||
}
|
||||
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,7 @@
|
||||
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
|
||||
#ifdef MOZ_METRO
|
||||
#include <DXGI1_2.h>
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -342,6 +340,7 @@ CompositorD3D11::Initialize()
|
||||
swapDesc.OutputWindow = mHwnd;
|
||||
swapDesc.Windowed = TRUE;
|
||||
swapDesc.Flags = 0;
|
||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
|
||||
|
||||
|
||||
/**
|
||||
@ -571,6 +570,10 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
|
||||
gfx::Float aOpacity,
|
||||
const gfx::Matrix4x4& aTransform)
|
||||
{
|
||||
if (mCurrentClip.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCurrentRT, "No render target");
|
||||
memcpy(&mVSConstants.layerTransform, &aTransform._11, 64);
|
||||
IntPoint origin = mCurrentRT->GetOrigin();
|
||||
@ -618,12 +621,22 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
|
||||
mVSConstants.maskQuad = maskTransform.As2D().TransformBounds(bounds);
|
||||
}
|
||||
|
||||
|
||||
D3D11_RECT scissor;
|
||||
scissor.left = aClipRect.x;
|
||||
scissor.right = aClipRect.XMost();
|
||||
scissor.top = aClipRect.y;
|
||||
scissor.bottom = aClipRect.YMost();
|
||||
|
||||
IntRect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
if (mCurrentRT == mDefaultRT) {
|
||||
clipRect = clipRect.Intersect(mCurrentClip);
|
||||
}
|
||||
|
||||
if (clipRect.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
scissor.left = clipRect.x;
|
||||
scissor.right = clipRect.XMost();
|
||||
scissor.top = clipRect.y;
|
||||
scissor.bottom = clipRect.YMost();
|
||||
|
||||
mContext->RSSetScissorRects(1, &scissor);
|
||||
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
mContext->VSSetShader(mAttachments->mVSQuadShader[maskType], nullptr, 0);
|
||||
@ -842,6 +855,14 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
UINT offset = 0;
|
||||
mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset);
|
||||
|
||||
nsIntRect intRect = nsIntRect(nsIntPoint(0, 0), mSize);
|
||||
// Sometimes the invalid region is larger than we want to draw.
|
||||
nsIntRegion invalidRegionSafe;
|
||||
invalidRegionSafe.And(aInvalidRegion, intRect);
|
||||
nsIntRect invalidRect = invalidRegionSafe.GetBounds();
|
||||
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
|
||||
mInvalidRegion = invalidRegionSafe;
|
||||
|
||||
if (aClipRectOut) {
|
||||
*aClipRectOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
@ -849,26 +870,18 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
*aRenderBoundsOut = Rect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
|
||||
D3D11_RECT scissor;
|
||||
if (aClipRectIn) {
|
||||
scissor.left = aClipRectIn->x;
|
||||
scissor.right = aClipRectIn->XMost();
|
||||
scissor.top = aClipRectIn->y;
|
||||
scissor.bottom = aClipRectIn->YMost();
|
||||
} else {
|
||||
scissor.left = scissor.top = 0;
|
||||
scissor.right = mSize.width;
|
||||
scissor.bottom = mSize.height;
|
||||
invalidRect.IntersectRect(invalidRect, nsIntRect(aClipRectIn->x, aClipRectIn->y, aClipRectIn->width, aClipRectIn->height));
|
||||
}
|
||||
mContext->RSSetScissorRects(1, &scissor);
|
||||
|
||||
FLOAT black[] = { 0, 0, 0, 0 };
|
||||
mContext->ClearRenderTargetView(mDefaultRT->mRTView, black);
|
||||
mCurrentClip = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
|
||||
|
||||
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
|
||||
mContext->RSSetState(mAttachments->mRasterizerState);
|
||||
|
||||
SetRenderTarget(mDefaultRT);
|
||||
|
||||
// ClearRect will set the correct blend state for us.
|
||||
ClearRect(Rect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height));
|
||||
}
|
||||
|
||||
void
|
||||
@ -879,7 +892,33 @@ CompositorD3D11::EndFrame()
|
||||
nsIntSize oldSize = mSize;
|
||||
EnsureSize();
|
||||
if (oldSize == mSize) {
|
||||
mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
|
||||
RefPtr<IDXGISwapChain1> chain;
|
||||
HRESULT hr = mSwapChain->QueryInterface((IDXGISwapChain1**)byRef(chain));
|
||||
if (SUCCEEDED(hr) && chain) {
|
||||
DXGI_PRESENT_PARAMETERS params;
|
||||
PodZero(¶ms);
|
||||
params.DirtyRectsCount = mInvalidRegion.GetNumRects();
|
||||
std::vector<RECT> rects;
|
||||
rects.reserve(params.DirtyRectsCount);
|
||||
|
||||
nsIntRegionRectIterator iter(mInvalidRegion);
|
||||
const nsIntRect* r;
|
||||
uint32_t i = 0;
|
||||
while ((r = iter.Next()) != nullptr) {
|
||||
RECT rect;
|
||||
rect.left = r->x;
|
||||
rect.top = r->y;
|
||||
rect.bottom = r->YMost();
|
||||
rect.right = r->XMost();
|
||||
|
||||
rects.push_back(rect);
|
||||
}
|
||||
|
||||
params.pDirtyRects = &rects.front();
|
||||
chain->Present1(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0, ¶ms);
|
||||
} else {
|
||||
mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
|
||||
}
|
||||
mDisableSequenceForNextFrame = false;
|
||||
if (mTarget) {
|
||||
PaintToTarget();
|
||||
|
@ -184,6 +184,11 @@ private:
|
||||
VertexShaderConstants mVSConstants;
|
||||
PixelShaderConstants mPSConstants;
|
||||
bool mDisableSequenceForNextFrame;
|
||||
|
||||
gfx::IntRect mInvalidRect;
|
||||
// This is the clip rect applied to the default DrawTarget (i.e. the window)
|
||||
gfx::IntRect mCurrentClip;
|
||||
nsIntRegion mInvalidRegion;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -2184,6 +2184,10 @@ InitLayersAccelerationPrefs()
|
||||
sLayersSupportsD3D11 = true;
|
||||
}
|
||||
}
|
||||
if (!gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
// Always support D3D11 when WARP is allowed.
|
||||
sLayersSupportsD3D11 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -301,6 +301,8 @@ private:
|
||||
DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.testing.enabled", LayersOffMainThreadCompositionTestingEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0);
|
||||
DECL_GFX_PREF(Once, "layers.d3d11.disable-warp", LayersD3D11DisableWARP, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.d3d11.force-warp", LayersD3D11ForceWARP, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.prefer-d3d9", LayersPreferD3D9, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.prefer-opengl", LayersPreferOpenGL, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.progressive-paint", ProgressivePaintDoNotUseDirectly, bool, false);
|
||||
|
@ -344,12 +344,12 @@ gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
#endif
|
||||
RegisterStrongMemoryReporter(new GfxD2DVramReporter());
|
||||
|
||||
UpdateRenderMode();
|
||||
|
||||
if (gfxPrefs::Direct2DUse1_1()) {
|
||||
InitD3D11Devices();
|
||||
}
|
||||
|
||||
UpdateRenderMode();
|
||||
|
||||
RegisterStrongMemoryReporter(new GPUAdapterReporter());
|
||||
}
|
||||
|
||||
@ -487,7 +487,8 @@ gfxWindowsPlatform::UpdateRenderMode()
|
||||
canvasMask |= BackendTypeBit(BackendType::DIRECT2D);
|
||||
contentMask |= BackendTypeBit(BackendType::DIRECT2D);
|
||||
#ifdef USE_D2D1_1
|
||||
if (gfxPrefs::Direct2DUse1_1() && Factory::SupportsD2D1()) {
|
||||
if (gfxPrefs::Direct2DUse1_1() && Factory::SupportsD2D1() &&
|
||||
GetD3D11ContentDevice()) {
|
||||
contentMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
|
||||
canvasMask |= BackendTypeBit(BackendType::DIRECT2D1_1);
|
||||
defaultBackend = BackendType::DIRECT2D1_1;
|
||||
@ -1697,23 +1698,45 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
|
||||
void
|
||||
gfxWindowsPlatform::InitD3D11Devices()
|
||||
{
|
||||
// This function attempts to initialize our D3D11 devices. If the hardware
|
||||
// is not blacklisted for D3D11 layers. This will first attempt to create a
|
||||
// hardware accelerated device. If this creation fails or the hardware is
|
||||
// blacklisted, then this function will abort if WARP is disabled, causing us
|
||||
// to fallback to D3D9 or Basic layers. If WARP is not disabled it will use
|
||||
// a WARP device which should always be available on Windows 7 and higher.
|
||||
|
||||
mD3D11DeviceInitialized = true;
|
||||
|
||||
MOZ_ASSERT(!mD3D11Device);
|
||||
|
||||
bool useWARP = false;
|
||||
ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
if (gfxInfo) {
|
||||
int32_t status;
|
||||
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &status))) {
|
||||
if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
|
||||
return;
|
||||
|
||||
if (gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
return;
|
||||
}
|
||||
|
||||
useWARP = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gfxPrefs::LayersD3D11ForceWARP()) {
|
||||
useWARP = true;
|
||||
}
|
||||
|
||||
nsModuleHandle d3d11Module(LoadLibrarySystem32(L"d3d11.dll"));
|
||||
decltype(D3D11CreateDevice)* d3d11CreateDevice = (decltype(D3D11CreateDevice)*)
|
||||
GetProcAddress(d3d11Module, "D3D11CreateDevice");
|
||||
|
||||
if (!d3d11CreateDevice) {
|
||||
// We should just be on Windows Vista or XP in this case.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1726,51 +1749,92 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||
featureLevels.AppendElement(D3D_FEATURE_LEVEL_10_0);
|
||||
featureLevels.AppendElement(D3D_FEATURE_LEVEL_9_3);
|
||||
|
||||
RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
|
||||
RefPtr<IDXGIAdapter1> adapter;
|
||||
|
||||
if (!adapter) {
|
||||
return;
|
||||
if (!useWARP) {
|
||||
adapter = GetDXGIAdapter();
|
||||
|
||||
if (!adapter) {
|
||||
if (!gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
return;
|
||||
}
|
||||
useWARP = true;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
MOZ_SEH_TRY {
|
||||
hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
|
||||
|
||||
if (!useWARP) {
|
||||
MOZ_SEH_TRY {
|
||||
hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
|
||||
// Use
|
||||
// D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
|
||||
// to prevent bug 1092260. IE 11 also uses this flag.
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
||||
featureLevels.Elements(), featureLevels.Length(),
|
||||
D3D11_SDK_VERSION, byRef(mD3D11Device), nullptr, nullptr);
|
||||
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
|
||||
if (gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
return;
|
||||
}
|
||||
|
||||
useWARP = true;
|
||||
adapter = nullptr;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
if (gfxPrefs::LayersD3D11DisableWARP()) {
|
||||
return;
|
||||
}
|
||||
|
||||
useWARP = true;
|
||||
adapter = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (useWARP) {
|
||||
MOZ_ASSERT(!gfxPrefs::LayersD3D11DisableWARP());
|
||||
MOZ_ASSERT(!mD3D11Device);
|
||||
MOZ_ASSERT(!adapter);
|
||||
|
||||
hr = d3d11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
|
||||
// Use
|
||||
// D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
|
||||
// to prevent bug 1092260. IE 11 also uses this flag.
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
||||
featureLevels.Elements(), featureLevels.Length(),
|
||||
D3D11_SDK_VERSION, byRef(mD3D11Device),
|
||||
nullptr, nullptr);
|
||||
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
|
||||
mD3D11Device = nullptr;
|
||||
return;
|
||||
}
|
||||
D3D11_SDK_VERSION, byRef(mD3D11Device), nullptr, nullptr);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
mD3D11Device = nullptr;
|
||||
return;
|
||||
if (FAILED(hr)) {
|
||||
// This should always succeed... in theory.
|
||||
gfxCriticalError() << "Failed to initialize WARP D3D11 device!" << hr;
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
reporterWARP.SetSuccessful();
|
||||
}
|
||||
|
||||
mD3D11Device->SetExceptionMode(0);
|
||||
|
||||
#ifdef USE_D2D1_1
|
||||
if (Factory::SupportsD2D1()) {
|
||||
// We create our device for D2D content drawing here. Normally we don't use
|
||||
// D2D content drawing when using WARP. However when WARP is forced by
|
||||
// default we will let Direct2D use WARP as well.
|
||||
if (Factory::SupportsD2D1() && (!useWARP || gfxPrefs::LayersD3D11ForceWARP())) {
|
||||
MOZ_ASSERT((useWARP && !adapter) || !useWARP);
|
||||
|
||||
hr = E_INVALIDARG;
|
||||
MOZ_SEH_TRY {
|
||||
hr = d3d11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
|
||||
hr = d3d11CreateDevice(adapter, useWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN, nullptr,
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
||||
featureLevels.Elements(), featureLevels.Length(),
|
||||
D3D11_SDK_VERSION, byRef(mD3D11ContentDevice),
|
||||
nullptr, nullptr);
|
||||
D3D11_SDK_VERSION, byRef(mD3D11ContentDevice), nullptr, nullptr);
|
||||
} MOZ_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) {
|
||||
mD3D11Device = nullptr;
|
||||
return;
|
||||
mD3D11ContentDevice = nullptr;
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
mD3D11Device = nullptr;
|
||||
d3d11Module.disown();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -13,90 +13,101 @@
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
// Declared in imgRequest.cpp.
|
||||
extern PRLogModuleInfo *GetImgLog();
|
||||
extern PRLogModuleInfo* GetImgLog();
|
||||
|
||||
#define GIVE_ME_MS_NOW() PR_IntervalToMilliseconds(PR_IntervalNow())
|
||||
|
||||
class LogScope {
|
||||
public:
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
|
||||
LogScope(PRLogModuleInfo* aLog, void* aFrom, const char* aFunc)
|
||||
: mLog(aLog)
|
||||
, mFrom(aFrom)
|
||||
, mFunc(aFunc)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc));
|
||||
}
|
||||
|
||||
/* const char * constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const char *paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
LogScope(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, const char* paramValue)
|
||||
: mLog(aLog)
|
||||
, mFrom(from)
|
||||
, mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\") {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
/* void ptr constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const void *paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
LogScope(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, const void* paramValue)
|
||||
: mLog(aLog)
|
||||
, mFrom(from)
|
||||
, mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=%p) {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
/* int32_t constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, int32_t paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
LogScope(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, int32_t paramValue)
|
||||
: mLog(aLog)
|
||||
, mFrom(from)
|
||||
, mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
/* uint32_t constructor */
|
||||
LogScope(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, uint32_t paramValue) :
|
||||
mLog(aLog), mFrom(from), mFunc(fn)
|
||||
LogScope(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, uint32_t paramValue)
|
||||
: mLog(aLog)
|
||||
, mFrom(from)
|
||||
, mFunc(fn)
|
||||
{
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\") {ENTER}\n",
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
|
||||
~LogScope() {
|
||||
PR_LOG(mLog, PR_LOG_DEBUG, ("%d [this=%p] %s {EXIT}\n",
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc));
|
||||
GIVE_ME_MS_NOW(), mFrom, mFunc));
|
||||
}
|
||||
|
||||
private:
|
||||
PRLogModuleInfo *mLog;
|
||||
void *mFrom;
|
||||
const char *mFunc;
|
||||
PRLogModuleInfo* mLog;
|
||||
void* mFrom;
|
||||
const char* mFunc;
|
||||
};
|
||||
|
||||
|
||||
class LogFunc {
|
||||
public:
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn)
|
||||
LogFunc(PRLogModuleInfo* aLog, void* from, const char* fn)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s\n",
|
||||
GIVE_ME_MS_NOW(), from, fn));
|
||||
}
|
||||
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const char *paramValue)
|
||||
LogFunc(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, const char* paramValue)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%s\")\n",
|
||||
GIVE_ME_MS_NOW(), from, fn,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, const void *paramValue)
|
||||
LogFunc(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, const void* paramValue)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%p\")\n",
|
||||
GIVE_ME_MS_NOW(), from, fn,
|
||||
@ -104,12 +115,11 @@ public:
|
||||
}
|
||||
|
||||
|
||||
LogFunc(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *paramName, uint32_t paramValue)
|
||||
LogFunc(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* paramName, uint32_t paramValue)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s (%s=\"%d\")\n",
|
||||
GIVE_ME_MS_NOW(), from,
|
||||
fn,
|
||||
GIVE_ME_MS_NOW(), from, fn,
|
||||
paramName, paramValue));
|
||||
}
|
||||
|
||||
@ -118,8 +128,8 @@ public:
|
||||
|
||||
class LogMessage {
|
||||
public:
|
||||
LogMessage(PRLogModuleInfo *aLog, void *from, const char *fn,
|
||||
const char *msg)
|
||||
LogMessage(PRLogModuleInfo* aLog, void* from, const char* fn,
|
||||
const char* msg)
|
||||
{
|
||||
PR_LOG(aLog, PR_LOG_DEBUG, ("%d [this=%p] %s -- %s\n",
|
||||
GIVE_ME_MS_NOW(), from, fn, msg));
|
||||
@ -127,8 +137,10 @@ public:
|
||||
};
|
||||
|
||||
#define LOG_SCOPE_APPEND_LINE_NUMBER_PASTE(id, line) id ## line
|
||||
#define LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, line) LOG_SCOPE_APPEND_LINE_NUMBER_PASTE(id, line)
|
||||
#define LOG_SCOPE_APPEND_LINE_NUMBER(id) LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
|
||||
#define LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, line) \
|
||||
LOG_SCOPE_APPEND_LINE_NUMBER_PASTE(id, line)
|
||||
#define LOG_SCOPE_APPEND_LINE_NUMBER(id) \
|
||||
LOG_SCOPE_APPEND_LINE_NUMBER_EXPAND(id, __LINE__)
|
||||
|
||||
#define LOG_SCOPE(l, s) \
|
||||
LogScope LOG_SCOPE_APPEND_LINE_NUMBER(LOG_SCOPE_TMP_VAR) (l, this, s)
|
||||
|
@ -32,17 +32,19 @@ interface imgICache : nsISupports
|
||||
* Evict images from the cache.
|
||||
*
|
||||
* @param uri The URI to remove.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE if \a uri was unable to be removed from the cache.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE if \a uri was unable to be removed from
|
||||
* the cache.
|
||||
*/
|
||||
void removeEntry(in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Find Properties
|
||||
* Used to get properties such as 'type' and 'content-disposition'
|
||||
* 'type' is a nsISupportsCString containing the images' mime type such as 'image/png'
|
||||
* 'type' is a nsISupportsCString containing the images' mime type such as
|
||||
* 'image/png'
|
||||
* 'content-disposition' will be a nsISupportsCString containing the header
|
||||
* If you call this before any data has been loaded from a URI, it will succeed,
|
||||
* but come back empty.
|
||||
* If you call this before any data has been loaded from a URI, it will
|
||||
* succeed, but come back empty.
|
||||
*
|
||||
* Hopefully this will be removed with bug 805119
|
||||
*
|
||||
@ -52,9 +54,9 @@ interface imgICache : nsISupports
|
||||
nsIProperties findEntryProperties(in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Make this cache instance respect private browsing notifications. This entails clearing
|
||||
* the chrome and content caches whenever the last-pb-context-exited notification is
|
||||
* observed.
|
||||
* Make this cache instance respect private browsing notifications. This
|
||||
* entails clearing the chrome and content caches whenever the
|
||||
* last-pb-context-exited notification is observed.
|
||||
*/
|
||||
void respectPrivacyNotifications();
|
||||
};
|
||||
|
@ -92,8 +92,8 @@ interface imgIContainer : nsISupports
|
||||
[noscript] readonly attribute nsSize intrinsicSize;
|
||||
|
||||
/**
|
||||
* The (dimensionless) intrinsic ratio of this image. In the case of any error,
|
||||
* an exception will be thrown.
|
||||
* The (dimensionless) intrinsic ratio of this image. In the case of any
|
||||
* error, an exception will be thrown.
|
||||
*/
|
||||
[noscript] readonly attribute nsSize intrinsicRatio;
|
||||
|
||||
@ -113,10 +113,9 @@ interface imgIContainer : nsISupports
|
||||
* @param aFilter The filter to be used if we're scaling the image.
|
||||
* @param aFlags Flags of the FLAG_* variety
|
||||
*/
|
||||
[notxpcom, nostdcall] nsIntSizeByVal optimalImageSizeForDest([const] in gfxSize aDest,
|
||||
in uint32_t aWhichFrame,
|
||||
in gfxGraphicsFilter aFilter,
|
||||
in uint32_t aFlags);
|
||||
[notxpcom, nostdcall] nsIntSizeByVal
|
||||
optimalImageSizeForDest([const] in gfxSize aDest, in uint32_t aWhichFrame,
|
||||
in gfxGraphicsFilter aFilter, in uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Enumerated values for the 'type' attribute (below).
|
||||
@ -158,8 +157,8 @@ interface imgIContainer : nsISupports
|
||||
* it's not already premultiplied in the image data.
|
||||
*
|
||||
* FLAG_DECODE_NO_COLORSPACE_CONVERSION: Do not do any colorspace conversion;
|
||||
* ignore any embedded profiles, and don't convert to any particular destination
|
||||
* space.
|
||||
* ignore any embedded profiles, and don't convert to any particular
|
||||
* destination space.
|
||||
*
|
||||
* FLAG_CLAMP: Extend the image to the fill area by clamping image sample
|
||||
* coordinates instead of by tiling. This only affects 'draw'.
|
||||
@ -316,9 +315,10 @@ interface imgIContainer : nsISupports
|
||||
* includes FLAG_CLAMP, the image will be extended to this area
|
||||
* by clamping image sample coordinates. Otherwise, the image
|
||||
* will be automatically tiled as necessary. aRegion can also
|
||||
* optionally contain a second region which restricts the set of
|
||||
* pixels we're allowed to sample from when drawing; this is
|
||||
* only of use to callers which need to draw with pixel snapping.
|
||||
* optionally contain a second region which restricts the set
|
||||
* of pixels we're allowed to sample from when drawing; this
|
||||
* is only of use to callers which need to draw with pixel
|
||||
* snapping.
|
||||
* @param aWhichFrame Frame specifier of the FRAME_* variety.
|
||||
* @param aFilter The filter to be used if we're scaling the image.
|
||||
* @param aSVGContext If specified, SVG-related rendering context, such as
|
||||
@ -345,7 +345,8 @@ interface imgIContainer : nsISupports
|
||||
void requestDecode();
|
||||
|
||||
/*
|
||||
* This is equivalent to requestDecode() but it also decodes some of the image.
|
||||
* This is equivalent to requestDecode() but it also decodes some of the
|
||||
* image.
|
||||
*/
|
||||
[noscript] void startDecoding();
|
||||
|
||||
@ -456,7 +457,8 @@ interface imgIContainer : nsISupports
|
||||
* differ if the image is wrapped by an ImageWrapper that changes its size
|
||||
* or orientation.
|
||||
*/
|
||||
[notxpcom] nsIntRectByVal getImageSpaceInvalidationRect([const] in nsIntRect aRect);
|
||||
[notxpcom] nsIntRectByVal
|
||||
getImageSpaceInvalidationRect([const] in nsIntRect aRect);
|
||||
|
||||
/*
|
||||
* Removes any ImageWrappers and returns the unwrapped base image.
|
||||
|
@ -28,23 +28,25 @@ interface imgIEncoder : nsIAsyncInputStream
|
||||
// transparency=[yes|no|none] -- default: "yes"
|
||||
// Overrides default from input format. "no" and "none" are equivalent.
|
||||
// skipfirstframe=[yes|no] -- default: "no"
|
||||
// Controls display of the first frame in animations. PNG-only clients always
|
||||
// display the first frame (and only that frame).
|
||||
// Controls display of the first frame in animations. PNG-only clients
|
||||
// always display the first frame (and only that frame).
|
||||
// frames=# -- default: "1"
|
||||
// Total number of frames in the image. The first frame, even if skipped, is
|
||||
// always included in the count.
|
||||
// Total number of frames in the image. The first frame, even if skipped,
|
||||
// is always included in the count.
|
||||
// plays=# -- default: "0"
|
||||
// Number of times to play the animation sequence. "0" will repeat forever.
|
||||
//
|
||||
// Number of times to play the animation sequence. "0" will repeat
|
||||
// forever.
|
||||
//
|
||||
// The following options can be used for each frame, with addImageFrame():
|
||||
//
|
||||
// transparency=[yes|no|none] -- default: "yes"
|
||||
// Overrides default from input format. "no" and "none" are equivalent.
|
||||
// delay=# -- default: "500"
|
||||
// Number of milliseconds to display the frame, before moving to the next frame.
|
||||
// Number of milliseconds to display the frame, before moving to the next
|
||||
// frame.
|
||||
// dispose=[none|background|previous] -- default: "none"
|
||||
// What to do with the image's canvas before rendering the next frame. See APNG spec.
|
||||
// What to do with the image's canvas before rendering the next frame.
|
||||
// See APNG spec.
|
||||
// blend=[source|over] -- default: "source"
|
||||
// How to render the new frame on the canvas. See APNG spec.
|
||||
// xoffset=# -- default: "0"
|
||||
@ -56,7 +58,7 @@ interface imgIEncoder : nsIAsyncInputStream
|
||||
// -----
|
||||
//
|
||||
// quality=# -- default: "92"
|
||||
// Quality of compression, 0-100 (worst-best).
|
||||
// Quality of compression, 0-100 (worst-best).
|
||||
// Quality >= 90 prevents down-sampling of the color channels.
|
||||
|
||||
|
||||
|
@ -38,7 +38,8 @@ interface imgILoader : nsISupports
|
||||
/**
|
||||
* Start the load and decode of an image.
|
||||
* @param aURI the URI to load
|
||||
* @param aInitialDocumentURI the URI that 'initiated' the load -- used for 3rd party cookie blocking
|
||||
* @param aInitialDocumentURI the URI that 'initiated' the load -- used for
|
||||
* 3rd party cookie blocking
|
||||
* @param aReferrerURI the 'referring' URI
|
||||
* @param aReferrerPolicy the policy to apply to sending referrers.
|
||||
* examples: "default", "never", "always", "origin"
|
||||
@ -81,10 +82,10 @@ interface imgILoader : nsISupports
|
||||
* @param aObserver the observer (may be null)
|
||||
* @param cx some random data
|
||||
* @param aListener [out]
|
||||
* A listener that you must send the channel's notifications and data to.
|
||||
* Can be null, in which case imagelib has found a cached image and is
|
||||
* not interested in the data. @aChannel will be canceled for you in
|
||||
* this case.
|
||||
* A listener that you must send the channel's notifications and data
|
||||
* to. Can be null, in which case imagelib has found a cached image
|
||||
* and is not interested in the data. @aChannel will be canceled for
|
||||
* you in this case.
|
||||
*
|
||||
* ImageLib does NOT keep a strong ref to the observer; this prevents
|
||||
* reference cycles. This means that callers of loadImageWithChannel should
|
||||
|
@ -53,5 +53,6 @@ interface imgINotificationObserver : nsISupports
|
||||
// The image is transparent.
|
||||
const long HAS_TRANSPARENCY = 9;
|
||||
|
||||
[noscript] void notify(in imgIRequest aProxy, in long aType, [const] in nsIntRect aRect);
|
||||
[noscript] void notify(in imgIRequest aProxy, in long aType,
|
||||
[const] in nsIntRect aRect);
|
||||
};
|
||||
|
@ -133,7 +133,7 @@ interface imgIRequest : nsIRequest
|
||||
//@}
|
||||
|
||||
/**
|
||||
* The CORS mode that this image was loaded with.
|
||||
* The CORS mode that this image was loaded with.
|
||||
*/
|
||||
readonly attribute long CORSMode;
|
||||
|
||||
@ -195,14 +195,16 @@ interface imgIRequest : nsIRequest
|
||||
/**
|
||||
* Requests that the image animate (if it has an animation).
|
||||
*
|
||||
* @see Image::IncrementAnimationConsumers for documentation of the underlying call.
|
||||
* @see Image::IncrementAnimationConsumers for documentation of the
|
||||
* underlying call.
|
||||
*/
|
||||
void incrementAnimationConsumers();
|
||||
|
||||
/**
|
||||
* Tell the image it can forget about a request that the image animate.
|
||||
*
|
||||
* @see Image::DecrementAnimationConsumers for documentation of the underlying call.
|
||||
* @see Image::DecrementAnimationConsumers for documentation of the
|
||||
* underlying call.
|
||||
*/
|
||||
void decrementAnimationConsumers();
|
||||
};
|
||||
|
@ -145,7 +145,8 @@ interface imgITools : nsISupports
|
||||
* Create a wrapper around a scripted notification observer (ordinarily
|
||||
* imgINotificationObserver cannot be implemented from scripts).
|
||||
*
|
||||
* @param aObserver The scripted observer to wrap
|
||||
* @param aObserver The scripted observer to wrap
|
||||
*/
|
||||
imgINotificationObserver createScriptedObserver(in imgIScriptedNotificationObserver aObserver);
|
||||
imgINotificationObserver
|
||||
createScriptedObserver(in imgIScriptedNotificationObserver aObserver);
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
eDecoderType_icon = 5,
|
||||
eDecoderType_unknown = 6
|
||||
};
|
||||
static eDecoderType GetDecoderType(const char *aMimeType);
|
||||
static eDecoderType GetDecoderType(const char* aMimeType);
|
||||
|
||||
/**
|
||||
* Flags for Image initialization.
|
||||
@ -77,7 +77,8 @@ public:
|
||||
* If MallocSizeOf does not work on this platform, uses a fallback approach to
|
||||
* ensure that something reasonable is always returned.
|
||||
*/
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const = 0;
|
||||
virtual size_t SizeOfSourceWithComputedFallback(
|
||||
MallocSizeOf aMallocSizeOf) const = 0;
|
||||
|
||||
/**
|
||||
* The size, in bytes, occupied by the image's decoded data.
|
||||
@ -145,12 +146,16 @@ public:
|
||||
class ImageResource : public Image
|
||||
{
|
||||
public:
|
||||
already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE {
|
||||
already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE
|
||||
{
|
||||
nsRefPtr<ProgressTracker> progressTracker = mProgressTracker;
|
||||
MOZ_ASSERT(progressTracker);
|
||||
return progressTracker.forget();
|
||||
}
|
||||
void SetProgressTracker(ProgressTracker* aProgressTracker) MOZ_OVERRIDE MOZ_FINAL {
|
||||
|
||||
void SetProgressTracker(
|
||||
ProgressTracker* aProgressTracker) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
MOZ_ASSERT(aProgressTracker);
|
||||
MOZ_ASSERT(!mProgressTracker);
|
||||
mProgressTracker = aProgressTracker;
|
||||
@ -159,12 +164,16 @@ public:
|
||||
virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
#ifdef DEBUG
|
||||
virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE { return mAnimationConsumers; }
|
||||
virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE
|
||||
{
|
||||
return mAnimationConsumers;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void OnSurfaceDiscarded() MOZ_OVERRIDE { }
|
||||
|
||||
virtual void SetInnerWindowID(uint64_t aInnerWindowId) MOZ_OVERRIDE {
|
||||
virtual void SetInnerWindowID(uint64_t aInnerWindowId) MOZ_OVERRIDE
|
||||
{
|
||||
mInnerWindowId = aInnerWindowId;
|
||||
}
|
||||
virtual uint64_t InnerWindowID() const MOZ_OVERRIDE { return mInnerWindowId; }
|
||||
@ -183,7 +192,7 @@ protected:
|
||||
|
||||
// Shared functionality for implementors of imgIContainer. Every
|
||||
// implementation of attribute animationMode should forward here.
|
||||
nsresult GetAnimationModeInternal(uint16_t *aAnimationMode);
|
||||
nsresult GetAnimationModeInternal(uint16_t* aAnimationMode);
|
||||
nsresult SetAnimationModeInternal(uint16_t aAnimationMode);
|
||||
|
||||
/**
|
||||
|
@ -38,7 +38,8 @@ public:
|
||||
* @param aClip The rectangle to clip the image against.
|
||||
*/
|
||||
static already_AddRefed<Image> Clip(Image* aImage, nsIntRect aClip);
|
||||
static already_AddRefed<imgIContainer> Clip(imgIContainer* aImage, nsIntRect aClip);
|
||||
static already_AddRefed<imgIContainer> Clip(imgIContainer* aImage,
|
||||
nsIntRect aClip);
|
||||
|
||||
/**
|
||||
* Creates a version of an existing image which is rotated and/or flipped to
|
||||
@ -47,15 +48,18 @@ public:
|
||||
* @param aImage The existing image.
|
||||
* @param aOrientation The desired orientation.
|
||||
*/
|
||||
static already_AddRefed<Image> Orient(Image* aImage, Orientation aOrientation);
|
||||
static already_AddRefed<imgIContainer> Orient(imgIContainer* aImage, Orientation aOrientation);
|
||||
static already_AddRefed<Image> Orient(Image* aImage,
|
||||
Orientation aOrientation);
|
||||
static already_AddRefed<imgIContainer> Orient(imgIContainer* aImage,
|
||||
Orientation aOrientation);
|
||||
|
||||
/**
|
||||
* Creates an image from a gfxDrawable.
|
||||
*
|
||||
* @param aDrawable The gfxDrawable.
|
||||
*/
|
||||
static already_AddRefed<imgIContainer> CreateFromDrawable(gfxDrawable* aDrawable);
|
||||
static already_AddRefed<imgIContainer>
|
||||
CreateFromDrawable(gfxDrawable* aDrawable);
|
||||
|
||||
private:
|
||||
// This is a static utility class, so disallow instantiation.
|
||||
|
@ -28,7 +28,8 @@ namespace image {
|
||||
class ImageURL
|
||||
{
|
||||
public:
|
||||
explicit ImageURL(nsIURI* aURI) {
|
||||
explicit ImageURL(nsIURI* aURI)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!");
|
||||
aURI->GetSpec(mSpec);
|
||||
aURI->GetScheme(mScheme);
|
||||
@ -37,17 +38,19 @@ public:
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageURL)
|
||||
|
||||
nsresult GetSpec(nsACString &result) {
|
||||
nsresult GetSpec(nsACString& result)
|
||||
{
|
||||
result = mSpec;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetScheme(nsACString &result) {
|
||||
nsresult GetScheme(nsACString& result)
|
||||
{
|
||||
result = mScheme;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult SchemeIs(const char *scheme, bool *result)
|
||||
nsresult SchemeIs(const char* scheme, bool* result)
|
||||
{
|
||||
NS_PRECONDITION(scheme, "scheme is null");
|
||||
NS_PRECONDITION(result, "result is null");
|
||||
@ -56,12 +59,14 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetRef(nsACString &result) {
|
||||
nsresult GetRef(nsACString& result)
|
||||
{
|
||||
result = mRef;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI> ToIURI() {
|
||||
already_AddRefed<nsIURI> ToIURI()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(),
|
||||
"Convert to nsIURI on main thread only; it is not threadsafe.");
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
@ -79,7 +84,7 @@ private:
|
||||
nsAutoCString mScheme;
|
||||
nsAutoCString mRef;
|
||||
|
||||
~ImageURL() {}
|
||||
~ImageURL() { }
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
|
@ -93,7 +93,8 @@ ImageWrapper::OnImageDataComplete(nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
bool aLastPart)
|
||||
{
|
||||
return mInnerImage->OnImageDataComplete(aRequest, aContext, aStatus, aLastPart);
|
||||
return mInnerImage->OnImageDataComplete(aRequest, aContext, aStatus,
|
||||
aLastPart);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -204,7 +205,8 @@ ImageWrapper::IsOpaque()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageWrapper::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
|
||||
ImageWrapper::GetImageContainer(LayerManager* aManager,
|
||||
ImageContainer** _retval)
|
||||
{
|
||||
return mInnerImage->GetImageContainer(aManager, _retval);
|
||||
}
|
||||
@ -305,10 +307,12 @@ ImageWrapper::SetAnimationStartTime(const TimeStamp& aTime)
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
ImageWrapper::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
|
||||
ImageWrapper::OptimalImageSizeForDest(const gfxSize& aDest,
|
||||
uint32_t aWhichFrame,
|
||||
GraphicsFilter aFilter, uint32_t aFlags)
|
||||
{
|
||||
return mInnerImage->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags);
|
||||
return mInnerImage->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter,
|
||||
aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsIntRect)
|
||||
|
@ -27,8 +27,12 @@ public:
|
||||
virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
|
||||
virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
|
||||
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t
|
||||
SizeOfSourceWithComputedFallback( MallocSizeOf aMallocSizeOf) const
|
||||
MOZ_OVERRIDE;
|
||||
virtual size_t
|
||||
SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
|
||||
virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
|
@ -136,8 +136,7 @@ BackgroundChildImpl::DeallocPBackgroundTestChild(PBackgroundTestChild* aActor)
|
||||
}
|
||||
|
||||
BackgroundChildImpl::PBackgroundIDBFactoryChild*
|
||||
BackgroundChildImpl::AllocPBackgroundIDBFactoryChild(
|
||||
const OptionalWindowId& aOptionalWindowId)
|
||||
BackgroundChildImpl::AllocPBackgroundIDBFactoryChild()
|
||||
{
|
||||
MOZ_CRASH("PBackgroundIDBFactoryChild actors should be manually "
|
||||
"constructed!");
|
||||
|
@ -53,8 +53,7 @@ protected:
|
||||
DeallocPBackgroundTestChild(PBackgroundTestChild* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBackgroundIDBFactoryChild*
|
||||
AllocPBackgroundIDBFactoryChild(const OptionalWindowId& aOptionalWindowId)
|
||||
MOZ_OVERRIDE;
|
||||
AllocPBackgroundIDBFactoryChild() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
DeallocPBackgroundIDBFactoryChild(PBackgroundIDBFactoryChild* aActor)
|
||||
|
@ -119,8 +119,7 @@ BackgroundParentImpl::DeallocPBackgroundTestParent(
|
||||
}
|
||||
|
||||
auto
|
||||
BackgroundParentImpl::AllocPBackgroundIDBFactoryParent(
|
||||
const OptionalWindowId& aOptionalWindowId)
|
||||
BackgroundParentImpl::AllocPBackgroundIDBFactoryParent()
|
||||
-> PBackgroundIDBFactoryParent*
|
||||
{
|
||||
using mozilla::dom::indexedDB::AllocPBackgroundIDBFactoryParent;
|
||||
@ -128,13 +127,12 @@ BackgroundParentImpl::AllocPBackgroundIDBFactoryParent(
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return AllocPBackgroundIDBFactoryParent(this, aOptionalWindowId);
|
||||
return AllocPBackgroundIDBFactoryParent();
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::RecvPBackgroundIDBFactoryConstructor(
|
||||
PBackgroundIDBFactoryParent* aActor,
|
||||
const OptionalWindowId& aOptionalWindowId)
|
||||
PBackgroundIDBFactoryParent* aActor)
|
||||
{
|
||||
using mozilla::dom::indexedDB::RecvPBackgroundIDBFactoryConstructor;
|
||||
|
||||
@ -142,7 +140,7 @@ BackgroundParentImpl::RecvPBackgroundIDBFactoryConstructor(
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
return RecvPBackgroundIDBFactoryConstructor(this, aActor, aOptionalWindowId);
|
||||
return RecvPBackgroundIDBFactoryConstructor(aActor);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -33,14 +33,11 @@ protected:
|
||||
DeallocPBackgroundTestParent(PBackgroundTestParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PBackgroundIDBFactoryParent*
|
||||
AllocPBackgroundIDBFactoryParent(const OptionalWindowId& aOptionalWindowId)
|
||||
MOZ_OVERRIDE;
|
||||
AllocPBackgroundIDBFactoryParent() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvPBackgroundIDBFactoryConstructor(
|
||||
PBackgroundIDBFactoryParent* aActor,
|
||||
const OptionalWindowId& aOptionalWindowId)
|
||||
MOZ_OVERRIDE;
|
||||
RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
DeallocPBackgroundIDBFactoryParent(PBackgroundIDBFactoryParent* aActor)
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Move.h"
|
||||
@ -79,6 +81,8 @@
|
||||
using namespace mozilla;
|
||||
using namespace std;
|
||||
|
||||
using mozilla::dom::AutoNoJSAPI;
|
||||
using mozilla::dom::ScriptSettingsInitialized;
|
||||
using mozilla::MonitorAutoLock;
|
||||
using mozilla::MonitorAutoUnlock;
|
||||
|
||||
@ -1058,6 +1062,9 @@ MessageChannel::OnMaybeDequeueOne()
|
||||
void
|
||||
MessageChannel::DispatchMessage(const Message &aMsg)
|
||||
{
|
||||
Maybe<AutoNoJSAPI> nojsapi;
|
||||
if (ScriptSettingsInitialized() && NS_IsMainThread())
|
||||
nojsapi.emplace();
|
||||
if (aMsg.is_sync())
|
||||
DispatchSyncMessage(aMsg);
|
||||
else if (aMsg.is_interrupt())
|
||||
|
@ -9,22 +9,7 @@ include protocol PFileDescriptorSet;
|
||||
|
||||
include DOMTypes;
|
||||
|
||||
using struct mozilla::void_t
|
||||
from "ipc/IPCMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace indexedDB {
|
||||
|
||||
union OptionalWindowId
|
||||
{
|
||||
uint64_t;
|
||||
void_t;
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
|
||||
sync protocol PBackground
|
||||
@ -38,7 +23,7 @@ parent:
|
||||
// Only called at startup during mochitests to check the basic infrastructure.
|
||||
PBackgroundTest(nsCString testArg);
|
||||
|
||||
PBackgroundIDBFactory(OptionalWindowId optionalWindowId);
|
||||
PBackgroundIDBFactory();
|
||||
|
||||
both:
|
||||
PBlob(BlobConstructorParams params);
|
||||
|
@ -759,7 +759,7 @@ CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
|
||||
// returns a primary type, which is the case for all asm.js exported
|
||||
// functions, the returned value is discarded and an empty object is
|
||||
// returned instead.
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &JSObject::class_);
|
||||
PlainObject *obj = NewBuiltinClassInstance<PlainObject>(cx);
|
||||
callArgs.rval().set(ObjectValue(*obj));
|
||||
return true;
|
||||
}
|
||||
@ -997,7 +997,7 @@ CreateExportObject(JSContext *cx, Handle<AsmJSModuleObject*> moduleObj)
|
||||
}
|
||||
|
||||
gc::AllocKind allocKind = gc::GetGCObjectKind(module.numExportedFunctions());
|
||||
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_, allocKind));
|
||||
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx, allocKind));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
|
@ -2814,8 +2814,7 @@ class FunctionCompiler
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
|
||||
// The code generator requires explicit bounds checking for compareExchange.
|
||||
bool needsBoundsCheck = true;
|
||||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK;
|
||||
MAsmJSCompareExchangeHeap *cas =
|
||||
MAsmJSCompareExchangeHeap::New(alloc(), vt, ptr, oldv, newv, needsBoundsCheck);
|
||||
curBlock_->add(cas);
|
||||
@ -2828,8 +2827,7 @@ class FunctionCompiler
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
|
||||
// The code generator requires explicit bounds checking for the binops.
|
||||
bool needsBoundsCheck = true;
|
||||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK;
|
||||
MAsmJSAtomicBinopHeap *binop =
|
||||
MAsmJSAtomicBinopHeap::New(alloc(), op, vt, ptr, v, needsBoundsCheck);
|
||||
curBlock_->add(binop);
|
||||
|
@ -420,7 +420,7 @@ IntlInitialize(JSContext *cx, HandleObject obj, Handle<PropertyName*> initialize
|
||||
static bool
|
||||
CreateDefaultOptions(JSContext *cx, MutableHandleValue defaultOptions)
|
||||
{
|
||||
RootedObject options(cx, NewObjectWithGivenProto(cx, &JSObject::class_, nullptr, cx->global()));
|
||||
RootedObject options(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, cx->global()));
|
||||
if (!options)
|
||||
return false;
|
||||
defaultOptions.setObject(*options);
|
||||
@ -439,7 +439,7 @@ static bool
|
||||
intl_availableLocales(JSContext *cx, CountAvailable countAvailable,
|
||||
GetAvailable getAvailable, MutableHandleValue result)
|
||||
{
|
||||
RootedObject locales(cx, NewObjectWithGivenProto(cx, &JSObject::class_, nullptr, nullptr));
|
||||
RootedObject locales(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, nullptr));
|
||||
if (!locales)
|
||||
return false;
|
||||
|
||||
|
@ -904,8 +904,8 @@ GlobalObject::initMapIteratorProto(JSContext *cx, Handle<GlobalObject *> global)
|
||||
JSObject *base = GlobalObject::getOrCreateIteratorPrototype(cx, global);
|
||||
if (!base)
|
||||
return false;
|
||||
RootedNativeObject proto(cx,
|
||||
NewNativeObjectWithGivenProto(cx, &MapIteratorObject::class_, base, global));
|
||||
Rooted<MapIteratorObject *> proto(cx,
|
||||
NewObjectWithGivenProto<MapIteratorObject>(cx, base, global));
|
||||
if (!proto)
|
||||
return false;
|
||||
proto->setSlot(MapIteratorObject::RangeSlot, PrivateValue(nullptr));
|
||||
@ -928,7 +928,7 @@ MapIteratorObject::create(JSContext *cx, HandleObject mapobj, ValueMap *data,
|
||||
if (!range)
|
||||
return nullptr;
|
||||
|
||||
NativeObject *iterobj = NewNativeObjectWithGivenProto(cx, &class_, proto, global);
|
||||
MapIteratorObject *iterobj = NewObjectWithGivenProto<MapIteratorObject>(cx, proto, global);
|
||||
if (!iterobj) {
|
||||
js_delete(range);
|
||||
return nullptr;
|
||||
@ -936,7 +936,7 @@ MapIteratorObject::create(JSContext *cx, HandleObject mapobj, ValueMap *data,
|
||||
iterobj->setSlot(TargetSlot, ObjectValue(*mapobj));
|
||||
iterobj->setSlot(KindSlot, Int32Value(int32_t(kind)));
|
||||
iterobj->setSlot(RangeSlot, PrivateValue(range));
|
||||
return static_cast<MapIteratorObject *>(iterobj);
|
||||
return iterobj;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1207,7 +1207,7 @@ MapObject::set(JSContext *cx, HandleObject obj, HandleValue k, HandleValue v)
|
||||
MapObject*
|
||||
MapObject::create(JSContext *cx)
|
||||
{
|
||||
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
|
||||
Rooted<MapObject *> obj(cx, NewBuiltinClassInstance<MapObject>(cx));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
@ -1219,7 +1219,7 @@ MapObject::create(JSContext *cx)
|
||||
}
|
||||
|
||||
obj->setPrivate(map);
|
||||
return &obj->as<MapObject>();
|
||||
return obj;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1586,8 +1586,8 @@ GlobalObject::initSetIteratorProto(JSContext *cx, Handle<GlobalObject*> global)
|
||||
JSObject *base = GlobalObject::getOrCreateIteratorPrototype(cx, global);
|
||||
if (!base)
|
||||
return false;
|
||||
RootedNativeObject proto(cx, NewNativeObjectWithGivenProto(cx, &SetIteratorObject::class_,
|
||||
base, global));
|
||||
Rooted<SetIteratorObject *> proto(cx,
|
||||
NewObjectWithGivenProto<SetIteratorObject>(cx, base, global));
|
||||
if (!proto)
|
||||
return false;
|
||||
proto->setSlot(SetIteratorObject::RangeSlot, PrivateValue(nullptr));
|
||||
@ -1610,7 +1610,7 @@ SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
|
||||
if (!range)
|
||||
return nullptr;
|
||||
|
||||
NativeObject *iterobj = NewNativeObjectWithGivenProto(cx, &class_, proto, global);
|
||||
SetIteratorObject *iterobj = NewObjectWithGivenProto<SetIteratorObject>(cx, proto, global);
|
||||
if (!iterobj) {
|
||||
js_delete(range);
|
||||
return nullptr;
|
||||
@ -1618,7 +1618,7 @@ SetIteratorObject::create(JSContext *cx, HandleObject setobj, ValueSet *data,
|
||||
iterobj->setSlot(TargetSlot, ObjectValue(*setobj));
|
||||
iterobj->setSlot(KindSlot, Int32Value(int32_t(kind)));
|
||||
iterobj->setSlot(RangeSlot, PrivateValue(range));
|
||||
return static_cast<SetIteratorObject *>(iterobj);
|
||||
return iterobj;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1786,7 +1786,7 @@ SetObject::add(JSContext *cx, HandleObject obj, HandleValue k)
|
||||
SetObject*
|
||||
SetObject::create(JSContext *cx)
|
||||
{
|
||||
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
|
||||
SetObject *obj = NewBuiltinClassInstance<SetObject>(cx);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
@ -1797,7 +1797,7 @@ SetObject::create(JSContext *cx)
|
||||
return nullptr;
|
||||
}
|
||||
obj->setPrivate(set);
|
||||
return &obj->as<SetObject>();
|
||||
return obj;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "builtin/Eval.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
|
||||
@ -321,7 +322,7 @@ JS_BasicObjectToString(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
// Some classes are really common, don't allocate new strings for them.
|
||||
// The ordering below is based on the measurements in bug 966264.
|
||||
if (obj->is<JSObject>())
|
||||
if (obj->is<PlainObject>())
|
||||
return cx->names().objectObject;
|
||||
if (obj->is<StringObject>())
|
||||
return cx->names().objectString;
|
||||
@ -429,7 +430,7 @@ DefineAccessor(JSContext *cx, unsigned argc, Value *vp)
|
||||
if (!ValueToId<CanGC>(cx, args[0], &id))
|
||||
return false;
|
||||
|
||||
RootedObject descObj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
|
||||
RootedObject descObj(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||
if (!descObj)
|
||||
return false;
|
||||
|
||||
@ -812,7 +813,7 @@ js::obj_create(JSContext *cx, unsigned argc, Value *vp)
|
||||
* Use the callee's global as the parent of the new object to avoid dynamic
|
||||
* scoping (i.e., using the caller's global).
|
||||
*/
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, &JSObject::class_, proto, &args.callee().global()));
|
||||
RootedObject obj(cx, NewObjectWithGivenProto<PlainObject>(cx, proto, &args.callee().global()));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -1183,8 +1184,7 @@ ProtoSetter(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const JSFunctionSpec js::object_methods[] = {
|
||||
static const JSFunctionSpec object_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, obj_toSource, 0,0),
|
||||
#endif
|
||||
@ -1207,14 +1207,14 @@ const JSFunctionSpec js::object_methods[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
const JSPropertySpec js::object_properties[] = {
|
||||
static const JSPropertySpec object_properties[] = {
|
||||
#if JS_HAS_OBJ_PROTO_PROP
|
||||
JS_PSGS("__proto__", ProtoGetter, ProtoSetter, 0),
|
||||
#endif
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
const JSFunctionSpec js::object_static_methods[] = {
|
||||
static const JSFunctionSpec object_static_methods[] = {
|
||||
JS_FN("getPrototypeOf", obj_getPrototypeOf, 1,0),
|
||||
JS_FN("setPrototypeOf", obj_setPrototypeOf, 2,0),
|
||||
JS_FN("getOwnPropertyDescriptor", obj_getOwnPropertyDescriptor,2,0),
|
||||
@ -1239,8 +1239,134 @@ const JSFunctionSpec js::object_static_methods[] = {
|
||||
* time, after the intrinsic holder has been set, so we put them
|
||||
* in a different array.
|
||||
*/
|
||||
const JSFunctionSpec js::object_static_selfhosted_methods[] = {
|
||||
static const JSFunctionSpec object_static_selfhosted_methods[] = {
|
||||
JS_SELF_HOSTED_FN("assign", "ObjectStaticAssign", 2,0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
CreateObjectConstructor(JSContext *cx, JSProtoKey key)
|
||||
{
|
||||
Rooted<GlobalObject*> self(cx, cx->global());
|
||||
if (!GlobalObject::ensureConstructor(cx, self, JSProto_Function))
|
||||
return nullptr;
|
||||
|
||||
RootedObject functionProto(cx, &self->getPrototype(JSProto_Function).toObject());
|
||||
|
||||
/* Create the Object function now that we have a [[Prototype]] for it. */
|
||||
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &JSFunction::class_, functionProto,
|
||||
self, SingletonObject));
|
||||
if (!ctor)
|
||||
return nullptr;
|
||||
return NewFunction(cx, ctor, obj_construct, 1, JSFunction::NATIVE_CTOR, self,
|
||||
HandlePropertyName(cx->names().Object));
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
CreateObjectPrototype(JSContext *cx, JSProtoKey key)
|
||||
{
|
||||
Rooted<GlobalObject*> self(cx, cx->global());
|
||||
|
||||
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
|
||||
MOZ_ASSERT(self->isNative());
|
||||
|
||||
/*
|
||||
* Create |Object.prototype| first, mirroring CreateBlankProto but for the
|
||||
* prototype of the created object.
|
||||
*/
|
||||
RootedPlainObject objectProto(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr,
|
||||
self, SingletonObject));
|
||||
if (!objectProto)
|
||||
return nullptr;
|
||||
|
||||
/*
|
||||
* The default 'new' type of Object.prototype is required by type inference
|
||||
* to have unknown properties, to simplify handling of e.g. heterogenous
|
||||
* objects in JSON and script literals.
|
||||
*/
|
||||
if (!JSObject::setNewTypeUnknown(cx, &PlainObject::class_, objectProto))
|
||||
return nullptr;
|
||||
|
||||
return objectProto;
|
||||
}
|
||||
|
||||
static bool
|
||||
FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject proto)
|
||||
{
|
||||
Rooted<GlobalObject*> self(cx, cx->global());
|
||||
|
||||
/* ES5 15.1.2.1. */
|
||||
RootedId evalId(cx, NameToId(cx->names().eval));
|
||||
JSObject *evalobj = DefineFunction(cx, self, evalId, IndirectEval, 1, JSFUN_STUB_GSOPS);
|
||||
if (!evalobj)
|
||||
return false;
|
||||
self->setOriginalEval(evalobj);
|
||||
|
||||
RootedObject intrinsicsHolder(cx);
|
||||
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(self);
|
||||
if (isSelfHostingGlobal) {
|
||||
intrinsicsHolder = self;
|
||||
} else {
|
||||
intrinsicsHolder = NewObjectWithGivenProto<PlainObject>(cx, proto, self, TenuredObject);
|
||||
if (!intrinsicsHolder)
|
||||
return false;
|
||||
}
|
||||
self->setIntrinsicsHolder(intrinsicsHolder);
|
||||
/* Define a property 'global' with the current global as its value. */
|
||||
RootedValue global(cx, ObjectValue(*self));
|
||||
if (!JSObject::defineProperty(cx, intrinsicsHolder, cx->names().global,
|
||||
global, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define self-hosted functions after setting the intrinsics holder
|
||||
* (which is needed to define self-hosted functions)
|
||||
*/
|
||||
if (!isSelfHostingGlobal) {
|
||||
if (!JS_DefineFunctions(cx, ctor, object_static_selfhosted_methods))
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The global object should have |Object.prototype| as its [[Prototype]].
|
||||
* Eventually we'd like to have standard classes be there from the start,
|
||||
* and thus we would know we were always setting what had previously been a
|
||||
* null [[Prototype]], but right now some code assumes it can set the
|
||||
* [[Prototype]] before standard classes have been initialized. For now,
|
||||
* only set the [[Prototype]] if it hasn't already been set.
|
||||
*/
|
||||
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
|
||||
if (self->shouldSplicePrototype(cx) && !self->splicePrototype(cx, self->getClass(), tagged))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const Class PlainObject::class_ = {
|
||||
js_Object_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_DeletePropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
nullptr, /* construct */
|
||||
nullptr, /* trace */
|
||||
{
|
||||
CreateObjectConstructor,
|
||||
CreateObjectPrototype,
|
||||
object_static_methods,
|
||||
object_methods,
|
||||
object_properties,
|
||||
FinishObjectClassInit
|
||||
}
|
||||
};
|
||||
|
||||
const Class* const js::ObjectClassPtr = &PlainObject::class_;
|
||||
|
@ -16,11 +16,6 @@ class Value;
|
||||
|
||||
namespace js {
|
||||
|
||||
extern const JSFunctionSpec object_methods[];
|
||||
extern const JSPropertySpec object_properties[];
|
||||
extern const JSFunctionSpec object_static_methods[];
|
||||
extern const JSFunctionSpec object_static_selfhosted_methods[];
|
||||
|
||||
// Object constructor native. Exposed only so the JIT can know its address.
|
||||
bool
|
||||
obj_construct(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
@ -507,13 +507,13 @@ js_InitRegExpClass(JSContext *cx, HandleObject obj)
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
|
||||
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &RegExpObject::class_));
|
||||
Rooted<RegExpObject*> proto(cx, global->createBlankPrototype<RegExpObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
proto->setPrivate(nullptr);
|
||||
proto->NativeObject::setPrivate(nullptr);
|
||||
|
||||
HandlePropertyName empty = cx->names().empty;
|
||||
RegExpObjectBuilder builder(cx, &proto->as<RegExpObject>());
|
||||
RegExpObjectBuilder builder(cx, proto);
|
||||
if (!builder.build(empty, RegExpFlag(0)))
|
||||
return nullptr;
|
||||
|
||||
|
@ -63,7 +63,7 @@ SymbolObject::initClass(JSContext *cx, HandleObject obj)
|
||||
// This uses &JSObject::class_ because: "The Symbol prototype object is an
|
||||
// ordinary object. It is not a Symbol instance and does not have a
|
||||
// [[SymbolData]] internal slot." (ES6 rev 24, 19.4.3)
|
||||
RootedObject proto(cx, global->createBlankPrototype(cx, &JSObject::class_));
|
||||
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
|
@ -1212,7 +1212,7 @@ js::testingFunc_inParallelSection(JSContext *cx, unsigned argc, jsval *vp)
|
||||
static bool
|
||||
ShellObjectMetadataCallback(JSContext *cx, JSObject **pmetadata)
|
||||
{
|
||||
RootedObject obj(cx, NewBuiltinClassInstance(cx, &JSObject::class_));
|
||||
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -2025,7 +2025,7 @@ FindPath(JSContext *cx, unsigned argc, jsval *vp)
|
||||
// array in start-to-target order.
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
// Build an object describing the node and edge.
|
||||
RootedObject obj(cx, NewBuiltinClassInstance<JSObject>(cx));
|
||||
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
|
@ -808,11 +808,11 @@ StructMetaTypeDescr::create(JSContext *cx,
|
||||
int32_t alignment = 1; // Alignment of struct.
|
||||
bool opaque = false; // Opacity of struct.
|
||||
|
||||
userFieldOffsets = NewObjectWithProto<JSObject>(cx, nullptr, nullptr, TenuredObject);
|
||||
userFieldOffsets = NewObjectWithProto<PlainObject>(cx, nullptr, nullptr, TenuredObject);
|
||||
if (!userFieldOffsets)
|
||||
return nullptr;
|
||||
|
||||
userFieldTypes = NewObjectWithProto<JSObject>(cx, nullptr, nullptr, TenuredObject);
|
||||
userFieldTypes = NewObjectWithProto<PlainObject>(cx, nullptr, nullptr, TenuredObject);
|
||||
if (!userFieldTypes)
|
||||
return nullptr;
|
||||
|
||||
@ -1067,7 +1067,7 @@ StructTypeDescr::maybeForwardedFieldCount() const
|
||||
bool
|
||||
StructTypeDescr::fieldIndex(jsid id, size_t *out) const
|
||||
{
|
||||
NativeObject &fieldNames = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES);
|
||||
ArrayObject &fieldNames = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_NAMES);
|
||||
size_t l = fieldNames.getDenseInitializedLength();
|
||||
for (size_t i = 0; i < l; i++) {
|
||||
JSAtom &a = fieldNames.getDenseElement(i).toString()->asAtom();
|
||||
@ -1088,7 +1088,7 @@ StructTypeDescr::fieldName(size_t index) const
|
||||
size_t
|
||||
StructTypeDescr::fieldOffset(size_t index) const
|
||||
{
|
||||
NativeObject &fieldOffsets = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
|
||||
ArrayObject &fieldOffsets = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
|
||||
MOZ_ASSERT(index < fieldOffsets.getDenseInitializedLength());
|
||||
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
|
||||
}
|
||||
@ -1096,7 +1096,7 @@ StructTypeDescr::fieldOffset(size_t index) const
|
||||
size_t
|
||||
StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
|
||||
{
|
||||
NativeObject &fieldOffsets = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
|
||||
ArrayObject &fieldOffsets = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_OFFSETS);
|
||||
MOZ_ASSERT(index < fieldOffsets.getDenseInitializedLength());
|
||||
return AssertedCast<size_t>(fieldOffsets.getDenseElement(index).toInt32());
|
||||
}
|
||||
@ -1104,7 +1104,7 @@ StructTypeDescr::maybeForwardedFieldOffset(size_t index) const
|
||||
TypeDescr&
|
||||
StructTypeDescr::fieldDescr(size_t index) const
|
||||
{
|
||||
NativeObject &fieldDescrs = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
|
||||
ArrayObject &fieldDescrs = fieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
|
||||
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
|
||||
return fieldDescrs.getDenseElement(index).toObject().as<TypeDescr>();
|
||||
}
|
||||
@ -1112,7 +1112,7 @@ StructTypeDescr::fieldDescr(size_t index) const
|
||||
TypeDescr&
|
||||
StructTypeDescr::maybeForwardedFieldDescr(size_t index) const
|
||||
{
|
||||
NativeObject &fieldDescrs = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
|
||||
ArrayObject &fieldDescrs = maybeForwardedFieldInfoObject(JS_DESCR_SLOT_STRUCT_FIELD_TYPES);
|
||||
MOZ_ASSERT(index < fieldDescrs.getDenseInitializedLength());
|
||||
JSObject &descr =
|
||||
*MaybeForwarded(&fieldDescrs.getDenseElement(index).toObject());
|
||||
@ -1228,12 +1228,12 @@ DefineSimpleTypeDescr(JSContext *cx,
|
||||
template<typename T>
|
||||
static JSObject *
|
||||
DefineMetaTypeDescr(JSContext *cx,
|
||||
const char *name,
|
||||
Handle<GlobalObject*> global,
|
||||
HandleNativeObject module,
|
||||
Handle<TypedObjectModuleObject*> module,
|
||||
TypedObjectModuleObject::Slot protoSlot)
|
||||
{
|
||||
RootedAtom className(cx, Atomize(cx, T::class_.name,
|
||||
strlen(T::class_.name)));
|
||||
RootedAtom className(cx, Atomize(cx, name, strlen(name)));
|
||||
if (!className)
|
||||
return nullptr;
|
||||
|
||||
@ -1243,8 +1243,8 @@ DefineMetaTypeDescr(JSContext *cx,
|
||||
|
||||
// Create ctor.prototype, which inherits from Function.__proto__
|
||||
|
||||
RootedObject proto(cx, NewObjectWithProto<JSObject>(cx, funcProto, global,
|
||||
SingletonObject));
|
||||
RootedObject proto(cx, NewObjectWithProto<PlainObject>(cx, funcProto, global,
|
||||
SingletonObject));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
@ -1254,8 +1254,8 @@ DefineMetaTypeDescr(JSContext *cx,
|
||||
if (!objProto)
|
||||
return nullptr;
|
||||
RootedObject protoProto(cx);
|
||||
protoProto = NewObjectWithProto<JSObject>(cx, objProto,
|
||||
global, SingletonObject);
|
||||
protoProto = NewObjectWithProto<PlainObject>(cx, objProto,
|
||||
global, SingletonObject);
|
||||
if (!protoProto)
|
||||
return nullptr;
|
||||
|
||||
@ -1329,7 +1329,7 @@ GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
|
||||
|
||||
RootedObject arrayType(cx);
|
||||
arrayType = DefineMetaTypeDescr<ArrayMetaTypeDescr>(
|
||||
cx, global, module, TypedObjectModuleObject::ArrayTypePrototype);
|
||||
cx, "ArrayType", global, module, TypedObjectModuleObject::ArrayTypePrototype);
|
||||
if (!arrayType)
|
||||
return false;
|
||||
|
||||
@ -1344,7 +1344,7 @@ GlobalObject::initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global)
|
||||
|
||||
RootedObject structType(cx);
|
||||
structType = DefineMetaTypeDescr<StructMetaTypeDescr>(
|
||||
cx, global, module, TypedObjectModuleObject::StructTypePrototype);
|
||||
cx, "StructType", global, module, TypedObjectModuleObject::StructTypePrototype);
|
||||
if (!structType)
|
||||
return false;
|
||||
|
||||
|
@ -162,15 +162,6 @@ class TypedProto : public NativeObject
|
||||
|
||||
class TypeDescr : public NativeObject
|
||||
{
|
||||
public:
|
||||
// This is *intentionally* not defined so as to produce link
|
||||
// errors if a is<FooTypeDescr>() etc goes wrong. Otherwise, the
|
||||
// default implementation resolves this to a reference to
|
||||
// FooTypeDescr::class_ which resolves to
|
||||
// JSObject::class_. Debugging the resulting errors leads to much
|
||||
// fun and rejoicing.
|
||||
static const Class class_;
|
||||
|
||||
public:
|
||||
TypedProto &typedProto() const {
|
||||
return getReservedSlot(JS_DESCR_SLOT_TYPROTO).toObject().as<TypedProto>();
|
||||
@ -498,12 +489,12 @@ class StructTypeDescr : public ComplexTypeDescr
|
||||
size_t maybeForwardedFieldOffset(size_t index) const;
|
||||
|
||||
private:
|
||||
NativeObject &fieldInfoObject(size_t slot) const {
|
||||
return getReservedSlot(slot).toObject().as<NativeObject>();
|
||||
ArrayObject &fieldInfoObject(size_t slot) const {
|
||||
return getReservedSlot(slot).toObject().as<ArrayObject>();
|
||||
}
|
||||
|
||||
NativeObject &maybeForwardedFieldInfoObject(size_t slot) const {
|
||||
return MaybeForwarded(&getReservedSlot(slot).toObject())->as<NativeObject>();
|
||||
ArrayObject &maybeForwardedFieldInfoObject(size_t slot) const {
|
||||
return MaybeForwarded(&getReservedSlot(slot).toObject())->as<ArrayObject>();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@ WeakSetObject::initClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
// Todo: WeakSet.prototype should not be a WeakSet!
|
||||
RootedNativeObject proto(cx, global->createBlankPrototype(cx, &class_));
|
||||
Rooted<WeakSetObject*> proto(cx, global->createBlankPrototype<WeakSetObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
proto->setReservedSlot(WEAKSET_MAP_SLOT, UndefinedValue());
|
||||
@ -70,7 +70,7 @@ WeakSetObject::initClass(JSContext *cx, JSObject *obj)
|
||||
WeakSetObject*
|
||||
WeakSetObject::create(JSContext *cx)
|
||||
{
|
||||
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &class_));
|
||||
Rooted<WeakSetObject *> obj(cx, NewBuiltinClassInstance<WeakSetObject>(cx));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
@ -79,7 +79,7 @@ WeakSetObject::create(JSContext *cx)
|
||||
return nullptr;
|
||||
|
||||
obj->setReservedSlot(WEAKSET_MAP_SLOT, ObjectValue(*map));
|
||||
return &obj->as<WeakSetObject>();
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1798,8 +1798,11 @@ BindNameToSlotHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
switch (dn->kind()) {
|
||||
case Definition::ARG:
|
||||
switch (op) {
|
||||
case JSOP_GETNAME: op = JSOP_GETARG; break;
|
||||
case JSOP_SETNAME: op = JSOP_SETARG; break;
|
||||
case JSOP_GETNAME:
|
||||
op = JSOP_GETARG; break;
|
||||
case JSOP_SETNAME:
|
||||
case JSOP_STRICTSETNAME:
|
||||
op = JSOP_SETARG; break;
|
||||
default: MOZ_CRASH("arg");
|
||||
}
|
||||
MOZ_ASSERT(!pn->isConst());
|
||||
@ -1810,9 +1813,13 @@ BindNameToSlotHelper(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
case Definition::CONST:
|
||||
case Definition::LET:
|
||||
switch (op) {
|
||||
case JSOP_GETNAME: op = JSOP_GETLOCAL; break;
|
||||
case JSOP_SETNAME: op = JSOP_SETLOCAL; break;
|
||||
case JSOP_SETCONST: op = JSOP_SETLOCAL; break;
|
||||
case JSOP_GETNAME:
|
||||
op = JSOP_GETLOCAL; break;
|
||||
case JSOP_SETNAME:
|
||||
case JSOP_STRICTSETNAME:
|
||||
op = JSOP_SETLOCAL; break;
|
||||
case JSOP_SETCONST:
|
||||
op = JSOP_SETLOCAL; break;
|
||||
default: MOZ_CRASH("local");
|
||||
}
|
||||
break;
|
||||
@ -2258,9 +2265,9 @@ IteratorResultShape(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned *shape)
|
||||
{
|
||||
MOZ_ASSERT(bce->script->compileAndGo());
|
||||
|
||||
RootedNativeObject obj(cx);
|
||||
RootedPlainObject obj(cx);
|
||||
gc::AllocKind kind = GuessObjectGCKind(2);
|
||||
obj = NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind);
|
||||
obj = NewBuiltinClassInstance<PlainObject>(cx, kind);
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -2300,10 +2307,10 @@ EmitFinishIteratorResult(ExclusiveContext *cx, BytecodeEmitter *bce, bool done)
|
||||
{
|
||||
jsatomid value_id;
|
||||
if (!bce->makeAtomIndex(cx->names().value, &value_id))
|
||||
return UINT_MAX;
|
||||
return false;
|
||||
jsatomid done_id;
|
||||
if (!bce->makeAtomIndex(cx->names().done, &done_id))
|
||||
return UINT_MAX;
|
||||
return false;
|
||||
|
||||
if (!EmitIndex32(cx, JSOP_INITPROP, value_id, bce))
|
||||
return false;
|
||||
@ -4240,8 +4247,8 @@ ParseNode::getConstantValue(ExclusiveContext *cx, AllowConstantObjects allowObje
|
||||
allowObjects = DontAllowObjects;
|
||||
|
||||
gc::AllocKind kind = GuessObjectGCKind(pn_count);
|
||||
RootedNativeObject obj(cx, NewNativeBuiltinClassInstance(cx, &JSObject::class_,
|
||||
kind, MaybeSingletonObject));
|
||||
RootedPlainObject obj(cx,
|
||||
NewBuiltinClassInstance<PlainObject>(cx, kind, MaybeSingletonObject));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
@ -6487,10 +6494,10 @@ EmitObject(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* Try to construct the shape of the object as we go, so we can emit a
|
||||
* JSOP_NEWOBJECT with the final shape instead.
|
||||
*/
|
||||
RootedNativeObject obj(cx);
|
||||
RootedPlainObject obj(cx);
|
||||
if (bce->script->compileAndGo()) {
|
||||
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count);
|
||||
obj = NewNativeBuiltinClassInstance(cx, &JSObject::class_, kind, TenuredObject);
|
||||
obj = NewBuiltinClassInstance<PlainObject>(cx, kind, TenuredObject);
|
||||
if (!obj)
|
||||
return false;
|
||||
}
|
||||
|
@ -176,6 +176,7 @@ class LazyScript;
|
||||
class NativeObject;
|
||||
class NestedScopeObject;
|
||||
class Nursery;
|
||||
class PlainObject;
|
||||
class PropertyName;
|
||||
class SavedFrame;
|
||||
class ScopeObject;
|
||||
@ -223,6 +224,7 @@ template <> struct MapTypeToTraceKind<JSScript> { static const JSGCTrace
|
||||
template <> struct MapTypeToTraceKind<JSString> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<LazyScript> { static const JSGCTraceKind kind = JSTRACE_LAZY_SCRIPT; };
|
||||
template <> struct MapTypeToTraceKind<NestedScopeObject>{ static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<PlainObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<PropertyName> { static const JSGCTraceKind kind = JSTRACE_STRING; };
|
||||
template <> struct MapTypeToTraceKind<SavedFrame> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
template <> struct MapTypeToTraceKind<ScopeObject> { static const JSGCTraceKind kind = JSTRACE_OBJECT; };
|
||||
@ -821,6 +823,7 @@ typedef HeapPtr<JSLinearString*> HeapPtrLinearString;
|
||||
typedef HeapPtr<JSObject*> HeapPtrObject;
|
||||
typedef HeapPtr<JSScript*> HeapPtrScript;
|
||||
typedef HeapPtr<JSString*> HeapPtrString;
|
||||
typedef HeapPtr<PlainObject*> HeapPtrPlainObject;
|
||||
typedef HeapPtr<PropertyName*> HeapPtrPropertyName;
|
||||
typedef HeapPtr<Shape*> HeapPtrShape;
|
||||
typedef HeapPtr<UnownedBaseShape*> HeapPtrUnownedBaseShape;
|
||||
|
@ -656,6 +656,7 @@ DeclMarkerImpl(Object, GlobalObject)
|
||||
DeclMarkerImpl(Object, JSObject)
|
||||
DeclMarkerImpl(Object, JSFunction)
|
||||
DeclMarkerImpl(Object, NestedScopeObject)
|
||||
DeclMarkerImpl(Object, PlainObject)
|
||||
DeclMarkerImpl(Object, SavedFrame)
|
||||
DeclMarkerImpl(Object, ScopeObject)
|
||||
DeclMarkerImpl(Object, SharedArrayBufferObject)
|
||||
|
@ -117,6 +117,7 @@ DeclMarker(Object, GlobalObject)
|
||||
DeclMarker(Object, JSObject)
|
||||
DeclMarker(Object, JSFunction)
|
||||
DeclMarker(Object, NestedScopeObject)
|
||||
DeclMarker(Object, PlainObject)
|
||||
DeclMarker(Object, SavedFrame)
|
||||
DeclMarker(Object, ScopeObject)
|
||||
DeclMarker(Object, SharedArrayBufferObject)
|
||||
|
@ -17,6 +17,7 @@ namespace js {
|
||||
class PropertyName;
|
||||
class NativeObject;
|
||||
class ArrayObject;
|
||||
class PlainObject;
|
||||
class ScriptSourceObject;
|
||||
class Shape;
|
||||
|
||||
@ -31,6 +32,7 @@ typedef JS::Handle<JSAtom*> HandleAtom;
|
||||
typedef JS::Handle<JSLinearString*> HandleLinearString;
|
||||
typedef JS::Handle<PropertyName*> HandlePropertyName;
|
||||
typedef JS::Handle<ArrayObject*> HandleArrayObject;
|
||||
typedef JS::Handle<PlainObject*> HandlePlainObject;
|
||||
typedef JS::Handle<ScriptSourceObject*> HandleScriptSource;
|
||||
|
||||
typedef JS::MutableHandle<Shape*> MutableHandleShape;
|
||||
@ -44,6 +46,7 @@ typedef JS::Rooted<JSAtom*> RootedAtom;
|
||||
typedef JS::Rooted<JSLinearString*> RootedLinearString;
|
||||
typedef JS::Rooted<PropertyName*> RootedPropertyName;
|
||||
typedef JS::Rooted<ArrayObject*> RootedArrayObject;
|
||||
typedef JS::Rooted<PlainObject*> RootedPlainObject;
|
||||
typedef JS::Rooted<ScriptSourceObject*> RootedScriptSource;
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -135,18 +135,40 @@ JS_TraceIncomingCCWs(JSTracer *trc, const JS::ZoneSet &zones)
|
||||
|
||||
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;
|
||||
JSObject *obj = static_cast<JSObject *>(key.wrapped);
|
||||
// Ignore CCWs whose wrapped value doesn't live in our given set
|
||||
// of zones.
|
||||
if (!zones.has(obj->zone()))
|
||||
JSObject *obj;
|
||||
JSScript *script;
|
||||
|
||||
switch (key.kind) {
|
||||
case CrossCompartmentKey::StringWrapper:
|
||||
// StringWrappers are just used to avoid copying strings
|
||||
// across zones multiple times, and don't hold a strong
|
||||
// reference.
|
||||
continue;
|
||||
|
||||
MarkObjectUnbarriered(trc, &obj, "cross-compartment wrapper");
|
||||
MOZ_ASSERT(obj == key.wrapped);
|
||||
case CrossCompartmentKey::ObjectWrapper:
|
||||
case CrossCompartmentKey::DebuggerObject:
|
||||
case CrossCompartmentKey::DebuggerSource:
|
||||
case CrossCompartmentKey::DebuggerEnvironment:
|
||||
obj = static_cast<JSObject *>(key.wrapped);
|
||||
// Ignore CCWs whose wrapped value doesn't live in our given
|
||||
// set of zones.
|
||||
if (!zones.has(obj->zone()))
|
||||
continue;
|
||||
|
||||
MarkObjectUnbarriered(trc, &obj, "cross-compartment wrapper");
|
||||
MOZ_ASSERT(obj == key.wrapped);
|
||||
break;
|
||||
|
||||
case CrossCompartmentKey::DebuggerScript:
|
||||
script = static_cast<JSScript *>(key.wrapped);
|
||||
// Ignore CCWs whose wrapped value doesn't live in our given
|
||||
// set of zones.
|
||||
if (!zones.has(script->zone()))
|
||||
continue;
|
||||
MarkScriptUnbarriered(trc, &script, "cross-compartment wrapper");
|
||||
MOZ_ASSERT(script == key.wrapped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
js/src/jit-test/tests/TypedObject/function-names.js
Normal file
8
js/src/jit-test/tests/TypedObject/function-names.js
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
if (typeof TypedObject === "undefined")
|
||||
quit();
|
||||
|
||||
// Make sure some builtin TypedObject functions are given sensible names.
|
||||
assertEq(TypedObject.ArrayType.name, "ArrayType");
|
||||
assertEq(TypedObject.StructType.name, "StructType");
|
||||
assertEq(TypedObject.storage.name, "storage");
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
var global = newGlobal();
|
||||
var array = global.Int8Array(10);
|
||||
var array = new global.Int8Array(10);
|
||||
|
||||
assertEq(array.find(v => v == 1), undefined)
|
||||
assertEq(array.findIndex(v => v == 0), 0)
|
||||
|
5
js/src/jit-test/tests/debug/bug-1103817.js
Normal file
5
js/src/jit-test/tests/debug/bug-1103817.js
Normal file
@ -0,0 +1,5 @@
|
||||
// Random chosen test: js/src/jit-test/tests/debug/Source-introductionScript-04.js
|
||||
x = (new Debugger).addDebuggee(newGlobal());
|
||||
print(x.getOwnPropertyDescriptor('Function').value.proto.script);
|
||||
// Random chosen test: js/src/jit-test/tests/debug/Memory-takeCensus-03.js
|
||||
(new Debugger).memory.takeCensus();
|
6
js/src/jit-test/tests/ion/bug1105684.js
Normal file
6
js/src/jit-test/tests/ion/bug1105684.js
Normal file
@ -0,0 +1,6 @@
|
||||
function f(x) {
|
||||
Math.exp(x ? 0 : 1)
|
||||
}
|
||||
f(objectEmulatingUndefined())
|
||||
f(objectEmulatingUndefined())
|
||||
|
@ -1684,7 +1684,7 @@ BaselineCompiler::emit_JSOP_NEWARRAY()
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef JSObject *(*NewArrayCopyOnWriteFn)(JSContext *, HandleNativeObject, gc::InitialHeap);
|
||||
typedef JSObject *(*NewArrayCopyOnWriteFn)(JSContext *, HandleArrayObject, gc::InitialHeap);
|
||||
const VMFunction jit::NewArrayCopyOnWriteInfo =
|
||||
FunctionInfo<NewArrayCopyOnWriteFn>(js::NewDenseCopyOnWriteArray);
|
||||
|
||||
@ -1742,8 +1742,8 @@ BaselineCompiler::emit_JSOP_NEWOBJECT()
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedNativeObject baseObject(cx, script->getObject(pc));
|
||||
RootedNativeObject templateObject(cx, CopyInitializerObject(cx, baseObject, TenuredObject));
|
||||
RootedPlainObject baseObject(cx, &script->getObject(pc)->as<PlainObject>());
|
||||
RootedPlainObject templateObject(cx, CopyInitializerObject(cx, baseObject, TenuredObject));
|
||||
if (!templateObject)
|
||||
return false;
|
||||
|
||||
@ -1809,8 +1809,8 @@ BaselineCompiler::emit_JSOP_NEWINIT()
|
||||
} else {
|
||||
MOZ_ASSERT(key == JSProto_Object);
|
||||
|
||||
RootedNativeObject templateObject(cx);
|
||||
templateObject = NewNativeBuiltinClassInstance(cx, &JSObject::class_, TenuredObject);
|
||||
RootedPlainObject templateObject(cx,
|
||||
NewBuiltinClassInstance<PlainObject>(cx, TenuredObject));
|
||||
if (!templateObject)
|
||||
return false;
|
||||
|
||||
@ -1857,7 +1857,7 @@ BaselineCompiler::emit_JSOP_INITELEM()
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*MutateProtoFn)(JSContext *cx, HandleObject obj, HandleValue newProto);
|
||||
typedef bool (*MutateProtoFn)(JSContext *cx, HandlePlainObject obj, HandleValue newProto);
|
||||
static const VMFunction MutateProtoInfo = FunctionInfo<MutateProtoFn>(MutatePrototype);
|
||||
|
||||
bool
|
||||
|
@ -1787,7 +1787,7 @@ DoNewObject(JSContext *cx, ICNewObject_Fallback *stub, MutableHandleValue res)
|
||||
{
|
||||
FallbackICSpew(cx, stub, "NewObject");
|
||||
|
||||
RootedNativeObject templateObject(cx, stub->templateObject());
|
||||
RootedPlainObject templateObject(cx, stub->templateObject());
|
||||
JSObject *obj = NewInitObject(cx, templateObject);
|
||||
if (!obj)
|
||||
return false;
|
||||
@ -8248,8 +8248,8 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
|
||||
}
|
||||
|
||||
if (op == JSOP_INITPROP) {
|
||||
MOZ_ASSERT(obj->is<JSObject>());
|
||||
if (!DefineNativeProperty(cx, obj.as<NativeObject>(), id, rhs,
|
||||
MOZ_ASSERT(obj->is<PlainObject>());
|
||||
if (!DefineNativeProperty(cx, obj.as<PlainObject>(), id, rhs,
|
||||
nullptr, nullptr, JSPROP_ENUMERATE))
|
||||
{
|
||||
return false;
|
||||
@ -9202,7 +9202,7 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
|
||||
|
||||
// Remember the template object associated with any script being called
|
||||
// as a constructor, for later use during Ion compilation.
|
||||
RootedNativeObject templateObject(cx);
|
||||
RootedPlainObject templateObject(cx);
|
||||
if (constructing) {
|
||||
templateObject = CreateThisForFunction(cx, fun, MaybeSingletonObject);
|
||||
if (!templateObject)
|
||||
|
@ -1927,26 +1927,26 @@ class ICNewObject_Fallback : public ICFallbackStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
HeapPtrNativeObject templateObject_;
|
||||
HeapPtrPlainObject templateObject_;
|
||||
|
||||
ICNewObject_Fallback(JitCode *stubCode, NativeObject *templateObject)
|
||||
ICNewObject_Fallback(JitCode *stubCode, PlainObject *templateObject)
|
||||
: ICFallbackStub(ICStub::NewObject_Fallback, stubCode), templateObject_(templateObject)
|
||||
{}
|
||||
|
||||
public:
|
||||
static inline ICNewObject_Fallback *New(ICStubSpace *space, JitCode *code,
|
||||
NativeObject *templateObject) {
|
||||
PlainObject *templateObject) {
|
||||
if (!code)
|
||||
return nullptr;
|
||||
return space->allocate<ICNewObject_Fallback>(code, templateObject);
|
||||
}
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
RootedNativeObject templateObject;
|
||||
RootedPlainObject templateObject;
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx, NativeObject *templateObject)
|
||||
Compiler(JSContext *cx, PlainObject *templateObject)
|
||||
: ICStubCompiler(cx, ICStub::NewObject_Fallback),
|
||||
templateObject(cx, templateObject)
|
||||
{}
|
||||
@ -1956,7 +1956,7 @@ class ICNewObject_Fallback : public ICFallbackStub
|
||||
}
|
||||
};
|
||||
|
||||
HeapPtrNativeObject &templateObject() {
|
||||
HeapPtrPlainObject &templateObject() {
|
||||
return templateObject_;
|
||||
}
|
||||
};
|
||||
@ -6371,10 +6371,10 @@ class ICCall_StringSplit : public ICMonitoredStub
|
||||
uint32_t pcOffset_;
|
||||
HeapPtrString expectedThis_;
|
||||
HeapPtrString expectedArg_;
|
||||
HeapPtrNativeObject templateObject_;
|
||||
HeapPtrArrayObject templateObject_;
|
||||
|
||||
ICCall_StringSplit(JitCode *stubCode, ICStub *firstMonitorStub, uint32_t pcOffset, HandleString thisString,
|
||||
HandleString argString, HandleNativeObject templateObject)
|
||||
HandleString argString, HandleArrayObject templateObject)
|
||||
: ICMonitoredStub(ICStub::Call_StringSplit, stubCode, firstMonitorStub),
|
||||
pcOffset_(pcOffset), expectedThis_(thisString), expectedArg_(argString),
|
||||
templateObject_(templateObject)
|
||||
@ -6383,7 +6383,7 @@ class ICCall_StringSplit : public ICMonitoredStub
|
||||
public:
|
||||
static inline ICCall_StringSplit *New(ICStubSpace *space, JitCode *code,
|
||||
ICStub *firstMonitorStub, uint32_t pcOffset, HandleString thisString,
|
||||
HandleString argString, HandleNativeObject templateObject)
|
||||
HandleString argString, HandleArrayObject templateObject)
|
||||
{
|
||||
if (!code)
|
||||
return nullptr;
|
||||
@ -6411,7 +6411,7 @@ class ICCall_StringSplit : public ICMonitoredStub
|
||||
return expectedArg_;
|
||||
}
|
||||
|
||||
HeapPtrNativeObject &templateObject() {
|
||||
HeapPtrArrayObject &templateObject() {
|
||||
return templateObject_;
|
||||
}
|
||||
|
||||
@ -6421,7 +6421,7 @@ class ICCall_StringSplit : public ICMonitoredStub
|
||||
uint32_t pcOffset_;
|
||||
RootedString expectedThis_;
|
||||
RootedString expectedArg_;
|
||||
RootedNativeObject templateObject_;
|
||||
RootedArrayObject templateObject_;
|
||||
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
@ -6437,7 +6437,7 @@ class ICCall_StringSplit : public ICMonitoredStub
|
||||
pcOffset_(pcOffset),
|
||||
expectedThis_(cx, thisString),
|
||||
expectedArg_(cx, argString),
|
||||
templateObject_(cx, &templateObject.toObject().as<NativeObject>())
|
||||
templateObject_(cx, &templateObject.toObject().as<ArrayObject>())
|
||||
{ }
|
||||
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
|
@ -4197,10 +4197,10 @@ class OutOfLineNewObject : public OutOfLineCodeBase<CodeGenerator>
|
||||
}
|
||||
};
|
||||
|
||||
typedef JSObject *(*NewInitObjectFn)(JSContext *, HandleNativeObject);
|
||||
typedef JSObject *(*NewInitObjectFn)(JSContext *, HandlePlainObject);
|
||||
static const VMFunction NewInitObjectInfo = FunctionInfo<NewInitObjectFn>(NewInitObject);
|
||||
|
||||
typedef JSObject *(*NewInitObjectWithClassPrototypeFn)(JSContext *, HandleObject);
|
||||
typedef JSObject *(*NewInitObjectWithClassPrototypeFn)(JSContext *, HandlePlainObject);
|
||||
static const VMFunction NewInitObjectWithClassPrototypeInfo =
|
||||
FunctionInfo<NewInitObjectWithClassPrototypeFn>(NewInitObjectWithClassPrototype);
|
||||
|
||||
@ -4321,7 +4321,7 @@ CodeGenerator::visitNewObject(LNewObject *lir)
|
||||
MOZ_ASSERT(gen->info().executionMode() == SequentialExecution);
|
||||
Register objReg = ToRegister(lir->output());
|
||||
Register tempReg = ToRegister(lir->temp());
|
||||
NativeObject *templateObject = lir->mir()->templateObject();
|
||||
PlainObject *templateObject = lir->mir()->templateObject();
|
||||
|
||||
if (lir->mir()->shouldUseVM()) {
|
||||
visitNewObjectVMCall(lir);
|
||||
@ -4375,7 +4375,7 @@ CodeGenerator::visitNewDeclEnvObject(LNewDeclEnvObject *lir)
|
||||
{
|
||||
Register objReg = ToRegister(lir->output());
|
||||
Register tempReg = ToRegister(lir->temp());
|
||||
NativeObject *templateObj = lir->mir()->templateObj();
|
||||
DeclEnvObject *templateObj = lir->mir()->templateObj();
|
||||
CompileInfo &info = lir->mir()->block()->info();
|
||||
|
||||
// If we have a template object, we can inline call object creation.
|
||||
@ -4401,7 +4401,7 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
|
||||
Register objReg = ToRegister(lir->output());
|
||||
Register tempReg = ToRegister(lir->temp());
|
||||
|
||||
NativeObject *templateObj = lir->mir()->templateObject();
|
||||
CallObject *templateObj = lir->mir()->templateObject();
|
||||
|
||||
JSScript *script = lir->mir()->block()->info().script();
|
||||
uint32_t lexicalBegin = script->bindings.aliasedBodyLevelLexicalBegin();
|
||||
@ -4452,7 +4452,7 @@ CodeGenerator::visitNewCallObjectPar(LNewCallObjectPar *lir)
|
||||
Register cxReg = ToRegister(lir->forkJoinContext());
|
||||
Register tempReg1 = ToRegister(lir->getTemp0());
|
||||
Register tempReg2 = ToRegister(lir->getTemp1());
|
||||
NativeObject *templateObj = lir->mir()->templateObj();
|
||||
CallObject *templateObj = lir->mir()->templateObj();
|
||||
|
||||
emitAllocateGCThingPar(lir, resultReg, cxReg, tempReg1, tempReg2, templateObj);
|
||||
}
|
||||
@ -4624,7 +4624,7 @@ CodeGenerator::visitInitElemGetterSetter(LInitElemGetterSetter *lir)
|
||||
callVM(InitElemGetterSetterInfo, lir);
|
||||
}
|
||||
|
||||
typedef bool(*MutatePrototypeFn)(JSContext *cx, HandleObject obj, HandleValue value);
|
||||
typedef bool(*MutatePrototypeFn)(JSContext *cx, HandlePlainObject obj, HandleValue value);
|
||||
static const VMFunction MutatePrototypeInfo =
|
||||
FunctionInfo<MutatePrototypeFn>(MutatePrototype);
|
||||
|
||||
@ -4728,7 +4728,7 @@ static const VMFunction NewGCObjectInfo =
|
||||
void
|
||||
CodeGenerator::visitCreateThisWithTemplate(LCreateThisWithTemplate *lir)
|
||||
{
|
||||
NativeObject *templateObject = lir->mir()->templateObject();
|
||||
PlainObject *templateObject = lir->mir()->templateObject();
|
||||
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
|
||||
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
|
||||
Register objReg = ToRegister(lir->output());
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user