This commit is contained in:
Wes Kocher 2014-06-13 17:00:46 -07:00
Родитель 7e7f51acd4 7078cf7ad0
Коммит 1416242684
172 изменённых файлов: 2285 добавлений и 2854 удалений

Просмотреть файл

@ -132,6 +132,7 @@ install-manifests: install-tests
install-tests: $(install_manifest_depends)
$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )_tests _build_manifests/install/tests)
include $(topsrcdir)/build/moz-automation.mk
# _tests should be purged during cleaning. However, we don't want it purged
# during PGO builds because it contains some auto-generated files.
@ -168,7 +169,7 @@ endif
endif
default all::
$(call BUILDSTATUS,TIERS export $(if $(COMPILE_ENVIRONMENT),$(if $(MOZ_PSEUDO_DERECURSE),compile ))libs tools)
$(call BUILDSTATUS,TIERS export $(if $(COMPILE_ENVIRONMENT),$(if $(MOZ_PSEUDO_DERECURSE),compile ))libs tools $(if $(MOZ_AUTOMATION),$(MOZ_AUTOMATION_TIERS)))
include $(topsrcdir)/config/rules.mk
@ -251,6 +252,9 @@ MOZ_SOURCE_STAMP := $(MOZ_SOURCE_STAMP)
export MOZ_SOURCE_STAMP
endif
update-packaging:
$(MAKE) -C tools/update-packaging
#XXX: this is a hack, since we don't want to clobber for MSVC
# PGO support, but we can't do this test in client.mk
ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)

Просмотреть файл

@ -304,10 +304,12 @@ var gAdvancedPane = {
actualSizeLabel.textContent = prefStrBundle.getString("actualDiskCacheSizeCalculated");
var cacheService =
Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
cacheService.asyncGetDiskConsumption(this.observer);
try {
var cacheService =
Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
cacheService.asyncGetDiskConsumption(this.observer);
} catch (e) {}
},
// Retrieves the amount of space currently used by offline cache
@ -324,11 +326,13 @@ var gAdvancedPane = {
}
};
var cacheService =
Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
var storage = cacheService.appCacheStorage(LoadContextInfo.default, null);
storage.asyncVisitStorage(visitor, false);
try {
var cacheService =
Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
var storage = cacheService.appCacheStorage(LoadContextInfo.default, null);
storage.asyncVisitStorage(visitor, false);
} catch (e) {}
},
updateCacheSizeUI: function (smartSizeEnabled)
@ -372,9 +376,9 @@ var gAdvancedPane = {
*/
clearCache: function ()
{
var cache = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
try {
var cache = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
cache.clear();
} catch(ex) {}
this.updateActualCacheSize();

Просмотреть файл

@ -7,11 +7,21 @@ Components.utils.import("resource://gre/modules/NetUtil.jsm");
function test() {
waitForExplicitFinish();
let prefs = [
"browser.cache.offline.enable",
"browser.cache.disk.enable",
"browser.cache.memory.enable",
];
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.cache.offline.enable");
for (let pref of prefs) {
Services.prefs.clearUserPref(pref);
}
});
Services.prefs.setBoolPref("browser.cache.offline.enable", false);
for (let pref of prefs) {
Services.prefs.setBoolPref(pref, false);
}
open_preferences(runTest);
}

Просмотреть файл

@ -46,23 +46,26 @@ if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
# autotools can't quite handle an MSVC build environment yet.
LDFLAGS=
CFLAGS=
ac_configure_args="$ac_configure_args LD=link CPP=\"cl -nologo -EP\" \
CXXCPP=\"cl -nologo -EP\" SHELL=sh.exe"
rtl=
ac_configure_args="$ac_configure_args LD=link CPP=\"$CC -nologo -EP\" \
CXXCPP=\"$CXX -nologo -EP\" SHELL=sh.exe"
flags=
if test -z "$MOZ_NO_DEBUG_RTL" -a -n "$MOZ_DEBUG"; then
rtl=" -DUSE_DEBUG_RTL"
flags=" -DUSE_DEBUG_RTL"
fi
if test -n "$CLANG_CL"; then
flags="$flags -clang-cl"
fi
case "${target_cpu}" in
x86_64)
# Need target since MSYS tools into mozilla-build may be 32bit
ac_configure_args="$ac_configure_args \
CC=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh -m64$rtl\" \
CXX=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh -m64$rtl\""
CC=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh -m64$flags\" \
CXX=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh -m64$flags\""
;;
*)
ac_configure_args="$ac_configure_args \
CC=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh$rtl\" \
CXX=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh$rtl\""
CC=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh$flags\" \
CXX=\"$_topsrcdir/js/src/ctypes/libffi/msvcc.sh$flags\""
;;
esac
fi

Просмотреть файл

@ -0,0 +1,79 @@
#!/usr/bin/python
#
# 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/.
import sys, os, sha, json, re
from argparse import ArgumentParser
def getFileHashAndSize(filename):
sha1Hash = 'UNKNOWN'
size = 'UNKNOWN'
try:
# open in binary mode to make sure we get consistent results
# across all platforms
f = open(filename, "rb")
shaObj = sha.new(f.read())
sha1Hash = shaObj.hexdigest()
size = os.path.getsize(filename)
except:
pass
return (sha1Hash, size)
def getMarProperties(filename):
(complete_mar_hash, complete_mar_size) = getFileHashAndSize(filename)
return {
'completeMarFilename': os.path.basename(filename),
'completeMarSize': complete_mar_size,
'completeMarHash': complete_mar_hash,
}
def getUrlProperties(filename):
# let's create a switch case using name-spaces/dict
# rather than a long if/else with duplicate code
property_conditions = [
# key: property name, value: condition
('symbolsUrl', lambda m: m.endswith('crashreporter-symbols.zip') or
m.endswith('crashreporter-symbols-full.zip')),
('testsUrl', lambda m: m.endswith(('tests.tar.bz2', 'tests.zip'))),
('unsignedApkUrl', lambda m: m.endswith('apk') and
'unsigned-unaligned' in m),
('robocopApkUrl', lambda m: m.endswith('apk') and 'robocop' in m),
('jsshellUrl', lambda m: 'jsshell-' in m and m.endswith('.zip')),
('completeMarUrl', lambda m: m.endswith('.complete.mar')),
# packageUrl must be last!
('packageUrl', lambda m: True),
]
url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz))$''')
properties = {}
with open(filename) as f:
for line in f:
m = url_re.match(line)
if m:
m = m.group(1)
for prop, condition in property_conditions:
if condition(m):
properties.update({prop: m})
break
return properties
if __name__ == '__main__':
parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.')
parser.add_argument("--complete-mar-file", required=True,
action="store", dest="complete_mar_file",
help="Path to the complete MAR file, relative to the objdir.")
parser.add_argument("--upload-output", required=True,
action="store", dest="upload_output",
help="Path to the text output of 'make upload'")
args = parser.parse_args()
json_data = getMarProperties(args.complete_mar_file)
json_data.update(getUrlProperties(args.upload_output))
with open('mach_build_properties.json', 'w') as outfile:
json.dump(json_data, outfile, indent=4)

66
build/moz-automation.mk Normal file
Просмотреть файл

@ -0,0 +1,66 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
# Log file from the 'make upload' step. We need this to parse out the URLs of
# the uploaded files.
AUTOMATION_UPLOAD_OUTPUT = $(DIST)/automation-upload.txt
# Automation build steps. Everything in MOZ_AUTOMATION_TIERS also gets used in
# TIERS for mach display. As such, the MOZ_AUTOMATION_TIERS are roughly sorted
# here in the order that they will be executed (since mach doesn't know of the
# dependencies between them).
MOZ_AUTOMATION_TIERS += package-tests
MOZ_AUTOMATION_TIERS += buildsymbols
ifdef NIGHTLY_BUILD
MOZ_AUTOMATION_TIERS += uploadsymbols
endif
ifdef MOZ_UPDATE_PACKAGING
MOZ_AUTOMATION_TIERS += update-packaging
automation/upload: automation/update-packaging
automation/update-packaging: automation/package
endif
MOZ_AUTOMATION_TIERS += package
MOZ_AUTOMATION_TIERS += check
ifndef MOZ_ASAN
MOZ_AUTOMATION_TIERS += l10n-check
automation/l10n-check: automation/package
endif
MOZ_AUTOMATION_TIERS += upload
automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) --upload-output $(AUTOMATION_UPLOAD_OUTPUT)
# Dependencies between automation build steps
automation/uploadsymbols: automation/buildsymbols
automation/upload: automation/package
automation/upload: automation/package-tests
automation/upload: automation/buildsymbols
# automation/package and automation/check should depend on build (which is
# implicit due to the way client.mk invokes automation/build), but buildsymbols
# changes the binaries/libs, and that's what we package/test.
automation/package: automation/buildsymbols
automation/check: automation/buildsymbols
# make check runs with the keep-going flag so we can see all the failures
AUTOMATION_EXTRA_CMDLINE-check = -k
# We need the log from make upload to grep it for urls in order to set
# properties.
AUTOMATION_EXTRA_CMDLINE-upload = 2>&1 | tee $(AUTOMATION_UPLOAD_OUTPUT)
automation/%:
$(call BUILDSTATUS,TIER_START $*)
@$(MAKE) $* $(AUTOMATION_EXTRA_CMDLINE-$*)
$(call BUILDSTATUS,TIER_FINISH $*)

Просмотреть файл

@ -25,7 +25,6 @@ if test -z "$SCCACHE_DISABLE" -a -z "$no_sccache"; then
bucket=mozilla-releng-s3-cache-us-west-2-try
;;
esac
mk_add_options "export SCCACHE_NO_HTTPS=1"
;;
*use1.mozilla.com*)
bucket=mozilla-releng-s3-cache-us-east-1-try

Просмотреть файл

@ -176,7 +176,7 @@ CONFIGURES := $(TOPSRCDIR)/configure
CONFIGURES += $(TOPSRCDIR)/js/src/configure
# Make targets that are going to be passed to the real build system
OBJDIR_TARGETS = install export libs clean realclean distclean maybe_clobber_profiledbuild upload sdk installer package package-compare stage-package source-package l10n-check
OBJDIR_TARGETS = install export libs clean realclean distclean maybe_clobber_profiledbuild upload sdk installer package package-compare stage-package source-package l10n-check automation/build
#######################################################################
# Rules

Просмотреть файл

@ -1817,6 +1817,10 @@ GK_ATOM(onuserproximity, "onuserproximity")
// light sensor support
GK_ATOM(ondevicelight, "ondevicelight")
// Audio channel events
GK_ATOM(onmozinterruptbegin, "onmozinterruptbegin")
GK_ATOM(onmozinterruptend, "onmozinterruptbegin")
//---------------------------------------------------------------------------
// Special atoms
//---------------------------------------------------------------------------

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/dom/OfflineAudioContextBinding.h"
#include "mozilla/dom/OwningNonNull.h"
#include "MediaStreamGraph.h"
#include "AudioChannelService.h"
#include "AudioDestinationNode.h"
#include "AudioBufferSourceNode.h"
#include "AudioBuffer.h"
@ -131,7 +132,9 @@ AudioContext::Constructor(const GlobalObject& aGlobal,
return nullptr;
}
nsRefPtr<AudioContext> object = new AudioContext(window, false);
nsRefPtr<AudioContext> object =
new AudioContext(window, false,
AudioChannelService::GetDefaultAudioChannel());
RegisterWeakMemoryReporter(object);

Просмотреть файл

@ -67,7 +67,7 @@ class AudioContext MOZ_FINAL : public DOMEventTargetHelper,
{
AudioContext(nsPIDOMWindow* aParentWindow,
bool aIsOffline,
AudioChannel aChannel = AudioChannel::Normal,
AudioChannel aChannel,
uint32_t aNumberOfChannels = 0,
uint32_t aLength = 0,
float aSampleRate = 0.0f);
@ -231,6 +231,9 @@ public:
return aTime - ExtraCurrentTime();
}
IMPL_EVENT_HANDLER(mozinterruptbegin)
IMPL_EVENT_HANDLER(mozinterruptend)
private:
/**
* Returns the amount of extra time added to the current time of the

Просмотреть файл

@ -0,0 +1,5 @@
[DEFAULT]
support-files =
browser_mozAudioChannel.html
[browser_mozAudioChannel.js]

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<meta charset="utf-8">
<title>Test for mozinterruptbegin/end in AudioContext</title>
mozAudioChannelTest = <span id="mozAudioChannelTest">FAIL</span>
<script type="application/javascript">
var ac = new AudioContext();
var buffer = ac.createBuffer(1, 2048, ac.sampleRate);
for (var i = 0; i < 2048; ++i) {
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / ac.sampleRate);
}
var source = ac.createBufferSource();
source.buffer = buffer;
source.connect(ac.destination);
source.start(0);
ac.onmozinterruptbegin = function(evt) {
document.getElementById("mozAudioChannelTest").innerHTML = "mozinterruptbegin";
}
ac.addEventListener('mozinterruptend', function() {
document.getElementById("mozAudioChannelTest").innerHTML = "mozinterruptend";
}, false);
document.getElementById("mozAudioChannelTest").innerHTML = "READY";
</script>

Просмотреть файл

@ -0,0 +1,71 @@
/* 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 whenTabRestored(aTab, aCallback) {
aTab.addEventListener("SSTabRestored", function onRestored(aEvent) {
aTab.removeEventListener("SSTabRestored", onRestored, true);
executeSoon(function executeWhenTabRestored() {
aCallback();
});
}, true);
}
function whenBrowserUnloaded(aBrowser, aCallback) {
aBrowser.addEventListener("unload", function onUnload() {
aBrowser.removeEventListener("unload", onUnload, true);
executeSoon(aCallback);
}, true);
}
function test() {
waitForExplicitFinish();
let testURL = "http://mochi.test:8888/browser/" +
"content/media/webaudio/test/browser_mozAudioChannel.html";
SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", "content" ],
["media.useAudioChannelService", true ]]},
function() {
let tab1 = gBrowser.addTab(testURL);
gBrowser.selectedTab = tab1;
whenBrowserLoaded(tab1.linkedBrowser, function() {
let doc = tab1.linkedBrowser.contentDocument;
is(doc.getElementById("mozAudioChannelTest").textContent, "READY",
"Test is ready to run");
SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", "telephony" ]]},
function() {
let tab2 = gBrowser.duplicateTab(tab1);
gBrowser.selectedTab = tab2;
whenTabRestored(tab2, function() {
is(doc.getElementById("mozAudioChannelTest").textContent, "mozinterruptbegin",
"AudioContext has been muted by the second tab.");
whenBrowserUnloaded(tab2.linkedBrowser, function() {
is(doc.getElementById("mozAudioChannelTest").textContent, "mozinterruptend",
"AudioContext has been unmuted.");
gBrowser.removeTab(tab1);
finish();
});
gBrowser.removeTab(tab2);
gBrowser.selectedTab = tab1;
});
}
);
});
}
);
}

Просмотреть файл

@ -12,3 +12,7 @@ MOCHITEST_MANIFESTS += [
MOCHITEST_CHROME_MANIFESTS += [
'chrome.ini'
]
BROWSER_CHROME_MANIFESTS += [
'browser.ini'
]

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsGlobalWindow.h"
#include "nsJSUtils.h"
#include "nsPerformance.h"
#include "ScriptSettings.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "xpcprivate.h"
@ -323,7 +324,8 @@ private:
wp = wp->GetParent();
}
AutoPushJSContext cx(wp->ParentJSContext());
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
ClearException ce(cx);
nsPIDOMWindow* window = wp->GetWindow();
@ -332,6 +334,8 @@ private:
nsRefPtr<nsGlobalWindow> win = static_cast<nsGlobalWindow*>(window);
NS_ENSURE_TRUE_VOID(win);
JSAutoCompartment ac(cx, win->GetWrapperPreserveColor());
ErrorResult error;
nsRefPtr<Console> console = win->GetConsole(error);
if (error.Failed()) {
@ -432,19 +436,18 @@ private:
wp = wp->GetParent();
}
AutoPushJSContext cx(wp->ParentJSContext());
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
ClearException ce(cx);
JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
NS_ENSURE_TRUE_VOID(global);
JSAutoCompartment ac(cx, global);
nsPIDOMWindow* window = wp->GetWindow();
NS_ENSURE_TRUE_VOID(window);
nsRefPtr<nsGlobalWindow> win = static_cast<nsGlobalWindow*>(window);
NS_ENSURE_TRUE_VOID(win);
JSAutoCompartment ac(cx, win->GetWrapperPreserveColor());
ErrorResult error;
nsRefPtr<Console> console = win->GetConsole(error);
if (error.Failed()) {

Просмотреть файл

@ -13,6 +13,7 @@
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "nsPresContext.h"
#include "ScriptSettings.h"
#include "nsIDocument.h"
#include "nsIDOMFile.h"
@ -271,14 +272,14 @@ PostMessageRunnable::Run()
{
MOZ_ASSERT(mPort);
// Get the JSContext for the target window
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(mPort->GetOwner());
NS_ENSURE_STATE(sgo);
nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
AutoPushJSContext cx(scriptContext ? scriptContext->GetNativeContext()
: nsContentUtils::GetSafeJSContext());
nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(mPort->GetOwner());
if (NS_WARN_IF(!globalObject)) {
return NS_ERROR_UNEXPECTED;
}
MOZ_ASSERT(cx);
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, globalObject->GetGlobalJSObject());
// Deserialize the structured clone data
JS::Rooted<JS::Value> messageData(cx);

Просмотреть файл

@ -20,65 +20,51 @@
namespace mozilla {
namespace dom {
class ScriptSettingsStack;
static mozilla::ThreadLocal<ScriptSettingsStack*> sScriptSettingsTLS;
ScriptSettingsStackEntry ScriptSettingsStackEntry::NoJSAPISingleton;
static mozilla::ThreadLocal<ScriptSettingsStackEntry*> sScriptSettingsTLS;
class ScriptSettingsStack {
public:
static ScriptSettingsStack& Ref() {
return *sScriptSettingsTLS.get();
}
ScriptSettingsStack() {};
void Push(ScriptSettingsStackEntry* aSettings) {
// The bottom-most entry must always be a candidate entry point.
MOZ_ASSERT_IF(mStack.Length() == 0 || mStack.LastElement()->NoJSAPI(),
aSettings->mIsCandidateEntryPoint);
mStack.AppendElement(aSettings);
static ScriptSettingsStackEntry* Top() {
return sScriptSettingsTLS.get();
}
void PushNoJSAPI() {
mStack.AppendElement(&ScriptSettingsStackEntry::NoJSAPISingleton);
static void Push(ScriptSettingsStackEntry *aEntry) {
MOZ_ASSERT(!aEntry->mOlder);
// Whenever JSAPI use is disabled, the next stack entry pushed must
// always be a candidate entry point.
MOZ_ASSERT_IF(!Top() || Top()->NoJSAPI(), aEntry->mIsCandidateEntryPoint);
aEntry->mOlder = Top();
sScriptSettingsTLS.set(aEntry);
}
void Pop() {
MOZ_ASSERT(mStack.Length() > 0);
mStack.RemoveElementAt(mStack.Length() - 1);
static void Pop(ScriptSettingsStackEntry *aEntry) {
MOZ_ASSERT(aEntry == Top());
sScriptSettingsTLS.set(aEntry->mOlder);
}
ScriptSettingsStackEntry* Incumbent() {
if (!mStack.Length()) {
return nullptr;
}
return mStack.LastElement();
}
nsIGlobalObject* IncumbentGlobal() {
ScriptSettingsStackEntry *entry = Incumbent();
static nsIGlobalObject* IncumbentGlobal() {
ScriptSettingsStackEntry *entry = Top();
return entry ? entry->mGlobalObject : nullptr;
}
ScriptSettingsStackEntry* EntryPoint() {
if (!mStack.Length())
static ScriptSettingsStackEntry* EntryPoint() {
ScriptSettingsStackEntry *entry = Top();
if (!entry) {
return nullptr;
for (int i = mStack.Length() - 1; i >= 0; --i) {
if (mStack[i]->mIsCandidateEntryPoint) {
return mStack[i];
}
}
while (entry) {
if (entry->mIsCandidateEntryPoint)
return entry;
entry = entry->mOlder;
}
MOZ_CRASH("Non-empty stack should always have an entry point");
}
nsIGlobalObject* EntryGlobal() {
static nsIGlobalObject* EntryGlobal() {
ScriptSettingsStackEntry *entry = EntryPoint();
return entry ? entry->mGlobalObject : nullptr;
}
private:
// These pointers are caller-owned.
nsTArray<ScriptSettingsStackEntry*> mStack;
};
void
@ -91,16 +77,44 @@ InitScriptSettings()
}
}
ScriptSettingsStack* ptr = new ScriptSettingsStack();
sScriptSettingsTLS.set(ptr);
sScriptSettingsTLS.set(nullptr);
}
void DestroyScriptSettings()
{
ScriptSettingsStack* ptr = sScriptSettingsTLS.get();
MOZ_ASSERT(ptr);
sScriptSettingsTLS.set(nullptr);
delete ptr;
MOZ_ASSERT(sScriptSettingsTLS.get() == nullptr);
}
ScriptSettingsStackEntry::ScriptSettingsStackEntry(nsIGlobalObject *aGlobal,
bool aCandidate)
: mGlobalObject(aGlobal)
, mIsCandidateEntryPoint(aCandidate)
, mOlder(nullptr)
{
MOZ_ASSERT(mGlobalObject);
MOZ_ASSERT(mGlobalObject->GetGlobalJSObject(),
"Must have an actual JS global for the duration on the stack");
MOZ_ASSERT(JS_IsGlobalObject(mGlobalObject->GetGlobalJSObject()),
"No outer windows allowed");
ScriptSettingsStack::Push(this);
}
// This constructor is only for use by AutoNoJSAPI.
ScriptSettingsStackEntry::ScriptSettingsStackEntry()
: mGlobalObject(nullptr)
, mIsCandidateEntryPoint(true)
, mOlder(nullptr)
{
ScriptSettingsStack::Push(this);
}
ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
{
// We must have an actual JS global for the entire time this is on the stack.
MOZ_ASSERT_IF(mGlobalObject, mGlobalObject->GetGlobalJSObject());
ScriptSettingsStack::Pop(this);
}
// This mostly gets the entry global, but doesn't entirely match the spec in
@ -115,7 +129,7 @@ BrokenGetEntryGlobal()
// must be no entry global on the stack.
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx) {
MOZ_ASSERT(ScriptSettingsStack::Ref().EntryGlobal() == nullptr);
MOZ_ASSERT(ScriptSettingsStack::EntryGlobal() == nullptr);
return nullptr;
}
@ -135,7 +149,7 @@ GetIncumbentGlobal()
// global either.
JSContext *cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx) {
MOZ_ASSERT(ScriptSettingsStack::Ref().EntryGlobal() == nullptr);
MOZ_ASSERT(ScriptSettingsStack::EntryGlobal() == nullptr);
return nullptr;
}
@ -149,17 +163,17 @@ GetIncumbentGlobal()
// Ok, nothing from the JS engine. Let's use whatever's on the
// explicit stack.
return ScriptSettingsStack::Ref().IncumbentGlobal();
return ScriptSettingsStack::IncumbentGlobal();
}
nsIPrincipal*
GetWebIDLCallerPrincipal()
{
MOZ_ASSERT(NS_IsMainThread());
ScriptSettingsStackEntry *entry = ScriptSettingsStack::Ref().EntryPoint();
ScriptSettingsStackEntry *entry = ScriptSettingsStack::EntryPoint();
// If we have an entry point that is not the NoJSAPI singleton, we know it
// must be an AutoEntryScript.
// If we have an entry point that is not NoJSAPI, we know it must be an
// AutoEntryScript.
if (!entry || entry->NoJSAPI()) {
return nullptr;
}
@ -248,37 +262,21 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
: AutoJSAPI(aCx ? aCx : FindJSContext(aGlobalObject), aIsMainThread, /* aSkipNullAc = */ true)
, ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
, mAc(cx(), aGlobalObject->GetGlobalJSObject())
, mStack(ScriptSettingsStack::Ref())
, mWebIDLCallerPrincipal(nullptr)
{
MOZ_ASSERT(aGlobalObject);
MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject));
mStack.Push(this);
}
AutoEntryScript::~AutoEntryScript()
{
MOZ_ASSERT(mStack.Incumbent() == this);
mStack.Pop();
}
AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject)
: ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ false)
, mStack(ScriptSettingsStack::Ref())
, mCallerOverride(nsContentUtils::GetCurrentJSContextForThread())
{
mStack.Push(this);
}
AutoIncumbentScript::~AutoIncumbentScript()
{
MOZ_ASSERT(mStack.Incumbent() == this);
mStack.Pop();
}
AutoNoJSAPI::AutoNoJSAPI(bool aIsMainThread)
: mStack(ScriptSettingsStack::Ref())
: ScriptSettingsStackEntry()
{
MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContextForThread(),
!JS_IsExceptionPending(nsContentUtils::GetCurrentJSContextForThread()));
@ -286,12 +284,6 @@ AutoNoJSAPI::AutoNoJSAPI(bool aIsMainThread)
mCxPusher.construct(static_cast<JSContext*>(nullptr),
/* aAllowNull = */ true);
}
mStack.PushNoJSAPI();
}
AutoNoJSAPI::~AutoNoJSAPI()
{
mStack.Pop();
}
} // namespace dom

Просмотреть файл

@ -66,33 +66,25 @@ inline JSObject& IncumbentJSGlobal()
}
class ScriptSettingsStack;
struct ScriptSettingsStackEntry {
class ScriptSettingsStackEntry {
friend class ScriptSettingsStack;
public:
ScriptSettingsStackEntry(nsIGlobalObject *aGlobal, bool aCandidate);
~ScriptSettingsStackEntry();
bool NoJSAPI() { return !mGlobalObject; }
protected:
nsCOMPtr<nsIGlobalObject> mGlobalObject;
bool mIsCandidateEntryPoint;
ScriptSettingsStackEntry(nsIGlobalObject *aGlobal, bool aCandidate)
: mGlobalObject(aGlobal)
, mIsCandidateEntryPoint(aCandidate)
{
MOZ_ASSERT(mGlobalObject);
MOZ_ASSERT(mGlobalObject->GetGlobalJSObject(),
"Must have an actual JS global for the duration on the stack");
MOZ_ASSERT(JS_IsGlobalObject(mGlobalObject->GetGlobalJSObject()),
"No outer windows allowed");
}
~ScriptSettingsStackEntry() {
// We must have an actual JS global for the entire time this is on the stack.
MOZ_ASSERT_IF(mGlobalObject, mGlobalObject->GetGlobalJSObject());
}
bool NoJSAPI() { return this == &NoJSAPISingleton; }
static ScriptSettingsStackEntry NoJSAPISingleton;
private:
ScriptSettingsStackEntry() : mGlobalObject(nullptr)
, mIsCandidateEntryPoint(true)
{}
// This constructor is only for use by AutoNoJSAPI.
friend class AutoNoJSAPI;
ScriptSettingsStackEntry();
ScriptSettingsStackEntry *mOlder;
};
/*
@ -172,7 +164,6 @@ public:
bool aIsMainThread = NS_IsMainThread(),
// Note: aCx is mandatory off-main-thread.
JSContext* aCx = nullptr);
~AutoEntryScript();
void SetWebIDLCallerPrincipal(nsIPrincipal *aPrincipal) {
mWebIDLCallerPrincipal = aPrincipal;
@ -180,7 +171,6 @@ public:
private:
JSAutoCompartment mAc;
dom::ScriptSettingsStack& mStack;
// It's safe to make this a weak pointer, since it's the subject principal
// when we go on the stack, so can't go away until after we're gone. In
// particular, this is only used from the CallSetup constructor, and only in
@ -198,9 +188,7 @@ private:
class AutoIncumbentScript : protected ScriptSettingsStackEntry {
public:
AutoIncumbentScript(nsIGlobalObject* aGlobalObject);
~AutoIncumbentScript();
private:
dom::ScriptSettingsStack& mStack;
JS::AutoHideScriptedCaller mCallerOverride;
};
@ -212,12 +200,10 @@ private:
*
* This class may not be instantiated if an exception is pending.
*/
class AutoNoJSAPI {
class AutoNoJSAPI : protected ScriptSettingsStackEntry {
public:
AutoNoJSAPI(bool aIsMainThread = NS_IsMainThread());
~AutoNoJSAPI();
private:
dom::ScriptSettingsStack& mStack;
mozilla::Maybe<AutoCxPusher> mCxPusher;
};

Просмотреть файл

@ -39,6 +39,7 @@
#include "nsXPCOMCIDInternal.h"
#include "nsIXULRuntime.h"
#include "nsTextFormatter.h"
#include "ScriptSettings.h"
#include "xpcpublic.h"
@ -1632,7 +1633,9 @@ nsresult
nsJSContext::InitClasses(JS::Handle<JSObject*> aGlobalObj)
{
JSOptionChangedCallback(js_options_dot_str, this);
AutoPushJSContext cx(mContext);
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, aGlobalObj);
// Attempt to initialize profiling functions
::JS_DefineProfilingFunctions(cx, aGlobalObj);

Просмотреть файл

@ -20,6 +20,7 @@
#include "mozilla/dom/PContentPermissionRequestChild.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/LazyIdleThread.h"
@ -28,6 +29,7 @@
#include "mozilla/Services.h"
#include "nsAutoPtr.h"
#include "nsGlobalWindow.h"
#include "nsServiceManagerUtils.h"
#include "nsIFile.h"
#include "nsIDirectoryEnumerator.h"
@ -1695,20 +1697,15 @@ JS::Value StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString)
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
if (!sgo) {
JSObject* global =
static_cast<nsGlobalWindow*>(aWindow)->GetWrapperPreserveColor();
if (NS_WARN_IF(!global)) {
return JSVAL_NULL;
}
nsIScriptContext *scriptContext = sgo->GetScriptContext();
if (!scriptContext) {
return JSVAL_NULL;
}
AutoPushJSContext cx(scriptContext->GetNativeContext());
if (!cx) {
return JSVAL_NULL;
}
AutoJSAPI jsapi;
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, global);
JS::Rooted<JS::Value> result(cx);
if (!xpc::StringToJsval(cx, aString, &result)) {

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/dom/MozIccBinding.h"
#include "mozilla/dom/MozStkCommandEvent.h"
#include "mozilla/dom/DOMRequest.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsIDOMIccInfo.h"
#include "nsJSON.h"
#include "nsRadioInterfaceLayer.h"
@ -51,7 +52,9 @@ Icc::NotifyStkEvent(const nsAString& aName, const nsAString& aMessage)
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
NS_ENSURE_SUCCESS(rv, rv);
AutoPushJSContext cx(sc->GetNativeContext());
AutoJSAPIWithErrorsReportedToWindow jsapi(sc);
JSContext* cx = jsapi.cx();
JSAutoCompartment ac(cx, sc->GetWindowProxyPreserveColor());
JS::Rooted<JS::Value> value(cx);
if (!aMessage.IsEmpty()) {

Просмотреть файл

@ -81,3 +81,14 @@ partial interface AudioContext {
[Pref="media.useAudioChannelService", SetterThrows]
attribute AudioChannel mozAudioChannelType;
};
partial interface AudioContext {
// These 2 events are dispatched when the AudioContext object is muted by
// the AudioChannelService. It's call 'interrupt' because when this event is
// dispatched on a HTMLMediaElement, the audio stream is paused.
[Pref="media.useAudioChannelService"]
attribute EventHandler onmozinterruptbegin;
[Pref="media.useAudioChannelService"]
attribute EventHandler onmozinterruptend;
};

Просмотреть файл

@ -5034,6 +5034,7 @@ nsEditor::DetermineCurrentDirection()
{
// Get the current root direction from its frame
nsIContent* rootElement = GetExposedRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
// If we don't have an explicit direction, determine our direction
// from the content's direction

Просмотреть файл

@ -12,13 +12,7 @@ namespace gfx {
TemporaryRef<DataSourceSurface>
DataSourceSurface::GetDataSurface()
{
RefPtr<DataSourceSurface> temp;
if (GetType() == SurfaceType::DATA) {
temp = this;
} else {
temp = new DataSourceSurfaceWrapper(this);
}
return temp;
return (GetType() == SurfaceType::DATA) ? this : new DataSourceSurfaceWrapper(this);
}
}

Просмотреть файл

@ -170,9 +170,8 @@ DrawTargetCG::Snapshot()
if (!mSnapshot) {
if (GetContextType(mCg) == CG_CONTEXT_TYPE_IOSURFACE) {
return new SourceSurfaceCGIOSurfaceContext(this);
} else {
mSnapshot = new SourceSurfaceCGBitmapContext(this);
}
mSnapshot = new SourceSurfaceCGBitmapContext(this);
}
return mSnapshot;
@ -185,10 +184,9 @@ DrawTargetCG::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aForma
// to add that in somehow, but at a higher level
RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
if (newTarget->Init(GetType(), aSize, aFormat)) {
return newTarget;
} else {
return nullptr;
return newTarget.forget();
}
return nullptr;
}
TemporaryRef<SourceSurface>
@ -199,11 +197,11 @@ DrawTargetCG::CreateSourceSurfaceFromData(unsigned char *aData,
{
RefPtr<SourceSurfaceCG> newSurf = new SourceSurfaceCG();
if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
return nullptr;
}
return newSurf;
return newSurf.forget();
}
// This function returns a retained CGImage that needs to be released after
@ -1447,8 +1445,7 @@ DrawTargetCG::Init(BackendType aType, const IntSize &aSize, SurfaceFormat &aForm
TemporaryRef<PathBuilder>
DrawTargetCG::CreatePathBuilder(FillRule aFillRule) const
{
RefPtr<PathBuilderCG> pb = new PathBuilderCG(aFillRule);
return pb;
return new PathBuilderCG(aFillRule);
}
void*

Просмотреть файл

@ -976,9 +976,7 @@ DrawTargetCairo::PopClip()
TemporaryRef<PathBuilder>
DrawTargetCairo::CreatePathBuilder(FillRule aFillRule /* = FillRule::FILL_WINDING */) const
{
RefPtr<PathBuilderCairo> builder = new PathBuilderCairo(aFillRule);
return builder;
return new PathBuilderCairo(aFillRule);
}
void
@ -998,9 +996,7 @@ TemporaryRef<GradientStops>
DrawTargetCairo::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops,
ExtendMode aExtendMode) const
{
RefPtr<GradientStopsCairo> stops = new GradientStopsCairo(aStops, aNumStops,
aExtendMode);
return stops;
return new GradientStopsCairo(aStops, aNumStops, aExtendMode);
}
TemporaryRef<FilterNode>
@ -1059,7 +1055,7 @@ DrawTargetCairo::CreateSourceSurfaceFromData(unsigned char *aData,
RefPtr<SourceSurfaceCairo> source_surf = new SourceSurfaceCairo(surf, aSize, aFormat);
cairo_surface_destroy(surf);
return source_surf;
return source_surf.forget();
}
#ifdef CAIRO_HAS_XLIB_SURFACE
@ -1156,10 +1152,7 @@ DrawTargetCairo::OptimizeSourceSurface(SourceSurface *aSurface) const
IntPoint(0, 0));
dt->Flush();
RefPtr<SourceSurface> surf =
new SourceSurfaceCairo(csurf, size, format);
return surf;
return new SourceSurfaceCairo(csurf, size, format);
#endif
return aSurface;
@ -1175,9 +1168,7 @@ DrawTargetCairo::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurf
return nullptr;
}
cairo_surface_t* surf = static_cast<cairo_surface_t*>(aSurface.mSurface);
RefPtr<SourceSurfaceCairo> source =
new SourceSurfaceCairo(surf, aSurface.mSize, aSurface.mFormat);
return source;
return new SourceSurfaceCairo(surf, aSurface.mSize, aSurface.mFormat);
}
return nullptr;
@ -1193,7 +1184,7 @@ DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFo
if (!cairo_surface_status(similar)) {
RefPtr<DrawTargetCairo> target = new DrawTargetCairo();
target->InitAlreadyReferenced(similar, aSize);
return target;
return target.forget();
}
return nullptr;
@ -1234,7 +1225,7 @@ DrawTargetCairo::CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFor
if (aSigma == 0.0F) {
RefPtr<DrawTargetCairo> target = new DrawTargetCairo();
target->InitAlreadyReferenced(similar, aSize);
return target;
return target.forget();
}
cairo_surface_t* blursurf = cairo_image_surface_create(CAIRO_FORMAT_A8,
@ -1257,7 +1248,7 @@ DrawTargetCairo::CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFor
RefPtr<DrawTargetCairo> target = new DrawTargetCairo();
target->InitAlreadyReferenced(tee, aSize);
return target;
return target.forget();
}
bool

Просмотреть файл

@ -1198,7 +1198,7 @@ DrawTargetD2D::CreateSourceSurfaceFromData(unsigned char *aData,
return nullptr;
}
return newSurf;
return newSurf.forget();
}
TemporaryRef<SourceSurface>
@ -1222,9 +1222,9 @@ DrawTargetD2D::OptimizeSourceSurface(SourceSurface *aSurface) const
data->Unmap();
if (!success) {
return data;
return data.forget();
}
return newSurf;
return newSurf.forget();
}
TemporaryRef<SourceSurface>
@ -1244,7 +1244,7 @@ DrawTargetD2D::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurfac
return nullptr;
}
return newSurf;
return newSurf.forget();
}
TemporaryRef<DrawTarget>
@ -1258,7 +1258,7 @@ DrawTargetD2D::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aForm
return nullptr;
}
return newTarget;
return newTarget.forget();
}
TemporaryRef<PathBuilder>
@ -1498,7 +1498,7 @@ DrawTargetD2D::GetCachedLayer()
}
mCurrentCachedLayer++;
return layer;
return layer.forget();
}
void
@ -1982,7 +1982,7 @@ DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aForm
return nullptr;
}
return rt;
return rt.forget();
}
void
@ -2282,7 +2282,7 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
if (!IsPatternSupportedByD2D(aPattern)) {
RefPtr<ID2D1SolidColorBrush> colBrush;
mRT->CreateSolidColorBrush(D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f), byRef(colBrush));
return colBrush;
return colBrush.forget();
}
if (aPattern.GetType() == PatternType::COLOR) {
@ -2292,8 +2292,9 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
color.b, color.a),
D2D1::BrushProperties(aAlpha),
byRef(colBrush));
return colBrush;
} else if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
return colBrush.forget();
}
if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
RefPtr<ID2D1LinearGradientBrush> gradBrush;
const LinearGradientPattern *pat =
static_cast<const LinearGradientPattern*>(&aPattern);
@ -2313,7 +2314,7 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
mRT->CreateSolidColorBrush(d2dStops.back().color,
D2D1::BrushProperties(aAlpha),
byRef(colBrush));
return colBrush;
return colBrush.forget();
}
mRT->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2DPoint(pat->mBegin),
@ -2321,8 +2322,9 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
stops->mStopCollection,
byRef(gradBrush));
return gradBrush;
} else if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
return gradBrush.forget();
}
if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
RefPtr<ID2D1RadialGradientBrush> gradBrush;
const RadialGradientPattern *pat =
static_cast<const RadialGradientPattern*>(&aPattern);
@ -2343,8 +2345,9 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
stops->mStopCollection,
byRef(gradBrush));
return gradBrush;
} else if (aPattern.GetType() == PatternType::SURFACE) {
return gradBrush.forget();
}
if (aPattern.GetType() == PatternType::SURFACE) {
RefPtr<ID2D1BitmapBrush> bmBrush;
const SurfacePattern *pat =
static_cast<const SurfacePattern*>(&aPattern);
@ -2401,7 +2404,7 @@ DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
byRef(bmBrush));
return bmBrush;
return bmBrush.forget();
}
gfxWarning() << "Invalid pattern type detected.";
@ -2477,7 +2480,7 @@ DrawTargetD2D::CreateGradientTexture(const GradientStopsD2D *aStops)
RefPtr<ID3D10Texture2D> tex;
mDevice->CreateTexture2D(&desc, &data, byRef(tex));
return tex;
return tex.forget();
}
TemporaryRef<ID3D10Texture2D>
@ -2542,7 +2545,7 @@ DrawTargetD2D::CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, cons
return nullptr;
}
return tex;
return tex.forget();
}
void

Просмотреть файл

@ -533,7 +533,7 @@ DrawTargetD2D1::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFor
return nullptr;
}
return dt;
return dt.forget();
}
TemporaryRef<PathBuilder>
@ -797,7 +797,7 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
if (!IsPatternSupportedByD2D(aPattern)) {
RefPtr<ID2D1SolidColorBrush> colBrush;
mDC->CreateSolidColorBrush(D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f), byRef(colBrush));
return colBrush;
return colBrush.forget();
}
if (aPattern.GetType() == PatternType::COLOR) {
@ -807,8 +807,9 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
color.b, color.a),
D2D1::BrushProperties(aAlpha),
byRef(colBrush));
return colBrush;
} else if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
return colBrush.forget();
}
if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
RefPtr<ID2D1LinearGradientBrush> gradBrush;
const LinearGradientPattern *pat =
static_cast<const LinearGradientPattern*>(&aPattern);
@ -828,7 +829,7 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
mDC->CreateSolidColorBrush(d2dStops.back().color,
D2D1::BrushProperties(aAlpha),
byRef(colBrush));
return colBrush;
return colBrush.forget();
}
mDC->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2DPoint(pat->mBegin),
@ -836,8 +837,9 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
stops->mStopCollection,
byRef(gradBrush));
return gradBrush;
} else if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
return gradBrush.forget();
}
if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
RefPtr<ID2D1RadialGradientBrush> gradBrush;
const RadialGradientPattern *pat =
static_cast<const RadialGradientPattern*>(&aPattern);
@ -855,11 +857,12 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
D2DPoint(pat->mCenter1 - pat->mCenter2),
pat->mRadius2, pat->mRadius2),
D2D1::BrushProperties(aAlpha, D2DMatrix(pat->mMatrix)),
stops->mStopCollection,
byRef(gradBrush));
stops->mStopCollection,
byRef(gradBrush));
return gradBrush;
} else if (aPattern.GetType() == PatternType::SURFACE) {
return gradBrush.forget();
}
if (aPattern.GetType() == PatternType::SURFACE) {
const SurfacePattern *pat =
static_cast<const SurfacePattern*>(&aPattern);
@ -881,7 +884,7 @@ DrawTargetD2D1::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
D2DInterpolationMode(pat->mFilter)),
D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
byRef(imageBrush));
return imageBrush;
return imageBrush.forget();
}
gfxWarning() << "Invalid pattern type detected.";
@ -909,16 +912,13 @@ DrawTargetD2D1::GetImageForSurface(SourceSurface *aSurface, Matrix &aSourceTrans
gfxWarning() << "Invalid surface type.";
return nullptr;
}
image = CreatePartialBitmapForSurface(dataSurf, mTransform, mSize, aExtendMode,
aSourceTransform, mDC);
return image;
return CreatePartialBitmapForSurface(dataSurf, mTransform, mSize, aExtendMode,
aSourceTransform, mDC);
}
break;
}
return image;
return image.forget();
}
TemporaryRef<SourceSurface>
@ -943,7 +943,7 @@ DrawTargetD2D1::OptimizeSourceSurface(SourceSurface* aSurface) const
data->Unmap();
if (!bitmap) {
return data;
return data.forget();
}
return new SourceSurfaceD2D1(bitmap.get(), mDC, data->GetFormat(), data->GetSize());

Просмотреть файл

@ -371,7 +371,7 @@ DrawTargetRecording::Snapshot()
mRecorder->RecordEvent(RecordedSnapshot(retSurf, this));
return retSurf;
return retSurf.forget();
}
void
@ -416,7 +416,7 @@ DrawTargetRecording::CreateFilter(FilterType aType)
mRecorder->RecordEvent(RecordedFilterNodeCreation(retNode, aType));
return retNode;
return retNode.forget();
}
void
@ -470,7 +470,7 @@ DrawTargetRecording::CreateSourceSurfaceFromData(unsigned char *aData,
mRecorder->RecordEvent(RecordedSourceSurfaceCreation(retSurf, aData, aStride, aSize, aFormat));
return retSurf;
return retSurf.forget();
}
TemporaryRef<SourceSurface>
@ -503,7 +503,7 @@ DrawTargetRecording::OptimizeSourceSurface(SourceSurface *aSurface) const
dataSurf->GetSize(), dataSurf->GetFormat()));
}
return retSurf;
return retSurf.forget();
}
TemporaryRef<SourceSurface>
@ -531,17 +531,14 @@ DrawTargetRecording::CreateSourceSurfaceFromNativeSurface(const NativeSurface &a
dataSurf->GetSize(), dataSurf->GetFormat()));
}
return retSurf;
return retSurf.forget();
}
TemporaryRef<DrawTarget>
DrawTargetRecording::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
{
RefPtr<DrawTarget> dt = mFinalDT->CreateSimilarDrawTarget(aSize, aFormat);
RefPtr<DrawTarget> retDT = new DrawTargetRecording(mRecorder.get(), dt);
return retDT;
return new DrawTargetRecording(mRecorder.get(), dt);
}
TemporaryRef<PathBuilder>
@ -562,7 +559,7 @@ DrawTargetRecording::CreateGradientStops(GradientStop *aStops,
mRecorder->RecordEvent(RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode));
return retStops;
return retStops.forget();
}
void

Просмотреть файл

@ -135,7 +135,7 @@ DrawTargetSkia::Snapshot()
return nullptr;
}
return snapshot;
return snapshot.forget();
}
static void
@ -587,7 +587,7 @@ DrawTargetSkia::CreateSourceSurfaceFromData(unsigned char *aData,
return nullptr;
}
return newSurf;
return newSurf.forget();
}
TemporaryRef<DrawTarget>
@ -597,7 +597,7 @@ DrawTargetSkia::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFor
if (!target->Init(aSize, aFormat)) {
return nullptr;
}
return target;
return target.forget();
}
bool
@ -638,7 +638,7 @@ DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const
map.mStride,
dataSurf->GetFormat());
dataSurf->Unmap();
return result;
return result.forget();
}
TemporaryRef<SourceSurface>
@ -808,8 +808,7 @@ DrawTargetSkia::GetNativeSurface(NativeSurfaceType aType)
TemporaryRef<PathBuilder>
DrawTargetSkia::CreatePathBuilder(FillRule aFillRule) const
{
RefPtr<PathBuilderSkia> pb = new PathBuilderSkia(aFillRule);
return pb;
return new PathBuilderSkia(aFillRule);
}
void

Просмотреть файл

@ -76,7 +76,7 @@ public:
}
surf->Unmap();
return surf;
return surf.forget();
}
private:
vector<RefPtr<SourceSurface>> mSnapshots;

Просмотреть файл

@ -299,9 +299,7 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
}
if (mRecorder && retVal) {
RefPtr<DrawTarget> recordDT;
recordDT = new DrawTargetRecording(mRecorder, retVal);
return recordDT;
return new DrawTargetRecording(mRecorder, retVal);
}
if (!retVal) {
@ -309,7 +307,7 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
gfxDebug() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize;
}
return retVal;
return retVal.forget();
}
TemporaryRef<DrawTarget>
@ -347,7 +345,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
{
RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
if (newTarget->Init(aBackend, aData, aSize, aStride, aFormat))
return newTarget;
return newTarget.forget();
break;
}
#endif
@ -357,7 +355,7 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
RefPtr<DrawTargetCairo> newTarget;
newTarget = new DrawTargetCairo();
if (newTarget->Init(aData, aSize, aStride, aFormat)) {
retVal = newTarget;
retVal = newTarget.forget();
}
break;
}
@ -368,15 +366,14 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
}
if (mRecorder && retVal) {
RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true);
return recordDT;
return new DrawTargetRecording(mRecorder, retVal, true);
}
if (!retVal) {
gfxDebug() << "Failed to create DrawTarget, Type: " << int(aBackend) << " Size: " << aSize;
}
return retVal;
return retVal.forget();
}
TemporaryRef<DrawTarget>
@ -388,7 +385,7 @@ Factory::CreateTiledDrawTarget(const TileSet& aTileSet)
return nullptr;
}
return dt;
return dt.forget();
}
TemporaryRef<ScaledFont>
@ -453,7 +450,7 @@ Factory::CreateScaledFontWithCairo(const NativeFont& aNativeFont, Float aSize, c
// Therefore, we just reuse CreateScaledFontForNativeFont's implementation.
RefPtr<ScaledFont> font = CreateScaledFontForNativeFont(aNativeFont, aSize);
static_cast<ScaledFontBase*>(font.get())->SetCairoScaledFont(aScaledFont);
return font;
return font.forget();
#else
return nullptr;
#endif
@ -471,7 +468,7 @@ Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
retVal = new DrawTargetRecording(mRecorder, retVal);
}
return retVal;
return retVal.forget();
}
@ -489,7 +486,7 @@ Factory::CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceForma
retVal = new DrawTargetRecording(mRecorder, retVal, true);
}
return retVal;
return retVal.forget();
}
gfxWarning() << "Failed to create draw target for D3D10 texture.";
@ -527,7 +524,7 @@ Factory::CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
retVal = new DrawTargetRecording(mRecorder, retVal);
}
return retVal;
return retVal.forget();
}
void
@ -571,10 +568,7 @@ Factory::GetD2D1Device()
TemporaryRef<GlyphRenderingOptions>
Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams)
{
RefPtr<GlyphRenderingOptions> options =
new GlyphRenderingOptionsDWrite(aParams);
return options;
return new GlyphRenderingOptionsDWrite(aParams);
}
uint64_t
@ -607,7 +601,7 @@ Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
if (!newTarget->InitWithGrContext(aGrContext, aSize, aFormat)) {
return nullptr;
}
return newTarget;
return newTarget.forget();
}
#endif // USE_SKIA_GPU
@ -626,7 +620,7 @@ Factory::CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHintin
options->SetHinting(aHinting);
options->SetAutoHinting(aAutoHinting);
return options;
return options.forget();
}
#endif
@ -644,10 +638,10 @@ Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSiz
if (mRecorder && retVal) {
RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true);
return recordDT;
return recordDT.forget();
}
#endif
return retVal;
return retVal.forget();
}
#ifdef XP_MACOSX
@ -663,10 +657,9 @@ Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize
}
if (mRecorder && retVal) {
RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal);
return recordDT;
return new DrawTargetRecording(mRecorder, retVal);
}
return retVal;
return retVal.forget();
}
#endif
@ -682,7 +675,7 @@ Factory::CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride,
RefPtr<SourceSurfaceRawData> newSurf = new SourceSurfaceRawData();
if (newSurf->InitWrappingData(aData, aSize, aStride, aFormat, false)) {
return newSurf;
return newSurf.forget();
}
return nullptr;
@ -698,7 +691,7 @@ Factory::CreateDataSourceSurface(const IntSize &aSize,
RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
if (newSurf->Init(aSize, aFormat)) {
return newSurf;
return newSurf.forget();
}
return nullptr;
@ -715,7 +708,7 @@ Factory::CreateDataSourceSurfaceWithStride(const IntSize &aSize,
RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
if (newSurf->InitWithStride(aSize, aFormat, aStride)) {
return newSurf;
return newSurf.forget();
}
return nullptr;

Просмотреть файл

@ -282,7 +282,7 @@ CloneAligned(DataSourceSurface* aSource)
if (copy) {
CopyRect(aSource, copy, IntRect(IntPoint(), aSource->GetSize()), IntPoint());
}
return copy;
return copy.forget();
}
static void
@ -518,7 +518,7 @@ GetDataSurfaceInRect(SourceSurface *aSurface,
}
if (!aSurface) {
return target;
return target.forget();
}
RefPtr<DataSourceSurface> dataSource = aSurface->GetDataSurface();
@ -526,7 +526,7 @@ GetDataSurfaceInRect(SourceSurface *aSurface,
if (aEdgeMode == EDGE_MODE_WRAP) {
TileSurface(dataSource, target, intersectInDestSpace.TopLeft());
return target;
return target.forget();
}
CopyRect(dataSource, target, intersectInSourceSpace,
@ -536,7 +536,7 @@ GetDataSurfaceInRect(SourceSurface *aSurface,
DuplicateEdges(target, intersectInDestSpace);
}
return target;
return target.forget();
}
/* static */ TemporaryRef<FilterNode>
@ -623,7 +623,7 @@ FilterNodeSoftware::Create(FilterType aType)
filter = new FilterNodeLightingSoftware<DistantLightSoftware, SpecularLightingSoftware>("FilterNodeLightingSoftware<DistantLight, SpecularLighting>");
break;
}
return filter;
return filter.forget();
}
void
@ -857,7 +857,7 @@ FilterNodeSoftware::GetInputDataSourceSurface(uint32_t aInputEnumIndex,
MOZ_ASSERT(!result || result->GetSize() == aRect.Size(), "wrong surface size");
return result;
return result.forget();
}
IntRect
@ -1022,7 +1022,7 @@ FilterNodeBlendSoftware::Render(const IntRect& aRect)
}
// Third case: one of them is transparent. Return the non-transparent one.
return input1 ? input1 : input2;
return input1 ? input1.forget() : input2.forget();
}
void
@ -1104,7 +1104,7 @@ FilterNodeTransformSoftware::Render(const IntRect& aRect)
Matrix transform = Matrix::Translation(srcRect.x, srcRect.y) * mMatrix *
Matrix::Translation(-aRect.x, -aRect.y);
if (transform.IsIdentity() && srcRect.Size() == aRect.Size()) {
return input;
return input.forget();
}
RefPtr<DrawTarget> dt =
@ -1119,7 +1119,7 @@ FilterNodeTransformSoftware::Render(const IntRect& aRect)
RefPtr<SourceSurface> result = dt->Snapshot();
RefPtr<DataSourceSurface> resultData = result->GetDataSurface();
return resultData;
return resultData.forget();
}
void
@ -1229,7 +1229,7 @@ ApplyMorphology(const IntRect& aSourceRect, DataSourceSurface* aInput,
tmpData, tmpStride, destData, destStride, destRect, ry, aOperator);
}
return dest;
return dest.forget();
}
TemporaryRef<DataSourceSurface>
@ -1248,7 +1248,7 @@ FilterNodeMorphologySoftware::Render(const IntRect& aRect)
int32_t ry = mRadii.height;
if (rx == 0 && ry == 0) {
return input;
return input.forget();
}
return ApplyMorphology(srcRect, input, aRect, rx, ry, mOperator);
@ -1325,7 +1325,7 @@ Premultiply(DataSourceSurface* aSurface)
FilterProcessing::DoPremultiplicationCalculation(
size, targetData, targetStride, inputData, inputStride);
return target;
return target.forget();
}
static TemporaryRef<DataSourceSurface>
@ -1350,7 +1350,7 @@ Unpremultiply(DataSourceSurface* aSurface)
FilterProcessing::DoUnpremultiplicationCalculation(
size, targetData, targetStride, inputData, inputStride);
return target;
return target.forget();
}
TemporaryRef<DataSourceSurface>
@ -1373,7 +1373,7 @@ FilterNodeColorMatrixSoftware::Render(const IntRect& aRect)
result = Premultiply(result);
}
return result;
return result.forget();
}
void
@ -1452,7 +1452,7 @@ FilterNodeFloodSoftware::Render(const IntRect& aRect)
MOZ_CRASH();
}
return target;
return target.forget();
}
// Override GetOutput to get around caching. Rendering simple floods is
@ -1564,7 +1564,7 @@ FilterNodeTileSoftware::Render(const IntRect& aRect)
}
}
return target;
return target.forget();
}
void
@ -1706,7 +1706,7 @@ FilterNodeComponentTransferSoftware::Render(const IntRect& aRect)
SurfaceFormat format = input->GetFormat();
if (format == SurfaceFormat::A8 && mDisableA) {
return input;
return input.forget();
}
RefPtr<DataSourceSurface> target =
@ -1721,7 +1721,7 @@ FilterNodeComponentTransferSoftware::Render(const IntRect& aRect)
TransferComponents<4>(input, target, lookupTables);
}
return target;
return target.forget();
}
void
@ -2426,7 +2426,7 @@ FilterNodeConvolveMatrixSoftware::DoRender(const IntRect& aRect,
}
delete[] intKernel;
return target;
return target.forget();
}
void
@ -2567,7 +2567,7 @@ FilterNodeDisplacementMapSoftware::Render(const IntRect& aRect)
}
}
return target;
return target.forget();
}
void
@ -2824,7 +2824,7 @@ FilterNodeCompositeSoftware::Render(const IntRect& aRect)
}
}
}
return dest;
return dest.forget();
}
void
@ -3429,7 +3429,7 @@ FilterNodeLightingSoftware<LightType, LightingType>::DoRender(const IntRect& aRe
}
}
return target;
return target.forget();
}
DiffuseLightingSoftware::DiffuseLightingSoftware()

Просмотреть файл

@ -26,7 +26,7 @@ FilterProcessing::ExtractAlpha(DataSourceSurface* aSource)
ExtractAlpha_Scalar(size, sourceData, sourceStride, alphaData, alphaStride);
}
return alpha;
return alpha.forget();
}
TemporaryRef<DataSourceSurface>
@ -162,7 +162,7 @@ FilterProcessing::CombineColorChannels(DataSourceSurface* aChannel0, DataSourceS
CombineColorChannels_Scalar(size, resultStride, resultData, channelStride, channel0Data, channel1Data, channel2Data, channel3Data);
}
return result;
return result.forget();
}
void

Просмотреть файл

@ -85,7 +85,7 @@ ApplyBlending_Scalar(DataSourceSurface* aInput1, DataSourceSurface* aInput2)
}
}
return target;
return target.forget();
}
TemporaryRef<DataSourceSurface>

Просмотреть файл

@ -355,7 +355,7 @@ GetTransformedGeometry(ID2D1Geometry *aGeometry, const D2D1_MATRIX_3X2_F &aTrans
aGeometry->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
aTransform, currentSink);
currentSink->Close();
return tmpGeometry;
return tmpGeometry.forget();
}
static TemporaryRef<ID2D1Geometry>
@ -368,7 +368,7 @@ IntersectGeometry(ID2D1Geometry *aGeometryA, ID2D1Geometry *aGeometryB)
aGeometryA->CombineWithGeometry(aGeometryB, D2D1_COMBINE_MODE_INTERSECT, nullptr, sink);
sink->Close();
return pathGeom;
return pathGeom.forget();
}
static TemporaryRef<ID2D1StrokeStyle>
@ -442,7 +442,7 @@ CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions)
gfxWarning() << "Failed to create Direct2D stroke style.";
}
return style;
return style.forget();
}
// This creates a (partially) uploaded bitmap for a DataSourceSurface. It
@ -525,7 +525,7 @@ CreatePartialBitmapForSurface(DataSourceSurface *aSurface, const Matrix &aDestin
aSourceTransform.Translate(uploadRect.x, uploadRect.y);
return bitmap;
return bitmap.forget();
} else {
int Bpp = BytesPerPixel(aSurface->GetFormat());
@ -571,7 +571,7 @@ CreatePartialBitmapForSurface(DataSourceSurface *aSurface, const Matrix &aDestin
aSourceTransform.Scale(Float(size.width / newSize.width),
Float(size.height / newSize.height));
return bitmap;
return bitmap.forget();
}
}

Просмотреть файл

@ -100,16 +100,14 @@ PathBuilderCG::EnsureActive(const Point &aPoint)
TemporaryRef<Path>
PathBuilderCG::Finish()
{
RefPtr<PathCG> path = new PathCG(mCGPath, mFillRule);
return path;
return new PathCG(mCGPath, mFillRule);
}
TemporaryRef<PathBuilder>
PathCG::CopyToBuilder(FillRule aFillRule) const
{
CGMutablePathRef path = CGPathCreateMutableCopy(mPath);
RefPtr<PathBuilderCG> builder = new PathBuilderCG(path, aFillRule);
return builder;
return new PathBuilderCG(path, aFillRule);
}
@ -169,8 +167,7 @@ PathCG::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) c
ta.transform = GfxMatrixToCGAffineTransform(aTransform);
CGPathApply(mPath, &ta, TransformApplier::TranformCGPathApplierFunc);
RefPtr<PathBuilderCG> builder = new PathBuilderCG(ta.path, aFillRule);
return builder;
return new PathBuilderCG(ta.path, aFillRule);
}
static void

Просмотреть файл

@ -167,7 +167,7 @@ PathCairo::CopyToBuilder(FillRule aFillRule) const
builder->mPathData = mPathData;
builder->mCurrentPoint = mCurrentPoint;
return builder;
return builder.forget();
}
TemporaryRef<PathBuilder>
@ -178,7 +178,7 @@ PathCairo::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule
AppendPathToBuilder(builder, &aTransform);
builder->mCurrentPoint = aTransform * mCurrentPoint;
return builder;
return builder.forget();
}
bool

Просмотреть файл

@ -353,7 +353,7 @@ PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule)
pathBuilder->mFigureActive = true;
}
return pathBuilder;
return pathBuilder.forget();
}
void

Просмотреть файл

@ -90,7 +90,7 @@ PathRecording::CopyToBuilder(FillRule aFillRule) const
RefPtr<PathBuilder> pathBuilder = mPath->CopyToBuilder(aFillRule);
RefPtr<PathBuilderRecording> recording = new PathBuilderRecording(pathBuilder, aFillRule);
recording->mPathOps = mPathOps;
return recording;
return recording.forget();
}
TemporaryRef<PathBuilder>
@ -113,7 +113,7 @@ PathRecording::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFill
}
recording->mPathOps.push_back(newPathOp);
}
return recording;
return recording.forget();
}
}

Просмотреть файл

@ -105,8 +105,7 @@ PathBuilderSkia::CurrentPoint() const
TemporaryRef<Path>
PathBuilderSkia::Finish()
{
RefPtr<PathSkia> path = new PathSkia(mPath, mFillRule);
return path;
return new PathSkia(mPath, mFillRule);
}
void
@ -124,8 +123,7 @@ PathSkia::CopyToBuilder(FillRule aFillRule) const
TemporaryRef<PathBuilder>
PathSkia::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
{
RefPtr<PathBuilderSkia> builder = new PathBuilderSkia(aTransform, mPath, aFillRule);
return builder;
return new PathBuilderSkia(aTransform, mPath, aFillRule);
}
bool

Просмотреть файл

@ -379,7 +379,7 @@ RadialGradientEffectD2D1::CreateGradientTexture()
gfxWarning() << "Failed to create resource texture: " << hr;
}
return tex;
return tex.forget();
}
}

Просмотреть файл

@ -118,7 +118,7 @@ ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *a
cairo_destroy(ctx);
}
return newPath;
return newPath.forget();
}
#endif
return nullptr;

Просмотреть файл

@ -96,9 +96,8 @@ ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aT
TemporaryRef<Path> ret = new PathCG(path, FillRule::FILL_WINDING);
CGPathRelease(path);
return ret;
} else {
return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
}
return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
}
void

Просмотреть файл

@ -43,9 +43,7 @@ SourceSurfaceCG::GetDataSurface()
// We also need to make sure that the returned surface has
// surface->GetType() == SurfaceType::DATA.
dataSurf = new DataSourceSurfaceWrapper(dataSurf);
return dataSurf;
return new DataSourceSurfaceWrapper(dataSurf);
}
static void releaseCallback(void *info, const void *data, size_t size) {

Просмотреть файл

@ -81,9 +81,7 @@ SourceSurfaceCairo::GetDataSurface()
// We also need to make sure that the returned surface has
// surface->GetType() == SurfaceType::DATA.
dataSurf = new DataSourceSurfaceWrapper(dataSurf);
return dataSurf;
return new DataSourceSurfaceWrapper(dataSurf);
}
cairo_surface_t*

Просмотреть файл

@ -45,7 +45,7 @@ SourceSurfaceD2D::GetDataSurface()
{
RefPtr<DataSourceSurfaceD2D> result = new DataSourceSurfaceD2D(this);
if (result->IsValid()) {
return result;
return result.forget();
}
return nullptr;
}

Просмотреть файл

@ -72,7 +72,7 @@ SourceSurfaceD2DTarget::GetDataSurface()
}
Factory::GetDirect3D10Device()->CopyResource(dataSurf->mTexture, mTexture);
return dataSurf;
return dataSurf.forget();
}
void*

Просмотреть файл

@ -197,7 +197,11 @@
#define unlikely(expr) (expr)
#endif
#ifndef __GNUC__
/*
* clang-cl supports __attribute__, but MSVC doesn't, so we need to make sure
* we do this if not GNUC but also if not clang either.
*/
#if !defined(__GNUC__) && !defined(__clang__)
#undef __attribute__
#define __attribute__(x)
#endif

Просмотреть файл

@ -330,8 +330,11 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
if (unlikely (buffer->in_error))
return;
/* Ok, let's see... */
/* Make Nikhahit be recognized as a mark when zeroing widths. */
unsigned int end = buffer->out_len;
_hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK);
/* Ok, let's see... */
unsigned int start = end - 2;
while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
start--;

Просмотреть файл

@ -452,26 +452,42 @@ hb_ot_substitute (hb_ot_shape_context_t *c)
/* Position */
static inline void
zero_mark_widths_by_unicode (hb_buffer_t *buffer)
adjust_mark_offsets (hb_glyph_position_t *pos)
{
pos->x_offset -= pos->x_advance;
pos->y_offset -= pos->y_advance;
}
static inline void
zero_mark_width (hb_glyph_position_t *pos)
{
pos->x_advance = 0;
pos->y_advance = 0;
}
static inline void
zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
{
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
{
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
if (adjust_offsets)
adjust_mark_offsets (&buffer->pos[i]);
zero_mark_width (&buffer->pos[i]);
}
}
static inline void
zero_mark_widths_by_gdef (hb_buffer_t *buffer)
zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
{
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_is_mark (&buffer->info[i]))
{
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
if (adjust_offsets)
adjust_mark_offsets (&buffer->pos[i]);
zero_mark_width (&buffer->pos[i]);
}
}
@ -501,16 +517,19 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
{
bool ret = false;
unsigned int count = c->buffer->len;
bool has_positioning = hb_ot_layout_has_positioning (c->face);
bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position ||
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction));
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
zero_mark_widths_by_gdef (c->buffer);
zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
break;
/* Not currently used for any shaper:
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
zero_mark_widths_by_unicode (c->buffer);
zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
break;
*/
@ -521,7 +540,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
break;
}
if (hb_ot_layout_has_positioning (c->face))
if (has_positioning)
{
hb_glyph_info_t *info = c->buffer->info;
hb_glyph_position_t *pos = c->buffer->pos;
@ -550,11 +569,11 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
zero_mark_widths_by_unicode (c->buffer);
zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
break;
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
zero_mark_widths_by_gdef (c->buffer);
zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
break;
default:

Просмотреть файл

@ -357,6 +357,13 @@ public:
NONE, SCROLLABLE
};
/**
* Returns true if aLayer is optimized for the given ThebesLayerCreationHint.
*/
virtual bool IsOptimizedFor(ThebesLayer* aLayer,
ThebesLayerCreationHint aCreationHint)
{ return true; }
/**
* CONSTRUCTION PHASE ONLY
* Create a ThebesLayer for this manager's layer tree.
@ -1549,6 +1556,8 @@ public:
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
}
LayerManager::ThebesLayerCreationHint GetCreationHint() const { return mCreationHint; }
bool UsedForReadback() { return mUsedForReadback; }
void SetUsedForReadback(bool aUsed) { mUsedForReadback = aUsed; }
/**
@ -1562,9 +1571,11 @@ public:
gfxPoint GetResidualTranslation() const { return mResidualTranslation; }
protected:
ThebesLayer(LayerManager* aManager, void* aImplData)
ThebesLayer(LayerManager* aManager, void* aImplData,
LayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE)
: Layer(aManager, aImplData)
, mValidRegion()
, mCreationHint(aCreationHint)
, mUsedForReadback(false)
, mAllowResidualTranslation(false)
{
@ -1580,6 +1591,10 @@ protected:
*/
gfxPoint mResidualTranslation;
nsIntRegion mValidRegion;
/**
* The creation hint that was used when constructing this layer.
*/
const LayerManager::ThebesLayerCreationHint mCreationHint;
/**
* Set when this ThebesLayer is participating in readback, i.e. some
* ReadbackLayer (may) be getting its background from this layer.

Просмотреть файл

@ -73,6 +73,8 @@ public:
virtual void Mutated(Layer* aLayer);
virtual bool IsOptimizedFor(ThebesLayer* aLayer, ThebesLayerCreationHint aHint);
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
virtual already_AddRefed<ThebesLayer> CreateThebesLayerWithHint(ThebesLayerCreationHint aHint);
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();

Просмотреть файл

@ -127,6 +127,22 @@ ClientThebesLayer::RenderLayer()
mContentClient->EndPaint();
}
bool
ClientLayerManager::IsOptimizedFor(ThebesLayer* aLayer, ThebesLayerCreationHint aHint)
{
#ifdef MOZ_B2G
// The only creation hint is whether the layer is scrollable or not, and this
// is only respected on B2G, where it's used to determine whether to use
// tiled layers or not.
// There are pretty nasty performance consequences for not using tiles on
// large, scrollable layers, so we want the layer to be recreated in this
// situation.
return aHint == aLayer->GetCreationHint();
#else
return LayerManager::IsOptimizedFor(aLayer, aHint);
#endif
}
already_AddRefed<ThebesLayer>
ClientLayerManager::CreateThebesLayer()
{
@ -150,19 +166,19 @@ ClientLayerManager::CreateThebesLayerWithHint(ThebesLayerCreationHint aHint)
}
if (gfxPrefs::LayersUseSimpleTiles()) {
nsRefPtr<SimpleClientTiledThebesLayer> layer =
new SimpleClientTiledThebesLayer(this);
new SimpleClientTiledThebesLayer(this, aHint);
CREATE_SHADOW(Thebes);
return layer.forget();
} else {
nsRefPtr<ClientTiledThebesLayer> layer =
new ClientTiledThebesLayer(this);
new ClientTiledThebesLayer(this, aHint);
CREATE_SHADOW(Thebes);
return layer.forget();
}
} else
{
nsRefPtr<ClientThebesLayer> layer =
new ClientThebesLayer(this);
new ClientThebesLayer(this, aHint);
CREATE_SHADOW(Thebes);
return layer.forget();
}

Просмотреть файл

@ -27,15 +27,17 @@ class CompositableClient;
class ShadowableLayer;
class SpecificLayerAttributes;
class ClientThebesLayer : public ThebesLayer,
class ClientThebesLayer : public ThebesLayer,
public ClientLayer {
public:
typedef RotatedContentBuffer::PaintState PaintState;
typedef RotatedContentBuffer::ContentType ContentType;
ClientThebesLayer(ClientLayerManager* aLayerManager) :
ClientThebesLayer(ClientLayerManager* aLayerManager,
LayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE) :
ThebesLayer(aLayerManager,
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST())),
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()),
aCreationHint),
mContentClient(nullptr)
{
MOZ_COUNT_CTOR(ClientThebesLayer);

Просмотреть файл

@ -29,9 +29,11 @@ namespace mozilla {
namespace layers {
ClientTiledThebesLayer::ClientTiledThebesLayer(ClientLayerManager* const aManager)
ClientTiledThebesLayer::ClientTiledThebesLayer(ClientLayerManager* const aManager,
ClientLayerManager::ThebesLayerCreationHint aCreationHint)
: ThebesLayer(aManager,
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()))
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()),
aCreationHint)
, mContentClient()
{
MOZ_COUNT_CTOR(ClientTiledThebesLayer);

Просмотреть файл

@ -41,7 +41,8 @@ class ClientTiledThebesLayer : public ThebesLayer,
typedef ThebesLayer Base;
public:
ClientTiledThebesLayer(ClientLayerManager* const aManager);
ClientTiledThebesLayer(ClientLayerManager* const aManager,
ClientLayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE);
~ClientTiledThebesLayer();
// Override name to distinguish it from ClientThebesLayer in layer dumps

Просмотреть файл

@ -247,9 +247,11 @@ SimpleTiledContentClient::UseTiledLayerBuffer()
mTiledBuffer.ClearPaintedRegion();
}
SimpleClientTiledThebesLayer::SimpleClientTiledThebesLayer(ClientLayerManager* aManager)
SimpleClientTiledThebesLayer::SimpleClientTiledThebesLayer(ClientLayerManager* aManager,
ClientLayerManager::ThebesLayerCreationHint aCreationHint)
: ThebesLayer(aManager,
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()))
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()),
aCreationHint)
, mContentClient()
{
MOZ_COUNT_CTOR(SimpleClientTiledThebesLayer);

Просмотреть файл

@ -159,7 +159,8 @@ class SimpleClientTiledThebesLayer : public ThebesLayer,
typedef ThebesLayer Base;
public:
SimpleClientTiledThebesLayer(ClientLayerManager* const aManager);
SimpleClientTiledThebesLayer(ClientLayerManager* const aManager,
ClientLayerManager::ThebesLayerCreationHint aCreationHint = LayerManager::NONE);
~SimpleClientTiledThebesLayer();
// Thebes Layer

Просмотреть файл

@ -144,6 +144,13 @@ GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
}
ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mTextureHost) {
// Wait until it's ready.
mTextureHost->WaitAcquireFenceSyncComplete();
}
#endif
}
void GrallocTextureSourceOGL::Lock()
@ -443,12 +450,6 @@ GrallocTextureSourceOGL::GetGLTexture()
void
GrallocTextureSourceOGL::BindEGLImage()
{
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mTextureHost) {
mTextureHost->WaitAcquireFenceSyncComplete();
}
#endif
if (mCompositableBackendData) {
CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
backend->BindEGLImage(GetTextureTarget(), mEGLImage);

Просмотреть файл

@ -229,9 +229,12 @@ TextureHostOGL::SetAcquireFence(const android::sp<android::Fence>& aAcquireFence
}
android::sp<android::Fence>
TextureHostOGL::GetAcquireFence()
TextureHostOGL::GetAndResetAcquireFence()
{
return mAcquireFence;
android::sp<android::Fence> fence = mAcquireFence;
// Reset current AcquireFence.
mAcquireFence = android::Fence::NO_FENCE;
return fence;
}
void

Просмотреть файл

@ -174,7 +174,10 @@ public:
virtual void SetAcquireFence(const android::sp<android::Fence>& aAcquireFence);
virtual android::sp<android::Fence> GetAcquireFence();
/**
* Return a acquireFence's Fence and clear a reference to the Fence.
*/
virtual android::sp<android::Fence> GetAndResetAcquireFence();
virtual void WaitAcquireFenceSyncComplete();

Просмотреть файл

@ -7,7 +7,6 @@
#include "mozilla/MemoryReporting.h"
#include "gfxDWriteShaper.h"
#include "gfxHarfBuzzShaper.h"
#include <algorithm>
#include "gfxGraphiteShaper.h"
@ -15,8 +14,6 @@
#include "gfxContext.h"
#include <dwrite.h>
#include "gfxDWriteTextAnalysis.h"
#include "harfbuzz/hb.h"
// Chosen this as to resemble DWrite's own oblique face style.
@ -137,10 +134,30 @@ gfxDWriteFont::CopyWithAntialiasOption(AntialiasOption anAAOption)
&mStyle, mNeedsBold, anAAOption);
}
void
gfxDWriteFont::CreatePlatformShaper()
bool
gfxDWriteFont::ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText,
bool aPreferPlatformShaping)
{
mPlatformShaper = new gfxDWriteShaper(this);
bool ok = false;
if (mGraphiteShaper && gfxPlatform::GetPlatform()->UseGraphiteShaping()) {
ok = mGraphiteShaper->ShapeText(aContext, aText, aOffset, aLength,
aScript, aShapedText);
}
if (!ok && mHarfBuzzShaper) {
ok = mHarfBuzzShaper->ShapeText(aContext, aText, aOffset, aLength,
aScript, aShapedText);
}
PostShapingFixup(aContext, aText, aOffset, aLength, aShapedText);
return ok;
}
const gfxFont::Metrics&
@ -595,7 +612,7 @@ gfxDWriteFont::Measure(gfxTextRun *aTextRun,
}
bool
gfxDWriteFont::ProvidesGlyphWidths()
gfxDWriteFont::ProvidesGlyphWidths() const
{
return !mUseSubpixelPositions ||
(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD);

Просмотреть файл

@ -53,7 +53,7 @@ public:
gfxContext *aContextForTightBoundingBox,
Spacing *aSpacing);
virtual bool ProvidesGlyphWidths();
virtual bool ProvidesGlyphWidths() const;
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
@ -71,9 +71,13 @@ public:
virtual cairo_scaled_font_t *GetCairoScaledFont();
protected:
friend class gfxDWriteShaper;
virtual void CreatePlatformShaper();
virtual bool ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText,
bool aPreferPlatformShaping = false);
bool GetFakeMetricsForArialBlack(DWRITE_FONT_METRICS *aFontMetrics);

Просмотреть файл

@ -1,230 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxDWriteShaper.h"
#include "gfxWindowsPlatform.h"
#include <dwrite.h>
#include "gfxDWriteTextAnalysis.h"
#include "nsCRT.h"
bool
gfxDWriteShaper::ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText)
{
HRESULT hr;
// TODO: Handle TEXT_DISABLE_OPTIONAL_LIGATURES
DWRITE_READING_DIRECTION readingDirection =
aShapedText->IsRightToLeft()
? DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
: DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
gfxDWriteFont *font = static_cast<gfxDWriteFont*>(mFont);
gfxShapedText::CompressedGlyph g;
IDWriteTextAnalyzer *analyzer =
gfxWindowsPlatform::GetPlatform()->GetDWriteAnalyzer();
if (!analyzer) {
return false;
}
/**
* There's an internal 16-bit limit on some things inside the analyzer,
* but we never attempt to shape a word longer than 32K characters
* in a single call, so we cannot exceed that limit.
*/
UINT32 length = aLength;
char16ptr_t text = aText;
TextAnalysis analysis(text, length, nullptr, readingDirection);
TextAnalysis::Run *runHead;
hr = analysis.GenerateResults(analyzer, &runHead);
if (FAILED(hr)) {
NS_WARNING("Analyzer failed to generate results.");
return false;
}
int32_t appUnitsPerDevPixel = aShapedText->GetAppUnitsPerDevUnit();
UINT32 maxGlyphs = 0;
trymoreglyphs:
if ((UINT32_MAX - 3 * length / 2 + 16) < maxGlyphs) {
// This isn't going to work, we're going to cross the UINT32 upper
// limit. Give up.
NS_WARNING("Shaper needs to generate more than 2^32 glyphs?!");
return false;
}
maxGlyphs += 3 * length / 2 + 16;
AutoFallibleTArray<UINT16, 400> clusters;
AutoFallibleTArray<UINT16, 400> indices;
AutoFallibleTArray<DWRITE_SHAPING_TEXT_PROPERTIES, 400> textProperties;
AutoFallibleTArray<DWRITE_SHAPING_GLYPH_PROPERTIES, 400> glyphProperties;
if (!clusters.SetLength(length) ||
!indices.SetLength(maxGlyphs) ||
!textProperties.SetLength(maxGlyphs) ||
!glyphProperties.SetLength(maxGlyphs)) {
NS_WARNING("Shaper failed to allocate memory.");
return false;
}
UINT32 actualGlyphs;
hr = analyzer->GetGlyphs(text, length,
font->GetFontFace(), FALSE,
readingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT,
&runHead->mScript, nullptr, nullptr, nullptr, nullptr, 0,
maxGlyphs, clusters.Elements(), textProperties.Elements(),
indices.Elements(), glyphProperties.Elements(), &actualGlyphs);
if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
// We increase the amount of glyphs and try again.
goto trymoreglyphs;
}
if (FAILED(hr)) {
NS_WARNING("Analyzer failed to get glyphs.");
return false;
}
WORD gID = indices[0];
AutoFallibleTArray<FLOAT, 400> advances;
AutoFallibleTArray<DWRITE_GLYPH_OFFSET, 400> glyphOffsets;
if (!advances.SetLength(actualGlyphs) ||
!glyphOffsets.SetLength(actualGlyphs)) {
NS_WARNING("Shaper failed to allocate memory.");
return false;
}
if (!static_cast<gfxDWriteFont*>(mFont)->mUseSubpixelPositions) {
hr = analyzer->GetGdiCompatibleGlyphPlacements(
text,
clusters.Elements(),
textProperties.Elements(),
length,
indices.Elements(),
glyphProperties.Elements(),
actualGlyphs,
font->GetFontFace(),
font->GetAdjustedSize(),
1.0,
nullptr,
FALSE,
FALSE,
FALSE,
&runHead->mScript,
nullptr,
nullptr,
nullptr,
0,
advances.Elements(),
glyphOffsets.Elements());
} else {
hr = analyzer->GetGlyphPlacements(text,
clusters.Elements(),
textProperties.Elements(),
length,
indices.Elements(),
glyphProperties.Elements(),
actualGlyphs,
font->GetFontFace(),
font->GetAdjustedSize(),
FALSE,
FALSE,
&runHead->mScript,
nullptr,
nullptr,
nullptr,
0,
advances.Elements(),
glyphOffsets.Elements());
}
if (FAILED(hr)) {
NS_WARNING("Analyzer failed to get glyph placements.");
return false;
}
nsAutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs;
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs();
for (unsigned int c = 0; c < length; c++) {
uint32_t k = clusters[c];
uint32_t absC = aOffset + c;
if (c > 0 && k == clusters[c - 1]) {
// This is a cluster continuation. No glyph here.
gfxShapedText::CompressedGlyph &g = charGlyphs[absC];
NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
g.SetComplex(g.IsClusterStart(), false, 0);
continue;
}
// Count glyphs for this character
uint32_t glyphCount = actualGlyphs - k;
uint32_t nextClusterOffset;
for (nextClusterOffset = c + 1;
nextClusterOffset < length; ++nextClusterOffset) {
if (clusters[nextClusterOffset] > k) {
glyphCount = clusters[nextClusterOffset] - k;
break;
}
}
int32_t advance = (int32_t)(advances[k] * appUnitsPerDevPixel);
if (glyphCount == 1 && advance >= 0 &&
glyphOffsets[k].advanceOffset == 0 &&
glyphOffsets[k].ascenderOffset == 0 &&
charGlyphs[absC].IsClusterStart() &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(advance) &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(indices[k])) {
charGlyphs[absC].SetSimpleGlyph(advance, indices[k]);
} else {
if (detailedGlyphs.Length() < glyphCount) {
if (!detailedGlyphs.AppendElements(
glyphCount - detailedGlyphs.Length())) {
continue;
}
}
float totalAdvance = 0;
for (unsigned int z = 0; z < glyphCount; z++) {
detailedGlyphs[z].mGlyphID = indices[k + z];
detailedGlyphs[z].mAdvance =
(int32_t)(advances[k + z]
* appUnitsPerDevPixel);
if (readingDirection ==
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT) {
detailedGlyphs[z].mXOffset =
(totalAdvance +
glyphOffsets[k + z].advanceOffset)
* appUnitsPerDevPixel;
} else {
detailedGlyphs[z].mXOffset =
glyphOffsets[k + z].advanceOffset *
appUnitsPerDevPixel;
}
detailedGlyphs[z].mYOffset =
-glyphOffsets[k + z].ascenderOffset *
appUnitsPerDevPixel;
totalAdvance += advances[k + z];
}
aShapedText->SetGlyphs(
absC,
g.SetComplex(charGlyphs[absC].IsClusterStart(),
true,
glyphCount),
detailedGlyphs.Elements());
}
}
return true;
}

Просмотреть файл

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_DWRITESHAPER_H
#define GFX_DWRITESHAPER_H
#include "gfxDWriteFonts.h"
/**
* \brief Class representing a DWrite font shaper.
*/
class gfxDWriteShaper : public gfxFontShaper
{
public:
gfxDWriteShaper(gfxDWriteFont *aFont)
: gfxFontShaper(aFont)
{
MOZ_COUNT_CTOR(gfxDWriteShaper);
}
virtual ~gfxDWriteShaper()
{
MOZ_COUNT_DTOR(gfxDWriteShaper);
}
virtual bool ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText);
};
#endif /* GFX_DWRITESHAPER_H */

Просмотреть файл

@ -1,257 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxDWriteTextAnalysis.h"
TextAnalysis::TextAnalysis(const wchar_t* text,
UINT32 textLength,
const wchar_t* localeName,
DWRITE_READING_DIRECTION readingDirection)
: mText(text)
, mTextLength(textLength)
, mLocaleName(localeName)
, mReadingDirection(readingDirection)
, mCurrentRun(nullptr)
{
}
TextAnalysis::~TextAnalysis()
{
// delete runs, except mRunHead which is part of the TextAnalysis object
for (Run *run = mRunHead.nextRun; run;) {
Run *origRun = run;
run = run->nextRun;
delete origRun;
}
}
STDMETHODIMP
TextAnalysis::GenerateResults(IDWriteTextAnalyzer* textAnalyzer,
OUT Run **runHead)
{
// Analyzes the text using the script analyzer and returns
// the result as a series of runs.
HRESULT hr = S_OK;
// Initially start out with one result that covers the entire range.
// This result will be subdivided by the analysis processes.
mRunHead.mTextStart = 0;
mRunHead.mTextLength = mTextLength;
mRunHead.mBidiLevel =
(mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
mRunHead.nextRun = nullptr;
mCurrentRun = &mRunHead;
// Call each of the analyzers in sequence, recording their results.
if (SUCCEEDED(hr = textAnalyzer->AnalyzeScript(this,
0,
mTextLength,
this))) {
*runHead = &mRunHead;
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// IDWriteTextAnalysisSource source implementation
IFACEMETHODIMP
TextAnalysis::GetTextAtPosition(UINT32 textPosition,
OUT WCHAR const** textString,
OUT UINT32* textLength)
{
if (textPosition >= mTextLength) {
// No text at this position, valid query though.
*textString = nullptr;
*textLength = 0;
} else {
*textString = mText + textPosition;
*textLength = mTextLength - textPosition;
}
return S_OK;
}
IFACEMETHODIMP
TextAnalysis::GetTextBeforePosition(UINT32 textPosition,
OUT WCHAR const** textString,
OUT UINT32* textLength)
{
if (textPosition == 0 || textPosition > mTextLength) {
// Either there is no text before here (== 0), or this
// is an invalid position. The query is considered valid thouh.
*textString = nullptr;
*textLength = 0;
} else {
*textString = mText;
*textLength = textPosition;
}
return S_OK;
}
DWRITE_READING_DIRECTION STDMETHODCALLTYPE
TextAnalysis::GetParagraphReadingDirection()
{
// We support only a single reading direction.
return mReadingDirection;
}
IFACEMETHODIMP
TextAnalysis::GetLocaleName(UINT32 textPosition,
OUT UINT32* textLength,
OUT WCHAR const** localeName)
{
// Single locale name is used, valid until the end of the string.
*localeName = mLocaleName;
*textLength = mTextLength - textPosition;
return S_OK;
}
IFACEMETHODIMP
TextAnalysis::GetNumberSubstitution(UINT32 textPosition,
OUT UINT32* textLength,
OUT IDWriteNumberSubstitution** numberSubstitution)
{
// We do not support number substitution.
*numberSubstitution = nullptr;
*textLength = mTextLength - textPosition;
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////
// IDWriteTextAnalysisSink implementation
IFACEMETHODIMP
TextAnalysis::SetLineBreakpoints(UINT32 textPosition,
UINT32 textLength,
DWRITE_LINE_BREAKPOINT const* lineBreakpoints)
{
// We don't use this for now.
return S_OK;
}
IFACEMETHODIMP
TextAnalysis::SetScriptAnalysis(UINT32 textPosition,
UINT32 textLength,
DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis)
{
SetCurrentRun(textPosition);
SplitCurrentRun(textPosition);
while (textLength > 0) {
Run *run = FetchNextRun(&textLength);
run->mScript = *scriptAnalysis;
}
return S_OK;
}
IFACEMETHODIMP
TextAnalysis::SetBidiLevel(UINT32 textPosition,
UINT32 textLength,
UINT8 explicitLevel,
UINT8 resolvedLevel)
{
// We don't use this for now.
return S_OK;
}
IFACEMETHODIMP
TextAnalysis::SetNumberSubstitution(UINT32 textPosition,
UINT32 textLength,
IDWriteNumberSubstitution* numberSubstitution)
{
// We don't use this for now.
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////
// Run modification.
TextAnalysis::Run *
TextAnalysis::FetchNextRun(IN OUT UINT32* textLength)
{
// Used by the sink setters, this returns a reference to the next run.
// Position and length are adjusted to now point after the current run
// being returned.
Run *origRun = mCurrentRun;
// Split the tail if needed (the length remaining is less than the
// current run's size).
if (*textLength < mCurrentRun->mTextLength) {
SplitCurrentRun(mCurrentRun->mTextStart + *textLength);
} else {
// Just advance the current run.
mCurrentRun = mCurrentRun->nextRun;
}
*textLength -= origRun->mTextLength;
// Return a reference to the run that was just current.
return origRun;
}
void TextAnalysis::SetCurrentRun(UINT32 textPosition)
{
// Move the current run to the given position.
// Since the analyzers generally return results in a forward manner,
// this will usually just return early. If not, find the
// corresponding run for the text position.
if (mCurrentRun && mCurrentRun->ContainsTextPosition(textPosition)) {
return;
}
for (Run *run = &mRunHead; run; run = run->nextRun) {
if (run->ContainsTextPosition(textPosition)) {
mCurrentRun = run;
return;
}
}
NS_NOTREACHED("We should always be able to find the text position in one \
of our runs");
}
void TextAnalysis::SplitCurrentRun(UINT32 splitPosition)
{
if (!mCurrentRun) {
NS_ASSERTION(false, "SplitCurrentRun called without current run.");
// Shouldn't be calling this when no current run is set!
return;
}
// Split the current run.
if (splitPosition <= mCurrentRun->mTextStart) {
// No need to split, already the start of a run
// or before it. Usually the first.
return;
}
Run *newRun = new Run;
*newRun = *mCurrentRun;
// Insert the new run in our linked list.
newRun->nextRun = mCurrentRun->nextRun;
mCurrentRun->nextRun = newRun;
// Adjust runs' text positions and lengths.
UINT32 splitPoint = splitPosition - mCurrentRun->mTextStart;
newRun->mTextStart += splitPoint;
newRun->mTextLength -= splitPoint;
mCurrentRun->mTextLength = splitPoint;
mCurrentRun = newRun;
}

Просмотреть файл

@ -1,146 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_DWRITETEXTANALYSIS_H
#define GFX_DWRITETEXTANALYSIS_H
#include "gfxDWriteCommon.h"
// Helper source/sink class for text analysis.
class TextAnalysis
: public IDWriteTextAnalysisSource,
public IDWriteTextAnalysisSink
{
public:
// IUnknown interface
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject)
{
if (iid == __uuidof(IDWriteTextAnalysisSource)) {
*ppObject = static_cast<IDWriteTextAnalysisSource*>(this);
return S_OK;
} else if (iid == __uuidof(IDWriteTextAnalysisSink)) {
*ppObject = static_cast<IDWriteTextAnalysisSink*>(this);
return S_OK;
} else if (iid == __uuidof(IUnknown)) {
*ppObject =
static_cast<IUnknown*>(static_cast<IDWriteTextAnalysisSource*>(this));
return S_OK;
} else {
return E_NOINTERFACE;
}
}
IFACEMETHOD_(ULONG, AddRef)()
{
return 1;
}
IFACEMETHOD_(ULONG, Release)()
{
return 1;
}
// A single contiguous run of characters containing the same analysis
// results.
struct Run
{
UINT32 mTextStart; // starting text position of this run
UINT32 mTextLength; // number of contiguous code units covered
UINT32 mGlyphStart; // starting glyph in the glyphs array
UINT32 mGlyphCount; // number of glyphs associated with this run of
// text
DWRITE_SCRIPT_ANALYSIS mScript;
UINT8 mBidiLevel;
bool mIsSideways;
inline bool ContainsTextPosition(UINT32 aTextPosition) const
{
return aTextPosition >= mTextStart
&& aTextPosition < mTextStart + mTextLength;
}
Run *nextRun;
};
public:
TextAnalysis(const wchar_t* text,
UINT32 textLength,
const wchar_t* localeName,
DWRITE_READING_DIRECTION readingDirection);
~TextAnalysis();
STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer,
Run **runHead);
// IDWriteTextAnalysisSource implementation
IFACEMETHODIMP GetTextAtPosition(UINT32 textPosition,
OUT WCHAR const** textString,
OUT UINT32* textLength);
IFACEMETHODIMP GetTextBeforePosition(UINT32 textPosition,
OUT WCHAR const** textString,
OUT UINT32* textLength);
IFACEMETHODIMP_(DWRITE_READING_DIRECTION)
GetParagraphReadingDirection() throw();
IFACEMETHODIMP GetLocaleName(UINT32 textPosition,
OUT UINT32* textLength,
OUT WCHAR const** localeName);
IFACEMETHODIMP
GetNumberSubstitution(UINT32 textPosition,
OUT UINT32* textLength,
OUT IDWriteNumberSubstitution** numberSubstitution);
// IDWriteTextAnalysisSink implementation
IFACEMETHODIMP
SetScriptAnalysis(UINT32 textPosition,
UINT32 textLength,
DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis);
IFACEMETHODIMP
SetLineBreakpoints(UINT32 textPosition,
UINT32 textLength,
const DWRITE_LINE_BREAKPOINT* lineBreakpoints);
IFACEMETHODIMP SetBidiLevel(UINT32 textPosition,
UINT32 textLength,
UINT8 explicitLevel,
UINT8 resolvedLevel);
IFACEMETHODIMP
SetNumberSubstitution(UINT32 textPosition,
UINT32 textLength,
IDWriteNumberSubstitution* numberSubstitution);
protected:
Run *FetchNextRun(IN OUT UINT32* textLength);
void SetCurrentRun(UINT32 textPosition);
void SplitCurrentRun(UINT32 splitPosition);
protected:
// Input
// (weak references are fine here, since this class is a transient
// stack-based helper that doesn't need to copy data)
UINT32 mTextLength;
const wchar_t* mText;
const wchar_t* mLocaleName;
DWRITE_READING_DIRECTION mReadingDirection;
// Current processing state.
Run *mCurrentRun;
// Output is a list of runs starting here
Run mRunHead;
};
#endif /* GFX_DWRITETEXTANALYSIS_H */

Просмотреть файл

@ -25,7 +25,7 @@ public:
virtual uint32_t GetSpaceGlyph();
virtual bool ProvidesGetGlyph() const { return true; }
virtual uint32_t GetGlyph(uint32_t unicode, uint32_t variation_selector);
virtual bool ProvidesGlyphWidths() { return true; }
virtual bool ProvidesGlyphWidths() const { return true; }
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
cairo_scaled_font_t *CairoScaledFont() { return mScaledFont; };

Просмотреть файл

@ -3983,7 +3983,6 @@ gfxFont::ShapeText(gfxContext *aContext,
if (!ok) {
if (!mPlatformShaper) {
CreatePlatformShaper();
NS_ASSERTION(mPlatformShaper, "no platform shaper available!");
}
if (mPlatformShaper) {
ok = mPlatformShaper->ShapeText(aContext, aText, aOffset, aLength,

Просмотреть файл

@ -1952,7 +1952,7 @@ protected:
// subclasses may provide (possibly hinted) glyph widths (in font units);
// if they do not override this, harfbuzz will use unhinted widths
// derived from the font tables
virtual bool ProvidesGlyphWidths() {
virtual bool ProvidesGlyphWidths() const {
return false;
}

Просмотреть файл

@ -8,8 +8,6 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/WindowsVersion.h"
#include "gfxGDIShaper.h"
#include "gfxUniscribeShaper.h"
#include "gfxHarfBuzzShaper.h"
#include <algorithm>
#include "gfxGraphiteShaper.h"
@ -51,14 +49,13 @@ gfxGDIFont::gfxGDIFont(GDIFontEntry *aFontEntry,
mFontFace(nullptr),
mMetrics(nullptr),
mSpaceGlyph(0),
mNeedsBold(aNeedsBold)
mNeedsBold(aNeedsBold),
mScriptCache(nullptr)
{
if (FontCanSupportGraphite()) {
mGraphiteShaper = new gfxGraphiteShaper(this);
}
if (FontCanSupportHarfBuzz()) {
mHarfBuzzShaper = new gfxHarfBuzzShaper(this);
}
mHarfBuzzShaper = new gfxHarfBuzzShaper(this);
}
gfxGDIFont::~gfxGDIFont()
@ -72,15 +69,12 @@ gfxGDIFont::~gfxGDIFont()
if (mFont) {
::DeleteObject(mFont);
}
if (mScriptCache) {
ScriptFreeCache(&mScriptCache);
}
delete mMetrics;
}
void
gfxGDIFont::CreatePlatformShaper()
{
mPlatformShaper = new gfxGDIShaper(this);
}
gfxFont*
gfxGDIFont::CopyWithAntialiasOption(AntialiasOption anAAOption)
{
@ -88,29 +82,6 @@ gfxGDIFont::CopyWithAntialiasOption(AntialiasOption anAAOption)
&mStyle, mNeedsBold, anAAOption);
}
static bool
UseUniscribe(gfxShapedText *aShapedText,
char16ptr_t aText,
uint32_t aLength)
{
uint32_t flags = aShapedText->Flags();
bool useGDI;
bool isXP = !IsVistaOrLater();
// bug 561304 - Uniscribe bug produces bad positioning at certain
// font sizes on XP, so default to GDI on XP using logic of 3.6
useGDI = isXP &&
(flags &
(gfxTextRunFactory::TEXT_OPTIMIZE_SPEED |
gfxTextRunFactory::TEXT_IS_RTL)
) == gfxTextRunFactory::TEXT_OPTIMIZE_SPEED;
return !useGDI ||
ScriptIsComplex(aText, aLength, SIC_COMPLEX) == S_OK;
}
bool
gfxGDIFont::ShapeText(gfxContext *aContext,
const char16_t *aText,
@ -128,8 +99,6 @@ gfxGDIFont::ShapeText(gfxContext *aContext,
return false;
}
bool ok = false;
// Ensure the cairo font is set up, so there's no risk it'll fall back to
// creating a "toy" font internally (see bug 544617).
// We must check that this succeeded, otherwise we risk cairo creating the
@ -138,83 +107,8 @@ gfxGDIFont::ShapeText(gfxContext *aContext,
return false;
}
if (mGraphiteShaper && gfxPlatform::GetPlatform()->UseGraphiteShaping()) {
ok = mGraphiteShaper->ShapeText(aContext, aText,
aOffset, aLength,
aScript, aShapedText);
}
if (!ok && mHarfBuzzShaper) {
if (gfxPlatform::GetPlatform()->UseHarfBuzzForScript(aScript) ||
(!IsVistaOrLater() &&
ScriptShapingType(aScript) == SHAPING_INDIC &&
!Preferences::GetBool("gfx.font_rendering.winxp-indic-uniscribe",
false))) {
ok = mHarfBuzzShaper->ShapeText(aContext, aText, aOffset, aLength,
aScript, aShapedText);
}
}
if (!ok) {
GDIFontEntry *fe = static_cast<GDIFontEntry*>(GetFontEntry());
bool preferUniscribe =
(!fe->IsTrueType() || fe->IsSymbolFont()) && !fe->mForceGDI;
if (preferUniscribe || UseUniscribe(aShapedText, aText, aLength)) {
// first try Uniscribe
if (!mUniscribeShaper) {
mUniscribeShaper = new gfxUniscribeShaper(this);
}
ok = mUniscribeShaper->ShapeText(aContext, aText, aOffset, aLength,
aScript, aShapedText);
if (!ok) {
// fallback to GDI shaping
if (!mPlatformShaper) {
CreatePlatformShaper();
}
ok = mPlatformShaper->ShapeText(aContext, aText, aOffset,
aLength, aScript, aShapedText);
}
} else {
// first use GDI
if (!mPlatformShaper) {
CreatePlatformShaper();
}
ok = mPlatformShaper->ShapeText(aContext, aText, aOffset, aLength,
aScript, aShapedText);
if (!ok) {
// try Uniscribe if GDI failed
if (!mUniscribeShaper) {
mUniscribeShaper = new gfxUniscribeShaper(this);
}
// use Uniscribe shaping
ok = mUniscribeShaper->ShapeText(aContext, aText,
aOffset, aLength,
aScript, aShapedText);
}
}
#if DEBUG
if (!ok) {
NS_ConvertUTF16toUTF8 name(GetName());
char msg[256];
sprintf(msg,
"text shaping with both uniscribe and GDI failed for"
" font: %s",
name.get());
NS_WARNING(msg);
}
#endif
}
PostShapingFixup(aContext, aText, aOffset, aLength, aShapedText);
return ok;
return gfxFont::ShapeText(aContext, aText, aOffset, aLength, aScript,
aShapedText, aPreferPlatformShaping);
}
const gfxFont::Metrics&
@ -537,6 +431,43 @@ gfxGDIFont::FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize,
}
}
uint32_t
gfxGDIFont::GetGlyph(uint32_t aUnicode, uint32_t aVarSelector)
{
// Callback used only for fonts that lack a 'cmap' table.
// We don't support variation selector sequences or non-BMP characters
// in the legacy bitmap, vector or postscript fonts that might use
// this code path.
if (aUnicode > 0xffff || aVarSelector) {
return 0;
}
if (!mGlyphIDs) {
mGlyphIDs = new nsDataHashtable<nsUint32HashKey,uint32_t>(128);
}
uint32_t gid;
if (mGlyphIDs->Get(aUnicode, &gid)) {
return gid;
}
wchar_t ch = aUnicode;
WORD glyph;
DWORD ret = ScriptGetCMap(nullptr, &mScriptCache, &ch, 1, 0, &glyph);
if (ret == E_PENDING) {
AutoDC dc;
AutoSelectFont fs(dc.GetDC(), GetHFONT());
ret = ScriptGetCMap(dc.GetDC(), &mScriptCache, &ch, 1, 0, &glyph);
}
if (ret != S_OK) {
glyph = 0;
}
mGlyphIDs->Put(aUnicode, glyph);
return glyph;
}
int32_t
gfxGDIFont::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID)
{

Просмотреть файл

@ -14,6 +14,7 @@
#include "nsHashKeys.h"
#include "cairo.h"
#include "usp10.h"
class gfxGDIFont : public gfxFont
{
@ -49,7 +50,15 @@ public:
/* required for MathML to suppress effects of ClearType "padding" */
virtual gfxFont* CopyWithAntialiasOption(AntialiasOption anAAOption);
virtual bool ProvidesGlyphWidths() { return true; }
// If the font has a cmap table, we handle it purely with harfbuzz;
// but if not (e.g. .fon fonts), we'll use a GDI callback to get glyphs.
virtual bool ProvidesGetGlyph() const {
return !mFontEntry->HasCmapTable();
}
virtual uint32_t GetGlyph(uint32_t aUnicode, uint32_t aVarSelector);
virtual bool ProvidesGlyphWidths() const { return true; }
// get hinted glyph width in pixels as 16.16 fixed-point value
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
@ -62,9 +71,7 @@ public:
virtual FontType GetType() const { return FONT_TYPE_GDI; }
protected:
virtual void CreatePlatformShaper();
/* override to check for uniscribe failure and fall back to GDI */
/* override to ensure the cairo font is set up properly */
virtual bool ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
@ -80,10 +87,6 @@ protected:
// italics.
void FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize, bool aUseGDIFakeItalic);
// mPlatformShaper is used for the GDI shaper, mUniscribeShaper
// for the Uniscribe version if needed
nsAutoPtr<gfxFontShaper> mUniscribeShaper;
HFONT mFont;
cairo_font_face_t *mFontFace;
@ -92,6 +95,10 @@ protected:
bool mNeedsBold;
// cache of glyph IDs (used for non-sfnt fonts only)
nsAutoPtr<nsDataHashtable<nsUint32HashKey,uint32_t> > mGlyphIDs;
SCRIPT_CACHE mScriptCache;
// cache of glyph widths in 16.16 fixed-point pixels
nsAutoPtr<nsDataHashtable<nsUint32HashKey,int32_t> > mGlyphWidths;
};

Просмотреть файл

@ -1,96 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//#define FORCE_PR_LOG
#include "gfxGDIShaper.h"
/**********************************************************************
*
* class gfxGDIShaper
*
**********************************************************************/
bool
gfxGDIShaper::ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText)
{
DCFromContext dc(aContext);
AutoSelectFont selectFont(dc, static_cast<gfxGDIFont*>(mFont)->GetHFONT());
uint32_t length = aLength;
AutoFallibleTArray<WORD,500> glyphArray;
if (!glyphArray.SetLength(length)) {
return false;
}
WORD *glyphs = glyphArray.Elements();
DWORD ret = ::GetGlyphIndicesW(dc, char16ptr_t(aText), length,
glyphs, GGI_MARK_NONEXISTING_GLYPHS);
if (ret == GDI_ERROR) {
return false;
}
for (int k = 0; k < length; k++) {
if (glyphs[k] == 0xFFFF)
return false;
}
SIZE size;
AutoFallibleTArray<int,500> partialWidthArray;
if (!partialWidthArray.SetLength(length)) {
return false;
}
BOOL success = ::GetTextExtentExPointI(dc,
glyphs,
length,
INT_MAX,
nullptr,
partialWidthArray.Elements(),
&size);
if (!success) {
return false;
}
gfxTextRun::CompressedGlyph g;
gfxTextRun::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs();
uint32_t i;
int32_t lastWidth = 0;
int32_t appUnitsPerDevPixel = aShapedText->GetAppUnitsPerDevUnit();
for (i = 0; i < length; ++i) {
uint32_t offset = aOffset + i;
int32_t advancePixels = partialWidthArray[i] - lastWidth;
lastWidth = partialWidthArray[i];
int32_t advanceAppUnits = advancePixels * appUnitsPerDevPixel;
WCHAR glyph = glyphs[i];
NS_ASSERTION(!gfxFontGroup::IsInvalidChar(aText[i]),
"Invalid character detected!");
bool atClusterStart = charGlyphs[offset].IsClusterStart();
if (advanceAppUnits >= 0 &&
gfxShapedWord::CompressedGlyph::IsSimpleAdvance(advanceAppUnits) &&
gfxShapedWord::CompressedGlyph::IsSimpleGlyphID(glyph) &&
atClusterStart)
{
charGlyphs[offset].SetSimpleGlyph(advanceAppUnits, glyph);
} else {
gfxShapedText::DetailedGlyph details;
details.mGlyphID = glyph;
details.mAdvance = advanceAppUnits;
details.mXOffset = 0;
details.mYOffset = 0;
aShapedText->SetGlyphs(offset,
g.SetComplex(atClusterStart, true, 1),
&details);
}
}
return true;
}

Просмотреть файл

@ -1,33 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_GDISHAPER_H
#define GFX_GDISHAPER_H
#include "gfxGDIFont.h"
class gfxGDIShaper : public gfxFontShaper
{
public:
gfxGDIShaper(gfxGDIFont *aFont)
: gfxFontShaper(aFont)
{
MOZ_COUNT_CTOR(gfxGDIShaper);
}
virtual ~gfxGDIShaper()
{
MOZ_COUNT_DTOR(gfxGDIShaper);
}
virtual bool ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText);
};
#endif /* GFX_GDISHAPER_H */

Просмотреть файл

@ -1,527 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gfxTypes.h"
#include "gfxContext.h"
#include "gfxUniscribeShaper.h"
#include "gfxWindowsPlatform.h"
#include "gfxFontTest.h"
#include "cairo.h"
#include "cairo-win32.h"
#include <windows.h>
#include "nsTArray.h"
#include "prinit.h"
/**********************************************************************
*
* class gfxUniscribeShaper
*
**********************************************************************/
#define ESTIMATE_MAX_GLYPHS(L) (((3 * (L)) >> 1) + 16)
class UniscribeItem
{
public:
UniscribeItem(gfxContext *aContext, HDC aDC,
gfxUniscribeShaper *aShaper,
const char16_t *aString, uint32_t aLength,
SCRIPT_ITEM *aItem, uint32_t aIVS) :
mContext(aContext), mDC(aDC),
mShaper(aShaper),
mItemString(aString), mItemLength(aLength),
mAlternativeString(nullptr), mScriptItem(aItem),
mScript(aItem->a.eScript),
mNumGlyphs(0), mMaxGlyphs(ESTIMATE_MAX_GLYPHS(aLength)),
mFontSelected(false), mIVS(aIVS)
{
// See bug 394751 for details.
NS_ASSERTION(mMaxGlyphs < 65535,
"UniscribeItem is too big, ScriptShape() will fail!");
}
~UniscribeItem() {
free(mAlternativeString);
}
bool AllocateBuffers() {
return (mGlyphs.SetLength(mMaxGlyphs) &&
mClusters.SetLength(mItemLength + 1) &&
mAttr.SetLength(mMaxGlyphs));
}
/* possible return values:
* S_OK - things succeeded
* GDI_ERROR - things failed to shape. Might want to try again after calling DisableShaping()
*/
HRESULT Shape() {
HRESULT rv;
HDC shapeDC = nullptr;
char16ptr_t str = mAlternativeString ? mAlternativeString : mItemString;
mScriptItem->a.fLogicalOrder = true;
SCRIPT_ANALYSIS sa = mScriptItem->a;
while (true) {
rv = ScriptShape(shapeDC, mShaper->ScriptCache(),
str, mItemLength,
mMaxGlyphs, &sa,
mGlyphs.Elements(), mClusters.Elements(),
mAttr.Elements(), &mNumGlyphs);
if (rv == E_OUTOFMEMORY) {
mMaxGlyphs *= 2;
if (!mGlyphs.SetLength(mMaxGlyphs) ||
!mAttr.SetLength(mMaxGlyphs)) {
return E_OUTOFMEMORY;
}
continue;
}
// Uniscribe can't do shaping with some fonts, so it sets the
// fNoGlyphIndex flag in the SCRIPT_ANALYSIS structure to indicate
// this. This occurs with CFF fonts loaded with
// AddFontMemResourceEx but it's not clear what the other cases
// are. We return an error so our caller can try fallback shaping.
// see http://msdn.microsoft.com/en-us/library/ms776520(VS.85).aspx
if (sa.fNoGlyphIndex) {
return GDI_ERROR;
}
if (rv == E_PENDING) {
if (shapeDC == mDC) {
// we already tried this once, something failed, give up
return E_PENDING;
}
SelectFont();
shapeDC = mDC;
continue;
}
// http://msdn.microsoft.com/en-us/library/dd368564(VS.85).aspx:
// Uniscribe will return this if "the font corresponding to the
// DC does not support the script required by the run...".
// In this case, we'll set the script code to SCRIPT_UNDEFINED
// and try again, so that we'll at least get glyphs even though
// they won't necessarily have proper shaping.
// (We probably shouldn't have selected this font at all,
// but it's too late to fix that here.)
if (rv == USP_E_SCRIPT_NOT_IN_FONT) {
sa.eScript = SCRIPT_UNDEFINED;
NS_WARNING("Uniscribe says font does not support script needed");
continue;
}
// Prior to Windows 7, Uniscribe didn't support Ideographic Variation
// Selectors. Replace the UVS glyph manually.
if (mIVS) {
uint32_t lastChar = str[mItemLength - 1];
if (NS_IS_LOW_SURROGATE(lastChar)
&& NS_IS_HIGH_SURROGATE(str[mItemLength - 2])) {
lastChar = SURROGATE_TO_UCS4(str[mItemLength - 2], lastChar);
}
uint16_t glyphId = mShaper->GetFont()->GetUVSGlyph(lastChar, mIVS);
if (glyphId) {
mGlyphs[mNumGlyphs - 1] = glyphId;
}
}
return rv;
}
}
bool ShapingEnabled() {
return (mScriptItem->a.eScript != SCRIPT_UNDEFINED);
}
void DisableShaping() {
mScriptItem->a.eScript = SCRIPT_UNDEFINED;
// Note: If we disable the shaping by using SCRIPT_UNDEFINED and
// the string has the surrogate pair, ScriptShape API is
// *sometimes* crashed. Therefore, we should replace the surrogate
// pair to U+FFFD. See bug 341500.
GenerateAlternativeString();
}
void EnableShaping() {
mScriptItem->a.eScript = mScript;
if (mAlternativeString) {
free(mAlternativeString);
mAlternativeString = nullptr;
}
}
bool IsGlyphMissing(SCRIPT_FONTPROPERTIES *aSFP, uint32_t aGlyphIndex) {
return (mGlyphs[aGlyphIndex] == aSFP->wgDefault);
}
HRESULT Place() {
HRESULT rv;
HDC placeDC = nullptr;
if (!mOffsets.SetLength(mNumGlyphs) ||
!mAdvances.SetLength(mNumGlyphs)) {
return E_OUTOFMEMORY;
}
SCRIPT_ANALYSIS sa = mScriptItem->a;
while (true) {
rv = ScriptPlace(placeDC, mShaper->ScriptCache(),
mGlyphs.Elements(), mNumGlyphs,
mAttr.Elements(), &sa,
mAdvances.Elements(), mOffsets.Elements(), nullptr);
if (rv == E_PENDING) {
SelectFont();
placeDC = mDC;
continue;
}
if (rv == USP_E_SCRIPT_NOT_IN_FONT) {
sa.eScript = SCRIPT_UNDEFINED;
continue;
}
break;
}
return rv;
}
void ScriptFontProperties(SCRIPT_FONTPROPERTIES *sfp) {
HRESULT rv;
memset(sfp, 0, sizeof(SCRIPT_FONTPROPERTIES));
sfp->cBytes = sizeof(SCRIPT_FONTPROPERTIES);
rv = ScriptGetFontProperties(nullptr, mShaper->ScriptCache(),
sfp);
if (rv == E_PENDING) {
SelectFont();
rv = ScriptGetFontProperties(mDC, mShaper->ScriptCache(),
sfp);
}
}
void SaveGlyphs(gfxShapedText *aShapedText, uint32_t aOffset) {
uint32_t offsetInRun = mScriptItem->iCharPos;
// XXX We should store this in the item and only fetch it once
SCRIPT_FONTPROPERTIES sfp;
ScriptFontProperties(&sfp);
uint32_t offset = 0;
nsAutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs;
gfxShapedText::CompressedGlyph g;
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs();
const uint32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit();
while (offset < mItemLength) {
uint32_t runOffset = aOffset + offsetInRun + offset;
bool atClusterStart = charGlyphs[runOffset].IsClusterStart();
if (offset > 0 && mClusters[offset] == mClusters[offset - 1]) {
gfxShapedText::CompressedGlyph &g = charGlyphs[runOffset];
NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
g.SetComplex(atClusterStart, false, 0);
} else {
// Count glyphs for this character
uint32_t k = mClusters[offset];
uint32_t glyphCount = mNumGlyphs - k;
uint32_t nextClusterOffset;
bool missing = IsGlyphMissing(&sfp, k);
for (nextClusterOffset = offset + 1; nextClusterOffset < mItemLength; ++nextClusterOffset) {
if (mClusters[nextClusterOffset] > k) {
glyphCount = mClusters[nextClusterOffset] - k;
break;
}
}
uint32_t j;
for (j = 1; j < glyphCount; ++j) {
if (IsGlyphMissing(&sfp, k + j)) {
missing = true;
}
}
int32_t advance = mAdvances[k]*appUnitsPerDevUnit;
WORD glyph = mGlyphs[k];
NS_ASSERTION(!gfxFontGroup::IsInvalidChar(mItemString[offset]),
"invalid character detected");
if (missing) {
if (NS_IS_HIGH_SURROGATE(mItemString[offset]) &&
offset + 1 < mItemLength &&
NS_IS_LOW_SURROGATE(mItemString[offset + 1])) {
aShapedText->SetMissingGlyph(runOffset,
SURROGATE_TO_UCS4(mItemString[offset],
mItemString[offset + 1]),
mShaper->GetFont());
} else {
aShapedText->SetMissingGlyph(runOffset, mItemString[offset],
mShaper->GetFont());
}
} else if (glyphCount == 1 && advance >= 0 &&
mOffsets[k].dv == 0 && mOffsets[k].du == 0 &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(advance) &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(glyph) &&
atClusterStart)
{
charGlyphs[runOffset].SetSimpleGlyph(advance, glyph);
} else {
if (detailedGlyphs.Length() < glyphCount) {
if (!detailedGlyphs.AppendElements(glyphCount - detailedGlyphs.Length()))
return;
}
uint32_t i;
for (i = 0; i < glyphCount; ++i) {
gfxTextRun::DetailedGlyph *details = &detailedGlyphs[i];
details->mGlyphID = mGlyphs[k + i];
details->mAdvance = mAdvances[k + i] * appUnitsPerDevUnit;
details->mXOffset = float(mOffsets[k + i].du) * appUnitsPerDevUnit *
aShapedText->GetDirection();
details->mYOffset = - float(mOffsets[k + i].dv) * appUnitsPerDevUnit;
}
aShapedText->SetGlyphs(runOffset,
g.SetComplex(atClusterStart, true,
glyphCount),
detailedGlyphs.Elements());
}
}
++offset;
}
}
void SelectFont() {
if (mFontSelected)
return;
cairo_t *cr = mContext->GetCairo();
cairo_set_font_face(cr, mShaper->GetFont()->CairoFontFace());
cairo_set_font_size(cr, mShaper->GetFont()->GetAdjustedSize());
cairo_scaled_font_t *scaledFont = mShaper->GetFont()->CairoScaledFont();
cairo_win32_scaled_font_select_font(scaledFont, mDC);
mFontSelected = true;
}
private:
void GenerateAlternativeString() {
if (mAlternativeString)
free(mAlternativeString);
mAlternativeString = (char16_t *)malloc(mItemLength * sizeof(char16_t));
if (!mAlternativeString)
return;
memcpy((void *)mAlternativeString, (const void *)mItemString,
mItemLength * sizeof(char16_t));
for (uint32_t i = 0; i < mItemLength; i++) {
if (NS_IS_HIGH_SURROGATE(mItemString[i]) || NS_IS_LOW_SURROGATE(mItemString[i]))
mAlternativeString[i] = char16_t(0xFFFD);
}
}
private:
nsRefPtr<gfxContext> mContext;
HDC mDC;
gfxUniscribeShaper *mShaper;
SCRIPT_ITEM *mScriptItem;
WORD mScript;
public:
// these point to the full string/length of the item
const char16_t *mItemString;
const uint32_t mItemLength;
private:
char16_t *mAlternativeString;
#define AVERAGE_ITEM_LENGTH 40
AutoFallibleTArray<WORD, uint32_t(ESTIMATE_MAX_GLYPHS(AVERAGE_ITEM_LENGTH))> mGlyphs;
AutoFallibleTArray<WORD, AVERAGE_ITEM_LENGTH + 1> mClusters;
AutoFallibleTArray<SCRIPT_VISATTR, uint32_t(ESTIMATE_MAX_GLYPHS(AVERAGE_ITEM_LENGTH))> mAttr;
AutoFallibleTArray<GOFFSET, 2 * AVERAGE_ITEM_LENGTH> mOffsets;
AutoFallibleTArray<int, 2 * AVERAGE_ITEM_LENGTH> mAdvances;
#undef AVERAGE_ITEM_LENGTH
int mMaxGlyphs;
int mNumGlyphs;
uint32_t mIVS;
bool mFontSelected;
};
class Uniscribe
{
public:
Uniscribe(const char16_t *aString,
gfxShapedText *aShapedText,
uint32_t aOffset, uint32_t aLength):
mString(aString), mShapedText(aShapedText),
mOffset(aOffset), mLength(aLength)
{
}
void Init() {
memset(&mControl, 0, sizeof(SCRIPT_CONTROL));
memset(&mState, 0, sizeof(SCRIPT_STATE));
// Lock the direction. Don't allow the itemizer to change directions
// based on character type.
mState.uBidiLevel = mShapedText->IsRightToLeft() ? 1 : 0;
mState.fOverrideDirection = true;
}
public:
int Itemize() {
HRESULT rv;
int maxItems = 5;
Init();
// Allocate space for one more item than expected, to handle a rare
// overflow in ScriptItemize (pre XP SP2). See bug 366643.
if (!mItems.SetLength(maxItems + 1)) {
return 0;
}
while ((rv = ScriptItemize(mString, mLength,
maxItems, &mControl, &mState,
mItems.Elements(), &mNumItems)) == E_OUTOFMEMORY) {
maxItems *= 2;
if (!mItems.SetLength(maxItems + 1)) {
return 0;
}
Init();
}
return mNumItems;
}
SCRIPT_ITEM *ScriptItem(uint32_t i) {
NS_ASSERTION(i <= (uint32_t)mNumItems, "Trying to get out of bounds item");
return &mItems[i];
}
private:
char16ptr_t mString;
gfxShapedText *mShapedText;
uint32_t mOffset;
uint32_t mLength;
SCRIPT_CONTROL mControl;
SCRIPT_STATE mState;
FallibleTArray<SCRIPT_ITEM> mItems;
int mNumItems;
};
bool
gfxUniscribeShaper::ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText)
{
DCFromContext aDC(aContext);
bool result = true;
HRESULT rv;
Uniscribe us(aText, aShapedText, aOffset, aLength);
/* itemize the string */
int numItems = us.Itemize();
uint32_t length = aLength;
SaveDC(aDC);
uint32_t ivs = 0;
for (int i = 0; i < numItems; ++i) {
int iCharPos = us.ScriptItem(i)->iCharPos;
int iCharPosNext = us.ScriptItem(i+1)->iCharPos;
if (ivs) {
iCharPos += 2;
if (iCharPos >= iCharPosNext) {
ivs = 0;
continue;
}
}
if (i+1 < numItems && iCharPosNext <= length - 2
&& aText[iCharPosNext] == H_SURROGATE(kUnicodeVS17)
&& uint32_t(aText[iCharPosNext + 1]) - L_SURROGATE(kUnicodeVS17)
<= L_SURROGATE(kUnicodeVS256) - L_SURROGATE(kUnicodeVS17)) {
ivs = SURROGATE_TO_UCS4(aText[iCharPosNext],
aText[iCharPosNext + 1]);
} else {
ivs = 0;
}
UniscribeItem item(aContext, aDC, this,
aText + iCharPos,
iCharPosNext - iCharPos,
us.ScriptItem(i), ivs);
if (!item.AllocateBuffers()) {
result = false;
break;
}
if (!item.ShapingEnabled()) {
item.EnableShaping();
}
rv = item.Shape();
if (FAILED(rv)) {
// we know we have the glyphs to display this font already
// so Uniscribe just doesn't know how to shape the script.
// Render the glyphs without shaping.
item.DisableShaping();
rv = item.Shape();
}
#ifdef DEBUG
if (FAILED(rv)) {
NS_WARNING("Uniscribe failed to shape with font");
}
#endif
if (SUCCEEDED(rv)) {
rv = item.Place();
#ifdef DEBUG
if (FAILED(rv)) {
// crap fonts may fail when placing (e.g. funky free fonts)
NS_WARNING("Uniscribe failed to place with font");
}
#endif
}
if (FAILED(rv)) {
// Uniscribe doesn't like this font for some reason.
// Returning FALSE will make the gfxGDIFont retry with the
// "dumb" GDI shaper, unless useUniscribeOnly was set.
result = false;
break;
}
item.SaveGlyphs(aShapedText, aOffset);
}
RestoreDC(aDC, -1);
return result;
}

Просмотреть файл

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_UNISCRIBESHAPER_H
#define GFX_UNISCRIBESHAPER_H
#include "gfxTypes.h"
#include "gfxGDIFont.h"
#include <usp10.h>
#include <cairo-win32.h>
class gfxUniscribeShaper : public gfxFontShaper
{
public:
gfxUniscribeShaper(gfxGDIFont *aFont)
: gfxFontShaper(aFont)
, mScriptCache(nullptr)
{
MOZ_COUNT_CTOR(gfxUniscribeShaper);
}
virtual ~gfxUniscribeShaper()
{
MOZ_COUNT_DTOR(gfxUniscribeShaper);
}
virtual bool ShapeText(gfxContext *aContext,
const char16_t *aText,
uint32_t aOffset,
uint32_t aLength,
int32_t aScript,
gfxShapedText *aShapedText);
SCRIPT_CACHE *ScriptCache() { return &mScriptCache; }
gfxGDIFont *GetFont() { return static_cast<gfxGDIFont*>(mFont); }
private:
SCRIPT_CACHE mScriptCache;
enum {
kUnicodeVS17 = gfxFontUtils::kUnicodeVS17,
kUnicodeVS256 = gfxFontUtils::kUnicodeVS256
};
};
#endif /* GFX_UNISCRIBESHAPER_H */

Просмотреть файл

@ -171,13 +171,11 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'gfxWindowsPlatform.h',
'gfxWindowsSurface.h',
]
# gfxGDIFontList.cpp and gfxGDIShaper.cpp force NSPR logging, so they cannot be built in unified mode.
# gfxGDIFontList.cpp forces NSPR logging, so it cannot be built in unified mode.
SOURCES += [
'gfxGDIFont.cpp',
'gfxGDIFontList.cpp',
'gfxGDIShaper.cpp',
'gfxPDFSurface.cpp',
'gfxUniscribeShaper.cpp',
'gfxWindowsNativeDrawing.cpp',
'gfxWindowsPlatform.cpp',
'gfxWindowsSurface.cpp',
@ -189,8 +187,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'gfxDWriteCommon.cpp',
'gfxDWriteFontList.cpp',
'gfxDWriteFonts.cpp',
'gfxDWriteShaper.cpp',
'gfxDWriteTextAnalysis.cpp',
]
# Are we targeting x86 or x64? If so, build gfxAlphaRecoverySSE2.cpp.

Просмотреть файл

@ -115,45 +115,31 @@ enum {
namespace JS {
struct ClassInfo
// Data for tracking memory usage of things hanging off objects.
struct ObjectsExtraSizes
{
#define FOR_EACH_SIZE(macro) \
macro(Objects, IsLiveGCThing, objectsGCHeap) \
macro(Objects, NotLiveGCThing, objectsMallocHeapSlots) \
macro(Objects, NotLiveGCThing, objectsMallocHeapElementsNonAsmJS) \
macro(Objects, NotLiveGCThing, objectsMallocHeapElementsAsmJS) \
macro(Objects, NotLiveGCThing, objectsNonHeapElementsAsmJS) \
macro(Objects, NotLiveGCThing, objectsNonHeapElementsMapped) \
macro(Objects, NotLiveGCThing, objectsNonHeapCodeAsmJS) \
macro(Objects, NotLiveGCThing, objectsMallocHeapMisc) \
\
macro(Other, IsLiveGCThing, shapesGCHeapTree) \
macro(Other, IsLiveGCThing, shapesGCHeapDict) \
macro(Other, IsLiveGCThing, shapesGCHeapBase) \
macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \
macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \
macro(Other, NotLiveGCThing, shapesMallocHeapTreeKids) \
macro(Objects, NotLiveGCThing, mallocHeapSlots) \
macro(Objects, NotLiveGCThing, mallocHeapElementsNonAsmJS) \
macro(Objects, NotLiveGCThing, mallocHeapElementsAsmJS) \
macro(Objects, NotLiveGCThing, nonHeapElementsAsmJS) \
macro(Objects, NotLiveGCThing, nonHeapElementsMapped) \
macro(Objects, NotLiveGCThing, nonHeapCodeAsmJS) \
macro(Objects, NotLiveGCThing, mallocHeapAsmJSModuleData) \
macro(Objects, NotLiveGCThing, mallocHeapArgumentsData) \
macro(Objects, NotLiveGCThing, mallocHeapRegExpStatics) \
macro(Objects, NotLiveGCThing, mallocHeapPropertyIteratorData) \
macro(Objects, NotLiveGCThing, mallocHeapCtypesData)
ClassInfo()
ObjectsExtraSizes()
: FOR_EACH_SIZE(ZERO_SIZE)
dummy()
{}
void add(const ClassInfo &other) {
void add(const ObjectsExtraSizes &other) {
FOR_EACH_SIZE(ADD_OTHER_SIZE)
}
void subtract(const ClassInfo &other) {
FOR_EACH_SIZE(SUB_OTHER_SIZE)
}
bool isNotable() const {
static const size_t NotabilityThreshold = 16 * 1024;
size_t n = 0;
FOR_EACH_SIZE(ADD_SIZE_TO_N)
return n >= NotabilityThreshold;
}
size_t sizeOfLiveGCThings() const {
size_t n = 0;
FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
@ -170,29 +156,6 @@ struct ClassInfo
#undef FOR_EACH_SIZE
};
// Holds data about a notable class (one whose combined object and shape
// instances use more than a certain amount of memory) so we can report it
// individually.
//
// The only difference between this class and ClassInfo is that this class
// holds a copy of the filename.
struct NotableClassInfo : public ClassInfo
{
NotableClassInfo();
NotableClassInfo(const char *className, const ClassInfo &info);
NotableClassInfo(NotableClassInfo &&info);
NotableClassInfo &operator=(NotableClassInfo &&info);
~NotableClassInfo() {
js_free(className_);
}
char *className_;
private:
NotableClassInfo(const NotableClassInfo& info) MOZ_DELETE;
};
// Data for tracking JIT-code memory usage.
struct CodeSizes
{
@ -523,7 +486,20 @@ struct ZoneStats
struct CompartmentStats
{
#define FOR_EACH_SIZE(macro) \
macro(Objects, IsLiveGCThing, objectsGCHeapOrdinary) \
macro(Objects, IsLiveGCThing, objectsGCHeapFunction) \
macro(Objects, IsLiveGCThing, objectsGCHeapDenseArray) \
macro(Objects, IsLiveGCThing, objectsGCHeapSlowArray) \
macro(Objects, IsLiveGCThing, objectsGCHeapCrossCompartmentWrapper) \
macro(Private, NotLiveGCThing, objectsPrivate) \
macro(Other, IsLiveGCThing, shapesGCHeapTreeGlobalParented) \
macro(Other, IsLiveGCThing, shapesGCHeapTreeNonGlobalParented) \
macro(Other, IsLiveGCThing, shapesGCHeapDict) \
macro(Other, IsLiveGCThing, shapesGCHeapBase) \
macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \
macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \
macro(Other, NotLiveGCThing, shapesMallocHeapTreeShapeKids) \
macro(Other, NotLiveGCThing, shapesMallocHeapCompartmentTables) \
macro(Other, IsLiveGCThing, scriptsGCHeap) \
macro(Other, NotLiveGCThing, scriptsMallocHeapData) \
macro(Other, NotLiveGCThing, baselineData) \
@ -534,7 +510,6 @@ struct CompartmentStats
macro(Other, NotLiveGCThing, typeInferenceArrayTypeTables) \
macro(Other, NotLiveGCThing, typeInferenceObjectTypeTables) \
macro(Other, NotLiveGCThing, compartmentObject) \
macro(Other, NotLiveGCThing, compartmentTables) \
macro(Other, NotLiveGCThing, crossCompartmentWrappersTable) \
macro(Other, NotLiveGCThing, regexpCompartment) \
macro(Other, NotLiveGCThing, debuggeesSet) \
@ -542,69 +517,39 @@ struct CompartmentStats
CompartmentStats()
: FOR_EACH_SIZE(ZERO_SIZE)
classInfo(),
extra(),
allClasses(nullptr),
notableClasses(),
isTotals(true)
objectsExtra(),
extra()
{}
CompartmentStats(CompartmentStats &&other)
CompartmentStats(const CompartmentStats &other)
: FOR_EACH_SIZE(COPY_OTHER_SIZE)
classInfo(mozilla::Move(other.classInfo)),
extra(other.extra),
allClasses(other.allClasses),
notableClasses(mozilla::Move(other.notableClasses)),
isTotals(other.isTotals)
{
other.allClasses = nullptr;
MOZ_ASSERT(!other.isTotals);
}
objectsExtra(other.objectsExtra),
extra(other.extra)
{}
~CompartmentStats() {
// |allClasses| is usually deleted and set to nullptr before this
// destructor runs. But there are failure cases due to OOMs that may
// prevent that, so it doesn't hurt to try again here.
js_delete(allClasses);
}
bool initClasses(JSRuntime *rt);
void addSizes(const CompartmentStats &other) {
MOZ_ASSERT(isTotals);
void add(const CompartmentStats &other) {
FOR_EACH_SIZE(ADD_OTHER_SIZE)
classInfo.add(other.classInfo);
objectsExtra.add(other.objectsExtra);
// Do nothing with |extra|.
}
size_t sizeOfLiveGCThings() const {
MOZ_ASSERT(isTotals);
size_t n = 0;
FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING)
n += classInfo.sizeOfLiveGCThings();
n += objectsExtra.sizeOfLiveGCThings();
// Do nothing with |extra|.
return n;
}
void addToTabSizes(TabSizes *sizes) const {
MOZ_ASSERT(isTotals);
FOR_EACH_SIZE(ADD_TO_TAB_SIZES);
classInfo.addToTabSizes(sizes);
objectsExtra.addToTabSizes(sizes);
// Do nothing with |extra|.
}
// The class measurements in |classInfo| are initially for all classes. At
// the end, if the measurement granularity is FineGrained, we subtract the
// measurements of the notable classes and move them into |notableClasses|.
FOR_EACH_SIZE(DECL_SIZE)
ClassInfo classInfo;
void *extra; // This field can be used by embedders.
typedef js::HashMap<const char*, ClassInfo,
js::CStringHashPolicy,
js::SystemAllocPolicy> ClassesHashMap;
// These are similar to |allStrings| and |notableStrings| in ZoneStats.
ClassesHashMap *allClasses;
js::Vector<NotableClassInfo, 0, js::SystemAllocPolicy> notableClasses;
bool isTotals;
ObjectsExtraSizes objectsExtra;
void *extra; // This field can be used by embedders.
#undef FOR_EACH_SIZE
};

Просмотреть файл

@ -401,7 +401,8 @@ endif
selfhosted.out.h: $(selfhosted_out_h_deps)
$(PYTHON) $(srcdir)/builtin/embedjs.py $(SELFHOSTED_DEFINES) \
-p '$(CPP)' -m $(srcdir)/js.msg -o $@ $(selfhosting_srcs)
-c '$(CCC)' -p '$(PREPROCESS_OPTION)' -m $(srcdir)/js.msg \
-o $@ $(selfhosting_srcs)
###############################################
# Generating source package tarballs

Просмотреть файл

@ -20,6 +20,7 @@
// by the headers included above.
namespace JS {
class Latin1Chars;
class Latin1CharsZ;
class ConstTwoByteChars;
class TwoByteChars;
@ -65,6 +66,7 @@ using JS::UndefinedValue;
using JS::IsPoisonedPtr;
using JS::Latin1Char;
using JS::Latin1Chars;
using JS::Latin1CharsZ;
using JS::ConstTwoByteChars;
using JS::TwoByteChars;

Просмотреть файл

@ -173,8 +173,9 @@ TryEvalJSON(JSContext *cx, JSScript *callerScript,
if (cp == end) {
bool isArray = (chars[0] == '[');
JSONParser parser(cx, isArray ? chars : chars + 1U, isArray ? length : length - 2,
JSONParser::NoError);
JSONParser<jschar> parser(cx, isArray ? chars : chars + 1U,
isArray ? length : length - 2,
JSONParserBase::NoError);
RootedValue tmp(cx);
if (!parser.parse(&tmp))
return EvalJSON_Failure;

Просмотреть файл

@ -1414,13 +1414,13 @@ intl_FormatNumber(JSContext *cx, UNumberFormat *nf, double x, MutableHandleValue
if (!chars.resize(INITIAL_STRING_BUFFER_SIZE))
return false;
UErrorCode status = U_ZERO_ERROR;
int size = unum_formatDouble(nf, x, JSCharToUChar(chars.begin()),
int size = unum_formatDouble(nf, x, JSCharToUChar(chars.rawTwoByteBegin()),
INITIAL_STRING_BUFFER_SIZE, nullptr, &status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
if (!chars.resize(size))
return false;
status = U_ZERO_ERROR;
unum_formatDouble(nf, x, JSCharToUChar(chars.begin()),
unum_formatDouble(nf, x, JSCharToUChar(chars.rawTwoByteBegin()),
size, nullptr, &status);
}
if (U_FAILURE(status)) {
@ -1902,12 +1902,13 @@ intl_FormatDateTime(JSContext *cx, UDateFormat *df, double x, MutableHandleValue
if (!chars.resize(INITIAL_STRING_BUFFER_SIZE))
return false;
UErrorCode status = U_ZERO_ERROR;
int size = udat_format(df, x, JSCharToUChar(chars.begin()), INITIAL_STRING_BUFFER_SIZE, nullptr, &status);
int size = udat_format(df, x, JSCharToUChar(chars.rawTwoByteBegin()), INITIAL_STRING_BUFFER_SIZE,
nullptr, &status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
if (!chars.resize(size))
return false;
status = U_ZERO_ERROR;
udat_format(df, x, JSCharToUChar(chars.begin()), size, nullptr, &status);
udat_format(df, x, JSCharToUChar(chars.rawTwoByteBegin()), size, nullptr, &status);
}
if (U_FAILURE(status)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);

Просмотреть файл

@ -205,6 +205,8 @@ js::ObjectToSource(JSContext *cx, HandleObject obj)
const jschar *vchars = valstr->getChars(cx);
if (!vchars)
return nullptr;
const jschar *start = vchars;
size_t vlength = valstr->length();
/*
@ -212,7 +214,6 @@ js::ObjectToSource(JSContext *cx, HandleObject obj)
* end so that we can put "get" in front of the function definition.
*/
if (gsop[j] && IsFunctionObject(val[j])) {
const jschar *start = vchars;
const jschar *end = vchars + vlength;
uint8_t parenChomp = 0;
@ -255,7 +256,7 @@ js::ObjectToSource(JSContext *cx, HandleObject obj)
if (!buf.append(gsop[j] ? ' ' : ':'))
return nullptr;
if (!buf.append(vchars, vlength))
if (!buf.appendSubstring(valstr, vchars - start, vlength))
return nullptr;
}
}
@ -291,7 +292,7 @@ JS_BasicObjectToString(JSContext *cx, HandleObject obj)
return cx->names().objectWindow;
StringBuffer sb(cx);
if (!sb.append("[object ") || !sb.appendInflated(className, strlen(className)) ||
if (!sb.append("[object ") || !sb.append(className, strlen(className)) ||
!sb.append("]"))
{
return nullptr;

Просмотреть файл

@ -176,8 +176,12 @@ EscapeNakedForwardSlashes(JSContext *cx, HandleAtom unescaped)
/* There's a forward slash that needs escaping. */
if (sb.empty()) {
/* This is the first one we've seen, copy everything up to this point. */
if (unescaped->hasTwoByteChars() && !sb.ensureTwoByteChars())
return nullptr;
if (!sb.reserve(oldLen + 1))
return nullptr;
sb.infallibleAppend(oldChars, size_t(it - oldChars));
}
if (!sb.append('\\'))

Просмотреть файл

@ -39,6 +39,7 @@
from __future__ import with_statement
import re, sys, os, fileinput, subprocess
import shlex
import which
from optparse import OptionParser
def ToCAsciiArray(lines):
@ -77,19 +78,21 @@ namespace selfhosted {
} // js
"""
def embed(cpp, msgs, sources, c_out, js_out, env):
# Clang seems to complain and not output anything if the extension of the
# input is not something it recognizes, so just fake a .h here.
tmp = 'selfhosted.js.h'
with open(tmp, 'wb') as output:
output.write('\n'.join([msgs] + ['#include "%(s)s"' % { 's': source } for source in sources]))
cmdline = cpp + ['-D%(k)s=%(v)s' % { 'k': k, 'v': env[k] } for k in env] + [tmp]
p = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
processed = ''
for line in p.stdout:
if not line.startswith('#'):
processed += line
os.remove(tmp)
MSGS_TEMPLATE = """\
#define hash #
#define id(x) x
#define hashify(x) id(hash)x
#define MSG_DEF(name, id, argc, ex, msg) hashify(define) name id
#include "%(msgs)s"
"""
def embed(cxx, preprocessorOption, msgs, sources, c_out, js_out, env):
combinedSources = '\n'.join([msgs] + ['#include "%(s)s"' % { 's': source } for source in sources])
args = ['-D%(k)s=%(v)s' % { 'k': k, 'v': env[k] } for k in env]
preprocessed = preprocess(cxx, preprocessorOption, combinedSources, args)
processed = '\n'.join([line for line in preprocessed.splitlines() if \
(line.strip() and not line.startswith('#'))])
with open(js_out, 'w') as output:
output.write(processed)
with open(c_out, 'w') as output:
@ -114,21 +117,25 @@ def embed(cpp, msgs, sources, c_out, js_out, env):
'raw_total_length': len(processed)
})
def process_msgs(cpp, msgs):
def preprocess(cxx, preprocessorOption, source, args = []):
if (not os.path.exists(cxx[0])):
cxx[0] = which.which(cxx[0])
# Clang seems to complain and not output anything if the extension of the
# input is not something it recognizes, so just fake a .h here.
tmp = 'selfhosted.msg.h'
with open(tmp, 'wb') as output:
output.write("""\
#define hash #
#define id(x) x
#define hashify(x) id(hash)x
#define MSG_DEF(name, id, argc, ex, msg) hashify(define) name id
#include "%(msgs)s"
""" % { 'msgs': msgs })
p = subprocess.Popen(cpp + [tmp], stdout=subprocess.PIPE)
processed = p.communicate()[0]
os.remove(tmp)
# input is not something it recognizes, so just fake a .cpp here.
tmpIn = 'self-hosting-cpp-input.cpp';
tmpOut = 'self-hosting-preprocessed.pp';
outputArg = shlex.split(preprocessorOption + tmpOut)
with open(tmpIn, 'wb') as input:
input.write(source)
print(' '.join(cxx + outputArg + args + [tmpIn]))
result = subprocess.Popen(cxx + outputArg + args + [tmpIn]).wait()
if (result != 0):
sys.exit(result);
with open(tmpOut, 'r') as output:
processed = output.read();
os.remove(tmpIn)
os.remove(tmpOut)
return processed
def main():
@ -143,7 +150,9 @@ def main():
metavar='var=[val]', help='Define a variable')
p.add_option('-m', type='string', metavar='jsmsg', default='../js.msg',
help='js.msg file')
p.add_option('-p', type='string', metavar='cpp', help='Path to C preprocessor')
p.add_option('-c', type='string', metavar='cxx', help='Path to C++ compiler')
p.add_option('-p', type='string', dest='p', metavar='cxxoption',
help='Argument to compiler for preprocessing into an output file')
p.add_option('-o', type='string', metavar='filename', default='selfhosted.out.h',
help='C array header file')
p.add_option('-s', type='string', metavar='jsfilename', default='selfhosted.js',
@ -151,10 +160,10 @@ def main():
(options, sources) = p.parse_args()
if not (options.p and sources):
p.print_help()
exit(1)
cpp = shlex.split(options.p)
embed(cpp, process_msgs(cpp, options.m),
sources, options.o, options.s, env)
sys.exit(1)
cxx = shlex.split(options.c)
msgs = preprocess(cxx, options.p, MSGS_TEMPLATE % { 'msgs': options.m })
embed(cxx, options.p, msgs, sources, options.o, options.s, env)
if __name__ == "__main__":
main()

Просмотреть файл

@ -473,6 +473,9 @@ case "$target" in
INCREMENTAL_LINKER=1
unset _MSVC_VER_FILTER
CFLAGS="$CFLAGS -D_HAS_EXCEPTIONS=0"
CXXFLAGS="$CXXFLAGS -D_HAS_EXCEPTIONS=0"
elif test -z "$CLANG_CC"; then
# Check w32api version
_W32API_MAJOR_VERSION=`echo $W32API_VERSION | $AWK -F\. '{ print $1 }'`

Просмотреть файл

@ -0,0 +1,63 @@
commit fb25cd08ed5a87640b02f0feeb10a09b37cfddbe (HEAD, origin/clang-cl, clang-cl)
Author: Ehsan Akhgari <ehsan@mozilla.com>
Date: Wed Jun 11 12:07:24 2014 -0400
Add support for building with clang-cl
diff --git a/README b/README
index 7aee5b4..9cba257 100644
--- a/README
+++ b/README
@@ -146,12 +146,17 @@ It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
-path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
+path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64" and
CXX="path/to/msvcc.sh -m64". You may also need to specify --build
appropriately.
+It is also possible to build libffi on Windows platforms with the LLVM
+project's clang-cl compiler, like below:
+
+path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP"
+
When building with MSVC under a MingW environment, you may need to
remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
command. ('cygpath' is not present in MingW, and is not required when
diff --git a/include/ffi.h.in b/include/ffi.h.in
index 70c6179..ebed0aa 100644
--- a/include/ffi.h.in
+++ b/include/ffi.h.in
@@ -68,7 +68,7 @@ extern "C" {
#ifndef LIBFFI_ASM
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
diff --git a/msvcc.sh b/msvcc.sh
index 9208076..4a65b0b 100755
--- a/msvcc.sh
+++ b/msvcc.sh
@@ -63,11 +63,15 @@ do
shift 1
;;
-m64)
- cl="cl" # "$MSVC/x86_amd64/cl"
ml="ml64" # "$MSVC/x86_amd64/ml64"
safeseh=
shift 1
;;
+ -clang-cl)
+ cl="clang-cl"
+ safeseh=
+ shift 1
+ ;;
-O0)
args="$args -Od"
shift 1

Просмотреть файл

@ -146,12 +146,17 @@ It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64" and
CXX="path/to/msvcc.sh -m64". You may also need to specify --build
appropriately.
It is also possible to build libffi on Windows platforms with the LLVM
project's clang-cl compiler, like below:
path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP"
When building with MSVC under a MingW environment, you may need to
remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
command. ('cygpath' is not present in MingW, and is not required when

Просмотреть файл

@ -68,7 +68,7 @@ extern "C" {
#ifndef LIBFFI_ASM
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif

Просмотреть файл

@ -63,11 +63,15 @@ do
shift 1
;;
-m64)
cl="cl" # "$MSVC/x86_amd64/cl"
ml="ml64" # "$MSVC/x86_amd64/ml64"
safeseh=
shift 1
;;
-clang-cl)
cl="clang-cl"
safeseh=
shift 1
;;
-O0)
args="$args -Od"
shift 1

Просмотреть файл

@ -45,23 +45,23 @@ class NameResolver
*/
bool appendPropertyReference(JSAtom *name) {
if (IsIdentifier(name))
return buf->append(".") && buf->append(name);
return buf->append('.') && buf->append(name);
/* Quote the string as needed. */
JSString *source = js_QuoteString(cx, name, '"');
return source && buf->append("[") && buf->append(source) && buf->append("]");
return source && buf->append('[') && buf->append(source) && buf->append(']');
}
/* Append a number to buf. */
bool appendNumber(double n) {
char number[30];
int digits = JS_snprintf(number, sizeof(number), "%g", n);
return buf->appendInflated(number, digits);
return buf->append(number, digits);
}
/* Append "[<n>]" to buf, referencing a property named by a numeric literal. */
bool appendNumericPropertyReference(double n) {
return buf->append("[") && appendNumber(n) && buf->append("]");
return buf->append("[") && appendNumber(n) && buf->append(']');
}
/*
@ -81,9 +81,9 @@ class NameResolver
case PNK_ELEM:
return nameExpression(n->pn_left) &&
buf->append("[") &&
buf->append('[') &&
nameExpression(n->pn_right) &&
buf->append("]");
buf->append(']');
case PNK_NUMBER:
return appendNumber(n->pn_dval);
@ -189,7 +189,7 @@ class NameResolver
return true;
}
if (!buf.append(prefix) ||
!buf.append("/") ||
!buf.append('/') ||
!buf.append(fun->displayAtom()))
return false;
retAtom.set(buf.finishAtom());
@ -197,7 +197,7 @@ class NameResolver
}
/* If a prefix is specified, then it is a form of namespace */
if (prefix != nullptr && (!buf.append(prefix) || !buf.append("/")))
if (prefix != nullptr && (!buf.append(prefix) || !buf.append('/')))
return false;
/* Gather all nodes relevant to naming */
@ -235,7 +235,7 @@ class NameResolver
* Don't have consecutive '<' characters, and also don't start
* with a '<' character.
*/
if (!buf.empty() && *(buf.end() - 1) != '<' && !buf.append("<"))
if (!buf.empty() && buf.getChar(buf.length() - 1) != '<' && !buf.append('<'))
return false;
}
}
@ -245,7 +245,7 @@ class NameResolver
* other namespace are rather considered as "contributing" to the outer
* function, so give them a contribution symbol here.
*/
if (!buf.empty() && *(buf.end() - 1) == '/' && !buf.append("<"))
if (!buf.empty() && buf.getChar(buf.length() - 1) == '/' && !buf.append('<'))
return false;
if (buf.empty())

Просмотреть файл

@ -689,7 +689,7 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
// Unicode and char versions of the window into the offending source
// line, without final \n.
err.report.uclinebuf = windowBuf.extractWellSized();
err.report.uclinebuf = windowBuf.stealChars();
if (!err.report.uclinebuf)
return false;
TwoByteChars tbchars(err.report.uclinebuf, windowLength);

Просмотреть файл

@ -576,7 +576,7 @@ AutoGCRooter::trace(JSTracer *trc)
}
case JSONPARSER:
static_cast<js::JSONParser *>(this)->trace(trc);
static_cast<js::JSONParserBase *>(this)->trace(trc);
return;
case CUSTOM:

Просмотреть файл

@ -97,12 +97,56 @@ assertThrowsValue(function() { f(8,2.4) }, 2.4+36);
assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var identity=imp.identity; function g(x) { x=+x; return +identity(x) } return g'), null, imp)(13.37), 13.37);
// Test asm.js => ion paths
setJitCompilerOption("ion.usecount.trigger", 20);
function ffiInt(a,b,c,d,e,f,g,h,i,j) { return j+1 }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i|0,(i+1)|0,(i+2)|0,(i+3)|0,(i+4)|0,(i+5)|0,(i+6)|0,(i+7)|0,(i+8)|0,(i+9)|0)|0 } return f'), null, {ffi:ffiInt});
// In registers on x64 and ARM, on the stack for x86
function ffiIntFew(a,b,c,d) { return d+1 }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i|0,(i+1)|0,(i+2)|0,(i+3)|0)|0 } return f'), null, {ffi:ffiIntFew});
for (var i = 0; i < 40; i++)
assertEq(f(i), i+4);
// Stack and registers for x64 and ARM, stack for x86
function ffiIntMany(a,b,c,d,e,f,g,h,i,j) { return j+1 }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i|0,(i+1)|0,(i+2)|0,(i+3)|0,(i+4)|0,(i+5)|0,(i+6)|0,(i+7)|0,(i+8)|0,(i+9)|0)|0 } return f'), null, {ffi:ffiIntMany});
for (var i = 0; i < 40; i++)
assertEq(f(i), i+10);
function ffiDouble(a,b,c,d,e,f,g,h,i,j) { return j+1 }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=+i; return +ffi(i,i+1.0,i+2.0,i+3.0,i+4.0,i+5.0,i+6.0,i+7.0,i+8.0,i+9.0) } return f'), null, {ffi:ffiDouble});
// In registers on x64 and ARM, on the stack for x86
function ffiDoubleFew(a,b,c,d) { return d+1 }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=+i; return +ffi(i,i+1.0,i+2.0,i+3.0) } return f'), null, {ffi:ffiDoubleFew});
for (var i = 0; i < 40; i++)
assertEq(f(i), i+4);
// Stack and registers for x64 and ARM, stack for x86
function ffiDoubleMany(a,b,c,d,e,f,g,h,i,j) { return j+1 }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=+i; return +ffi(i,i+1.0,i+2.0,i+3.0,i+4.0,i+5.0,i+6.0,i+7.0,i+8.0,i+9.0) } return f'), null, {ffi:ffiDoubleMany});
for (var i = 0; i < 40; i++)
assertEq(f(i), i+10);
// Test the throw path
function ffiThrow(n) { if (n == 38) throw 'yolo'; }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; ffi(i >> 0); } return f'), null, {ffi:ffiThrow});
var i = 0;
try {
for (; i < 40; i++)
f(i);
throw 'assume unreachable';
} catch (e) {
assertEq(e, 'yolo');
assertEq(i, 38);
}
// OOL conversion paths
var INT32_MAX = Math.pow(2, 31) - 1;
function ffiOOLConvertInt(n) { if (n == 40) return INT32_MAX + 1; return 42; }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i >> 0) | 0; } return f'), null, {ffi:ffiOOLConvertInt});
for (var i = 0; i < 40; i++)
assertEq(f(i), 42);
assertEq(f(40), INT32_MAX + 1 | 0);
function ffiOOLConvertDouble(n) { if (n == 40) return {valueOf: function() { return 13.37 }}; return 42.5; }
var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return +ffi(i >> 0); } return f'), null, {ffi:ffiOOLConvertDouble});
for (var i = 0; i < 40; i++)
assertEq(f(i), 42.5);
assertEq(f(40), 13.37);

Просмотреть файл

@ -6039,7 +6039,7 @@ LoadJSContextFromActivation(MacroAssembler &masm, Register activation, Register
static void
AssertStackAlignment(MacroAssembler &masm)
{
JS_ASSERT((AlignmentAtAsmJSPrologue + masm.framePushed()) % StackAlignment == 0);
JS_ASSERT((AsmJSSizeOfRetAddr + masm.framePushed()) % StackAlignment == 0);
#ifdef DEBUG
Label ok;
JS_ASSERT(IsPowerOfTwo(StackAlignment));
@ -6064,7 +6064,7 @@ StackDecrementForCall(MacroAssembler &masm, unsigned bytesToPush)
{
// Include extra padding so that, after pushing the bytesToPush,
// the stack is aligned for a call instruction.
unsigned alreadyPushed = AlignmentAtAsmJSPrologue + masm.framePushed();
unsigned alreadyPushed = AsmJSSizeOfRetAddr + masm.framePushed();
return AlignBytes(alreadyPushed + bytesToPush, StackAlignment) - alreadyPushed;
}
@ -6109,10 +6109,8 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
// PushRegsInMask(NonVolatileRegs).
masm.setFramePushed(0);
// See AsmJSSizeOfRetAddr comment in Assembler-*.h.
#if defined(JS_CODEGEN_ARM)
// Push lr without incrementing masm.framePushed since this push is
// accounted for by AlignmentAtAsmJSPrologue. The masm.ret at the end will
// pop.
masm.push(lr);
#endif // JS_CODEGEN_ARM
#if defined(JS_CODEGEN_MIPS)
@ -6148,7 +6146,7 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
Register argv = ABIArgGenerator::NonArgReturnVolatileReg0;
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
#if defined(JS_CODEGEN_X86)
masm.loadPtr(Address(StackPointer, NativeFrameSize + masm.framePushed()), argv);
masm.loadPtr(Address(StackPointer, AsmJSSizeOfRetAddr + masm.framePushed()), argv);
#else
masm.movePtr(IntArgReg0, argv);
#endif
@ -6370,10 +6368,8 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
m.setInterpExitOffset(exitIndex);
masm.setFramePushed(0);
// See AsmJSSizeOfRetAddr comment in Assembler-*.h.
#if defined(JS_CODEGEN_ARM)
// Push lr without incrementing masm.framePushed since this push is
// accounted for by AlignmentAtAsmJSPrologue. The masm.ret at the end will
// pop.
masm.push(lr);
#endif
#if defined(JS_CODEGEN_MIPS)
@ -6397,7 +6393,7 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
masm.reserveStack(stackDec);
// Fill the argument array.
unsigned offsetToCallerStackArgs = AlignmentAtAsmJSPrologue + masm.framePushed();
unsigned offsetToCallerStackArgs = AsmJSSizeOfRetAddr + masm.framePushed();
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
FillArgumentArray(m, exit.sig().args(), offsetToArgv, offsetToCallerStackArgs, scratch);
@ -6546,12 +6542,10 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
m.setIonExitOffset(exitIndex);
masm.setFramePushed(0);
// See AsmJSSizeOfRetAddr comment in Assembler-*.h.
#if defined(JS_CODEGEN_X64)
masm.Push(HeapReg);
#elif defined(JS_CODEGEN_ARM)
// Push lr without incrementing masm.framePushed since this push is
// accounted for by AlignmentAtAsmJSPrologue. The masm.ret at the end will
// pop.
masm.push(lr);
// The GlobalReg (r10) and HeapReg (r11) also need to be restored before
@ -6627,7 +6621,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
argOffset += sizeof(Value);
// 5. Fill the arguments
unsigned offsetToCallerStackArgs = masm.framePushed() + NativeFrameSize;
unsigned offsetToCallerStackArgs = masm.framePushed() + AsmJSSizeOfRetAddr;
FillArgumentArray(m, exit.sig().args(), argOffset, offsetToCallerStackArgs, scratch);
argOffset += exit.sig().args().length() * sizeof(Value);
JS_ASSERT(argOffset == offsetToArgs + argBytes);

Просмотреть файл

@ -941,15 +941,15 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
return nullptr;
if (PropertyName *argName = module.globalArgumentName()) {
if (!out.append(argName->chars(), argName->length()))
if (!out.append(argName))
return nullptr;
}
if (PropertyName *argName = module.importArgumentName()) {
if (!out.append(", ") || !out.append(argName->chars(), argName->length()))
if (!out.append(", ") || !out.append(argName))
return nullptr;
}
if (PropertyName *argName = module.bufferArgumentName()) {
if (!out.append(", ") || !out.append(argName->chars(), argName->length()))
if (!out.append(", ") || !out.append(argName))
return nullptr;
}
@ -965,7 +965,7 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
if (!AppendUseStrictSource(cx, fun, src, out))
return nullptr;
} else {
if (!out.append(src->chars(), src->length()))
if (!out.append(src))
return nullptr;
}
@ -1048,7 +1048,7 @@ js::AsmJSFunctionToString(JSContext *cx, HandleFunction fun)
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (!out.append(src->chars(), src->length()))
if (!out.append(src))
return nullptr;
}

Просмотреть файл

@ -8706,7 +8706,7 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
if (mir->spIncrement())
masm.freeStack(mir->spIncrement());
JS_ASSERT((AlignmentAtAsmJSPrologue + masm.framePushed()) % StackAlignment == 0);
JS_ASSERT((AsmJSSizeOfRetAddr + masm.framePushed()) % StackAlignment == 0);
#ifdef DEBUG
Label ok;

Просмотреть файл

@ -316,6 +316,15 @@ class InlineList : protected InlineListNode<T>
bool empty() const {
return begin() == end();
}
void takeElements(InlineList &l) {
MOZ_ASSERT(&l != this, "cannot takeElements from this");
Node *lprev = l.prev;
static_cast<Node *>(l.next)->prev = this;
lprev->next = this->next;
static_cast<Node *>(this->next)->prev = l.prev;
this->next = l.next;
l.clear();
}
};
template <typename T>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше