merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-12-08 12:48:58 +01:00
commit ad27337e2a
237 changed files with 2232 additions and 1788 deletions

View File

@ -122,4 +122,10 @@ LoadInfo::GetBaseURI(nsIURI** aBaseURI)
return NS_OK;
}
nsIURI*
LoadInfo::BaseURI()
{
return mBaseURI;
}
} // namespace mozilla

View File

@ -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();
};

View File

@ -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
{ }

View File

@ -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)

View File

@ -63,6 +63,7 @@ private:
*/
void InitScriptSettings();
void DestroyScriptSettings();
bool ScriptSettingsInitialized();
/*
* Static helpers in ScriptSettings which track the number of listeners

View File

@ -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;
}
}
},

View File

@ -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();
});

View File

@ -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.

View File

@ -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)

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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)) {

View File

@ -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)
{

View File

@ -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();

View File

@ -331,6 +331,12 @@ union MaybeFileDesc {
void_t;
};
union OptionalContentId
{
ContentParentId;
void_t;
};
prio(normal upto urgent) intr protocol PContent
{
parent spawns PPluginModule;

View File

@ -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) {

View File

@ -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();

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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();
} );
}

View File

@ -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();
} );
}

View File

@ -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();
} );
}

View File

@ -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();
} );
}

View File

@ -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();
} );
}

View File

@ -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();
} );
}

View File

@ -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();
} );
}

View File

@ -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__

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -17,7 +17,6 @@ EXPORTS += [
]
EXPORTS.mozilla.dom.quota += [
'AcquireListener.h',
'ArrayCluster.h',
'Client.h',
'FileStreams.h',

View File

@ -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;

View File

@ -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);

View File

@ -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']

View File

@ -0,0 +1,4 @@
[DEFAULT]
[browser_bug1104623.js]
run-if = buildapp == 'browser'

View 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);
});
}

View File

@ -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

View File

@ -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()

View File

@ -517,7 +517,6 @@ public:
static const char* GetFeatureName(GLFeature feature);
private:
std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;

View File

@ -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,

View File

@ -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);
}

View File

@ -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;
};
}

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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()) {

View File

@ -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

View File

@ -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);
}

View File

@ -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(&params);
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, &params);
} else {
mSwapChain->Present(0, mDisableSequenceForNextFrame ? DXGI_PRESENT_DO_NOT_SEQUENCE : 0);
}
mDisableSequenceForNextFrame = false;
if (mTarget) {
PaintToTarget();

View File

@ -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;
};
}

View File

@ -2184,6 +2184,10 @@ InitLayersAccelerationPrefs()
sLayersSupportsD3D11 = true;
}
}
if (!gfxPrefs::LayersD3D11DisableWARP()) {
// Always support D3D11 when WARP is allowed.
sLayersSupportsD3D11 = true;
}
}
}
#endif

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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();
};

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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);
};

View File

@ -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();
};

View File

@ -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);
};

View File

@ -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);
/**

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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!");

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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())

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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_;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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>();
}
};

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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 */

View File

@ -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;
}
}
}
}

View 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");

View File

@ -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)

View 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();

View File

@ -0,0 +1,6 @@
function f(x) {
Math.exp(x ? 0 : 1)
}
f(objectEmulatingUndefined())
f(objectEmulatingUndefined())

View File

@ -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

View File

@ -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)

View File

@ -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) {

View File

@ -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